diff --git a/AUTHORS b/AUTHORS index 8c74b6c7..42aaa7c 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -733,6 +733,7 @@ Manish Jethani <m.jethani@eyeo.com> Manojkumar Bhosale <manojkumar.bhosale@imgtec.com> Manuel Braun <thembrown@gmail.com> +Manuel Lagana <manuel.lagana.dev@gmail.com> Mao Yujie <maojie0924@gmail.com> Mao Yujie <yujie.mao@intel.com> Marc des Garets <marc.desgarets@googlemail.com>
diff --git a/DEPS b/DEPS index ecb193e..3f1cf103 100644 --- a/DEPS +++ b/DEPS
@@ -269,7 +269,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '7c892b6303fc189df70e70cf6f429ad65d35ef84', + 'skia_revision': 'd4ab439f9f6f51c041038ce556b611fe9af2e956', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -277,7 +277,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '7e9e597ea1a9987e614c223923fa91c8a2b639d7', + 'angle_revision': '580f90c7d33e219f50847ac89f229ff62e539cd5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -340,7 +340,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': 'e9b55266586c1188837e156587ff75221ed18120', + 'catapult_revision': '6240594199af227b802483b3689bdac749a6be1d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -348,7 +348,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '656e9fdf284182ff30061921d56bb1c750b11876', + 'devtools_frontend_revision': 'ffc94562308344fee2247a288a7f2bff8421f6fa', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -384,7 +384,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '08f94e900426ea7fcfa4c6e04ee083d8c648ce7c', + 'dawn_revision': 'e2d7f86872bf7c7c47cb2fc1c540feb3c42e1471', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -428,7 +428,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'libcxxabi_revision': 'bb1e46cb72b89a8bb61cc16ad33267b53889aae3', + 'libcxxabi_revision': 'f8b9fcc8e27d2ebb27e74378613bd7109737f15a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -914,7 +914,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '_6LSpTMrwppYMyP7cQHuhfab0hq8aJFpArKyFPpd9wgC', + 'version': 'PNBrshbagcx1GOHkHBhYzkuMPFqjoNIacmyt8tKhmfwC', }, ], 'condition': 'checkout_android', @@ -1009,7 +1009,7 @@ Var('chromium_git') + '/angle/angle.git' + '@' + Var('angle_revision'), 'src/third_party/content_analysis_sdk/src': - Var('chromium_git') + '/external/github.com/chromium/content_analysis_sdk.git' + '@' + 'ffaa2941d25f9321b4ab4f7beacd729494ae144c', + Var('chromium_git') + '/external/github.com/chromium/content_analysis_sdk.git' + '@' + 'd2a0b6188bcbae674f8ef2c42c7cffc908ac632e', 'src/third_party/dav1d/libdav1d': Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + '87f9a81cd770e49394a45deca7a3df41243de00b', @@ -1110,7 +1110,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'e332c78c2b9ee73b657c6b13fedcd908b37f6ffe', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '1a40fd23ac85e202145a649b7205fc3f6103d16f', 'condition': 'checkout_chromeos', }, @@ -1530,7 +1530,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b3694fd90110c28532e47831bd1ffc517d0ccc1b', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '078d86518ab973104a8066b22a94a4f281cb8553', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1705,7 +1705,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '5a1defd2980454b434c707ef002bdb21ff1e145e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '8c6d88ff5c5d8d89b93e74935aa354d58ef3799f', + Var('webrtc_git') + '/src.git' + '@' + '1cb0b90df4c9e9c573f655acbad603e95ba4000f', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1778,7 +1778,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c23e3d58f4950407b071db4f9261992b3d0a84e8', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@40eec5233574e972bd6c20f7dc8355a11377d677', 'condition': 'checkout_src_internal', }, @@ -1808,7 +1808,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'AajffdMk1aTPJcI58zxg_IIXWAnJIQeXYEnkOZl6ANYC', + 'version': 'bFdYp_B3xJ8c-mnuvfL1q7fRkYqoORhHWxZEjVuKX0QC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1819,7 +1819,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'WteMeuSUMJqpnMC5LMl5BWJGfjosmnhFQbIqa7QKKhkC', + 'version': 'RGIcLrebzU-C8bZd8lqHsASvZE5SOZ0ziavz4c0LBosC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 1c17533..c8a909f9 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -8,6 +8,7 @@ for more details about the presubmit API built into depot_tools. """ +from typing import Callable from typing import Optional from typing import Sequence from dataclasses import dataclass @@ -116,19 +117,19 @@ @dataclass class BanRule: - # String pattern. If the pattern begins with a slash, the pattern will be - # treated as a regular expression instead. - pattern: str - # Explanation as a sequence of strings. Each string in the sequence will be - # printed on its own line. - explanation: Sequence[str] - # Whether or not to treat this ban as a fatal error. If unspecified, defaults - # to true. - treat_as_error: Optional[bool] = None - # Paths that should be excluded from the ban check. Each string is a regular - # expression that will be matched against the path of the file being checked - # relative to the root of the source tree. - excluded_paths: Optional[Sequence[str]] = None + # String pattern. If the pattern begins with a slash, the pattern will be + # treated as a regular expression instead. + pattern: str + # Explanation as a sequence of strings. Each string in the sequence will be + # printed on its own line. + explanation: Sequence[str] + # Whether or not to treat this ban as a fatal error. If unspecified, + # defaults to true. + treat_as_error: Optional[bool] = None + # Paths that should be excluded from the ban check. Each string is a regular + # expression that will be matched against the path of the file being checked + # relative to the root of the source tree. + excluded_paths: Optional[Sequence[str]] = None _BANNED_JAVA_IMPORTS : Sequence[BanRule] = ( @@ -2610,9 +2611,10 @@ try: contents = input_api.ReadFile(filename) for i, char in enumerate(contents): - if not char.isascii(): - return ('Non-ascii character "%s" (ord %d) found at offset %d.' - % (char, ord(char), i)) + if not char.isascii(): + return ( + 'Non-ascii character "%s" (ord %d) found at offset %d.' % + (char, ord(char), i)) idl_schema = input_api.os_path.join(input_api.PresubmitLocalPath(), 'tools', 'json_schema_compiler', 'idl_schema.py') @@ -2753,54 +2755,67 @@ return False -def _GetOwnersFilesToCheckForIpcOwners(input_api): - """Gets a list of OWNERS files to check for correct security owners. +def _ChangeHasSecurityReviewer(input_api, owners_file): + """Returns True iff the CL has a reviewer from SECURITY_OWNERS. - Returns: - A dictionary mapping an OWNER file to the list of OWNERS rules it must - contain to cover IPC-related files with noparent reviewer rules. + Args: + input_api: The presubmit input API. + owners_file: OWNERS file with required reviewers. Typically, this is + something like ipc/SECURITY_OWNERS. + + Note: if the presubmit is running for commit rather than for upload, this + only returns True if a security reviewer has also approved the CL. """ - # Whether or not a file affects IPC is (mostly) determined by a simple list - # of filename patterns. - file_patterns = [ - # Legacy IPC: - '*_messages.cc', - '*_messages*.h', - '*_param_traits*.*', - # Mojo IPC: - '*.mojom', - '*_mojom_traits*.*', - '*_struct_traits*.*', - '*_type_converter*.*', - '*.typemap', - # Android native IPC: - '*.aidl', - # Blink uses a different file naming convention: - '*EnumTraits*.*', - "*MojomTraits*.*", - '*StructTraits*.*', - '*TypeConverter*.*', - ] + owner_email, reviewers = ( + input_api.canned_checks.GetCodereviewOwnerAndReviewers( + input_api, None, approval_needed=input_api.is_committing)) - # These third_party directories do not contain IPCs, but contain files - # matching the above patterns, which trigger false positives. - exclude_paths = [ - 'third_party/crashpad/*', - 'third_party/blink/renderer/platform/bindings/*', - 'third_party/protobuf/benchmarks/python/*', - 'third_party/win_build_output/*', - # These files are just used to communicate between class loaders running - # in the same process. - 'weblayer/browser/java/org/chromium/weblayer_private/interfaces/*', - 'weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/*', - ] + security_owners = input_api.owners_client.ListOwners(owners_file) + return any(owner in reviewers for owner in security_owners) - # Dictionary mapping an OWNERS file path to Patterns. - # Patterns is a dictionary mapping glob patterns (suitable for use in per-file - # rules ) to a PatternEntry. + +@dataclass +class _MissingSecurityOwnersResult: + owners_file_errors: Sequence[str] + has_security_sensitive_files: bool + missing_reviewer_errors: Sequence[str] + + +def _FindMissingSecurityOwners(input_api, + output_api, + file_patterns: Sequence[str], + excluded_patterns: Sequence[str], + required_owners_file: str, + custom_rule_function: Optional[Callable] = None + ) -> _MissingSecurityOwnersResult: + """Find OWNERS files missing per-file rules for security-sensitive files. + + Args: + input_api: the PRESUBMIT input API object. + output_api: the PRESUBMIT output API object. + file_patterns: basename patterns that require a corresponding per-file + security restriction. + excluded_patterns: path patterns that should be exempted from + requiring a security restriction. + required_owners_file: path to the required OWNERS file, e.g. + ipc/SECURITY_OWNERS + cc_alias: If not None, email that will be CCed automatically if the + change contains security-sensitive files, as determined by + `file_patterns` and `excluded_patterns`. + custom_rule_function: If not None, will be called with `input_api` and + the current file under consideration. Returning True will add an + exact match per-file rule check for the current file. + """ + + # `to_check` is a mapping of an OWNERS file path to Patterns. + # + # Patterns is a dictionary mapping glob patterns (suitable for use in + # per-file rules) to a PatternEntry. + # # PatternEntry is a dictionary with two keys: # - 'files': the files that are matched by this pattern # - 'rules': the per-file rules needed for this pattern + # # For example, if we expect OWNERS file to contain rules for *.mojom and # *_struct_traits*.*, Patterns might look like this: # { @@ -2820,117 +2835,57 @@ # }, # } to_check = {} + files_to_review = [] - def AddPatternToCheck(input_file, pattern): + def AddPatternToCheck(file, pattern): owners_file = input_api.os_path.join( - input_api.os_path.dirname(input_file.AbsoluteLocalPath()), - 'OWNERS') + input_api.os_path.dirname(file.AbsoluteLocalPath()), 'OWNERS') if owners_file not in to_check: to_check[owners_file] = {} if pattern not in to_check[owners_file]: to_check[owners_file][pattern] = { 'files': [], 'rules': [ - 'per-file %s=set noparent' % pattern, - 'per-file %s=file://ipc/SECURITY_OWNERS' % pattern, + f'per-file {pattern}=set noparent', + f'per-file {pattern}=file://{required_owners_file}', ] } - to_check[owners_file][pattern]['files'].append(input_file) + to_check[owners_file][pattern]['files'].append(file) + files_to_review.append(file.LocalPath()) - # Iterate through the affected files to see what we actually need to check - # for. We should only nag patch authors about per-file rules if a file in that - # directory would match that pattern. If a directory only contains *.mojom - # files and no *_messages*.h files, we should only nag about rules for - # *.mojom files. - for f in input_api.AffectedFiles(include_deletes=False): - # Manifest files don't have a strong naming convention. Instead, try to find - # affected .cc and .h files which look like they contain a manifest - # definition. - manifest_pattern = input_api.re.compile('manifests?\.(cc|h)$') - test_manifest_pattern = input_api.re.compile('test_manifests?\.(cc|h)') - if (manifest_pattern.search(f.LocalPath()) - and not test_manifest_pattern.search(f.LocalPath())): - # We expect all actual service manifest files to contain at least one - # qualified reference to service_manager::Manifest. - if 'service_manager::Manifest' in '\n'.join(f.NewContents()): - AddPatternToCheck(f, input_api.os_path.basename(f.LocalPath())) - for pattern in file_patterns: - if input_api.fnmatch.fnmatch( - input_api.os_path.basename(f.LocalPath()), pattern): - skip = False - for exclude in exclude_paths: - if input_api.fnmatch.fnmatch(f.LocalPath(), exclude): - skip = True - break - if skip: - continue - AddPatternToCheck(f, pattern) - break + # Only enforce security OWNERS rules for a directory if that directory has a + # file that matches `file_patterns`. For example, if a directory only + # contains *.mojom files and no *_messages*.h files, the check should only + # ensure that rules for *.mojom files are present. + for file in input_api.AffectedFiles(include_deletes=False): + file_basename = input_api.os_path.basename(file.LocalPath()) + if custom_rule_function is not None and custom_rule_function( + input_api, file): + AddPatternToCheck(file, file_basename) + continue - return to_check - - -def _AddOwnersFilesToCheckForFuchsiaSecurityOwners(input_api, to_check): - """Adds OWNERS files to check for correct Fuchsia security owners.""" - - file_patterns = [ - # Component specifications. - '*.cml', # Component Framework v2. - '*.cmx', # Component Framework v1. - - # Fuchsia IDL protocol specifications. - '*.fidl', - ] - - # Don't check for owners files for changes in these directories. - exclude_paths = [ - 'third_party/crashpad/*', - ] - - def AddPatternToCheck(input_file, pattern): - owners_file = input_api.os_path.join( - input_api.os_path.dirname(input_file.LocalPath()), 'OWNERS') - if owners_file not in to_check: - to_check[owners_file] = {} - if pattern not in to_check[owners_file]: - to_check[owners_file][pattern] = { - 'files': [], - 'rules': [ - 'per-file %s=set noparent' % pattern, - 'per-file %s=file://build/fuchsia/SECURITY_OWNERS' % pattern, - ] - } - to_check[owners_file][pattern]['files'].append(input_file) - - # Iterate through the affected files to see what we actually need to check - # for. We should only nag patch authors about per-file rules if a file in that - # directory would match that pattern. - for f in input_api.AffectedFiles(include_deletes=False): - skip = False - for exclude in exclude_paths: - if input_api.fnmatch.fnmatch(f.LocalPath(), exclude): - skip = True - if skip: + if any( + input_api.fnmatch.fnmatch(file.LocalPath(), pattern) + for pattern in excluded_patterns): continue for pattern in file_patterns: - if input_api.fnmatch.fnmatch( - input_api.os_path.basename(f.LocalPath()), pattern): - AddPatternToCheck(f, pattern) + # Unlike `excluded_patterns`, `file_patterns` is checked only against the + # file's basename. + if input_api.fnmatch.fnmatch(file_basename, pattern): + AddPatternToCheck(file, pattern) break - return to_check - - -def CheckSecurityOwners(input_api, output_api): - """Checks that affected files involving IPC have an IPC OWNERS rule.""" - to_check = _GetOwnersFilesToCheckForIpcOwners(input_api) - _AddOwnersFilesToCheckForFuchsiaSecurityOwners(input_api, to_check) - - if to_check: - # If there are any OWNERS files to check, there are IPC-related changes in - # this CL. Auto-CC the review list. - output_api.AppendCC('ipc-security-reviews@chromium.org') + has_security_sensitive_files = bool(to_check) + missing_reviewer_errors = [] + if files_to_review and not _ChangeHasSecurityReviewer( + input_api, required_owners_file): + joined_files_to_review = '\n'.join(f' {file}' + for file in files_to_review) + missing_reviewer_errors.append( + f'Code review from an owner in //{required_owners_file} is required ' + 'for this change for the following files:\n' + f'{joined_files_to_review}') # Go through the OWNERS files to check, filtering out rules that are already # present in that OWNERS file. @@ -2947,30 +2902,141 @@ continue # All the remaining lines weren't found in OWNERS files, so emit an error. - errors = [] + owners_file_errors = [] + for owners_file, patterns in to_check.items(): missing_lines = [] files = [] for _, entry in patterns.items(): missing_lines.extend(entry['rules']) - files.extend([' %s' % f.LocalPath() for f in entry['files']]) + files.extend( + [' %s' % file.LocalPath() for file in entry['files']]) if missing_lines: - errors.append('Because of the presence of files:\n%s\n\n' - '%s needs the following %d lines added:\n\n%s' % - ('\n'.join(files), owners_file, len(missing_lines), - '\n'.join(missing_lines))) + joined_files = '\n'.join(files) + joined_missing_lines = '\n'.join(missing_lines) + owners_file_errors.append( + f'Because of the presence of files:\n{joined_files}\n\n' + f'{owners_file} needs the following {len(missing_lines)} ' + 'line(s) added:\n\n' + f'{joined_missing_lines}') + + return _MissingSecurityOwnersResult(owners_file_errors, + has_security_sensitive_files, + missing_reviewer_errors) + + +def _CheckChangeForIpcSecurityOwners(input_api, output_api): + # Whether or not a file affects IPC is (mostly) determined by a simple list + # of filename patterns. + file_patterns = [ + # Legacy IPC: + '*_messages.cc', + '*_messages*.h', + '*_param_traits*.*', + # Mojo IPC: + '*.mojom', + '*_mojom_traits*.*', + '*_type_converter*.*', + # Android native IPC: + '*.aidl', + ] + + # These third_party directories do not contain IPCs, but contain files + # matching the above patterns, which trigger false positives. + excluded_patterns = [ + 'third_party/crashpad/*', + 'third_party/blink/renderer/platform/bindings/*', + 'third_party/protobuf/benchmarks/python/*', + 'third_party/win_build_output/*', + # These files are just used to communicate between class loaders running + # in the same process. + 'weblayer/browser/java/org/chromium/weblayer_private/interfaces/*', + 'weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/*', + ] + + def IsMojoServiceManifestFile(input_api, file): + manifest_pattern = input_api.re.compile('manifests?\.(cc|h)$') + test_manifest_pattern = input_api.re.compile('test_manifests?\.(cc|h)') + if not manifest_pattern.search(file.LocalPath()): + return False + + if test_manifest_pattern.search(file.LocalPath()): + return False + + # All actual service manifest files should contain at least one + # qualified reference to service_manager::Manifest. + return any('service_manager::Manifest' in line + for line in file.NewContents()) + + return _FindMissingSecurityOwners( + input_api, + output_api, + file_patterns, + excluded_patterns, + 'ipc/SECURITY_OWNERS', + custom_rule_function=IsMojoServiceManifestFile) + + +def _CheckChangeForFuchsiaSecurityOwners(input_api, output_api): + file_patterns = [ + # Component specifications. + '*.cml', # Component Framework v2. + '*.cmx', # Component Framework v1. + + # Fuchsia IDL protocol specifications. + '*.fidl', + ] + + # Don't check for owners files for changes in these directories. + excluded_patterns = [ + 'third_party/crashpad/*', + ] + + return _FindMissingSecurityOwners(input_api, output_api, file_patterns, + excluded_patterns, + 'build/fuchsia/SECURITY_OWNERS') + + +def CheckSecurityOwners(input_api, output_api): + """Checks that various security-sensitive files have an IPC OWNERS rule.""" + ipc_results = _CheckChangeForIpcSecurityOwners(input_api, output_api) + fuchsia_results = _CheckChangeForFuchsiaSecurityOwners( + input_api, output_api) + + if ipc_results.has_security_sensitive_files: + output_api.AppendCC('ipc-security-reviews@chromium.org') results = [] - if errors: - if input_api.is_committing: - output = output_api.PresubmitError - else: - output = output_api.PresubmitPromptWarning + if input_api.is_committing: + make_presubmit_message = output_api.PresubmitError + else: + make_presubmit_message = output_api.PresubmitPromptWarning + + # Ensure that a security reviewer is included as a CL reviewer. This is a + # hack, but is needed because the OWNERS check (by design) ignores new + # OWNERS entries; otherwise, a non-owner could add someone as a new OWNER + # and have that newly-added OWNER self-approve their own addition. + missing_reviewer_errors = [] + missing_reviewer_errors.extend(ipc_results.missing_reviewer_errors) + missing_reviewer_errors.extend(fuchsia_results.missing_reviewer_errors) + + if missing_reviewer_errors: results.append( - output( - 'Found OWNERS files that need to be updated for IPC security ' - + 'review coverage.\nPlease update the OWNERS files below:', - long_text='\n\n'.join(errors))) + make_presubmit_message( + 'Found missing security reviewers:', + long_text='\n\n'.join(missing_reviewer_errors))) + + owners_file_errors = [] + owners_file_errors.extend(ipc_results.owners_file_errors) + owners_file_errors.extend(fuchsia_results.owners_file_errors) + + if owners_file_errors: + results.append( + make_presubmit_message( + 'Found OWNERS files with missing per-file rules for ' + 'security-sensitive files.\nPlease update the OWNERS files ' + 'below to add the missing rules:', + long_text='\n\n'.join(owners_file_errors))) return results @@ -2993,11 +3059,9 @@ for k, v in _PATTERNS_TO_CHECK.items() } - import os - # We don't want to trigger on strings within this file. def presubmit_file_filter(f): - return 'PRESUBMIT.py' != os.path.split(f.LocalPath())[1] + return 'PRESUBMIT.py' != input_api.os_path.split(f.LocalPath())[1] # Scan all affected files for changes touching _FUNCTIONS_TO_CHECK. files_to_functions = {} @@ -3026,18 +3090,11 @@ if not len(files_to_functions): return [] - owner_email, reviewers = ( - input_api.canned_checks.GetCodereviewOwnerAndReviewers( - input_api, None, approval_needed=input_api.is_committing)) - - # Load the OWNERS file for security changes. owners_file = 'ipc/SECURITY_OWNERS' - security_owners = input_api.owners_client.ListOwners(owners_file) - has_security_owner = any([owner in reviewers for owner in security_owners]) - if has_security_owner: + if _ChangeHasSecurityReviewer(input_api, owners_file): return [] - msg = 'The following files change calls to security-sensive functions\n' \ + msg = 'The following files change calls to security-sensitive functions\n' \ 'that need to be reviewed by {}.\n'.format(owners_file) for path, names in files_to_functions.items(): msg += ' {}\n'.format(path) @@ -4945,7 +5002,7 @@ for f in input_api.AffectedSourceFiles(source_file_filter): # Ignore test files that contain crlf intentionally. if f.LocalPath().endswith('crlf.txt'): - continue + continue include_file = False for line in input_api.ReadFile(f, 'r').splitlines(True): if line.endswith('\r\n'):
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index 5a265227..ec156d3 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -2291,7 +2291,88 @@ 'chrome/app/chromium_strings.grd:8' in warnings[1].items[1]) -class ServiceManifestOwnerTest(unittest.TestCase): +class _SecurityOwnersTestCase(unittest.TestCase): + def _injectFakeOwnersClient(self, input_api, owners): + class FakeOwnersClient(object): + def ListOwners(self, f): + return owners + + input_api.owners_client = FakeOwnersClient() + + def _injectFakeChangeOwnerAndReviewers(self, input_api, owner, reviewers): + def MockOwnerAndReviewers(input_api, email_regexp, approval_needed=False): + return [owner, reviewers] + input_api.canned_checks.GetCodereviewOwnerAndReviewers = \ + MockOwnerAndReviewers + + +class IpcSecurityOwnerTest(_SecurityOwnersTestCase): + _test_cases = [ + ('*_messages.cc', 'scary_messages.cc'), + ('*_messages*.h', 'scary_messages.h'), + ('*_messages*.h', 'scary_messages_android.h'), + ('*_param_traits*.*', 'scary_param_traits.h'), + ('*_param_traits*.*', 'scary_param_traits_win.h'), + ('*.mojom', 'scary.mojom'), + ('*_mojom_traits*.*', 'scary_mojom_traits.h'), + ('*_mojom_traits*.*', 'scary_mojom_traits_mac.h'), + ('*_type_converter*.*', 'scary_type_converter.h'), + ('*_type_converter*.*', 'scary_type_converter_nacl.h'), + ('*.aidl', 'scary.aidl'), + ] + + # TODO(dcheng): add tests for when there are no missing per-file rules. These + # are currently missing because `open()` is not injected. + + def testMissingPerFileRulesButNotSecurityReviewer(self): + for pattern, filename in self._test_cases: + with self.subTest(line=filename): + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockAffectedFile(f'services/goat/public/{filename}', + ['// Scary contents.'])] + self._injectFakeOwnersClient( + mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['orange@chromium.org']) + mock_output_api = MockOutputApi() + errors = PRESUBMIT.CheckSecurityOwners( + mock_input_api, mock_output_api) + self.assertEqual(1, len(errors)) + self.assertEqual( + 'Found OWNERS files with missing per-file rules for ' + 'security-sensitive files.\nPlease update the OWNERS files below ' + 'to add the missing rules:', errors[0].message) + self.assertEqual(['ipc-security-reviews@chromium.org'], + mock_output_api.more_cc) + + def testIpcChangeNeedsSecurityOwner(self): + for pattern, filename in self._test_cases: + with self.subTest(line=filename): + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockAffectedFile(f'services/goat/public/{filename}', + ['// Scary contents.'])] + self._injectFakeOwnersClient( + mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) + mock_output_api = MockOutputApi() + errors = PRESUBMIT.CheckSecurityOwners( + mock_input_api, mock_output_api) + self.assertEqual(2, len(errors)) + self.assertEqual( + 'Found missing security reviewers:', errors[0].message) + self.assertEqual( + 'Found OWNERS files with missing per-file rules for ' + 'security-sensitive files.\nPlease update the OWNERS files below ' + 'to add the missing rules:', errors[1].message) + self.assertEqual(['ipc-security-reviews@chromium.org'], + mock_output_api.more_cc) + + def testServiceManifestChangeNeedsSecurityOwner(self): mock_input_api = MockInputApi() mock_input_api.files = [ @@ -2300,16 +2381,28 @@ '#include "services/goat/public/cpp/manifest.h"', 'const service_manager::Manifest& GetManifest() {}', ])] + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) mock_output_api = MockOutputApi() errors = PRESUBMIT.CheckSecurityOwners( mock_input_api, mock_output_api) - self.assertEqual(1, len(errors)) + self.assertEqual(2, len(errors)) self.assertEqual( - 'Found OWNERS files that need to be updated for IPC security review ' + - 'coverage.\nPlease update the OWNERS files below:', errors[0].message) + 'Found missing security reviewers:', errors[0].message) + self.assertEqual( + 'Found OWNERS files with missing per-file rules for security-sensitive ' + 'files.\nPlease update the OWNERS files below to ' + 'add the missing rules:', errors[1].message) + self.assertEqual(['ipc-security-reviews@chromium.org'], mock_output_api.more_cc) def testNonServiceManifestSourceChangesDoNotRequireSecurityOwner(self): mock_input_api = MockInputApi() + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) mock_input_api.files = [ MockAffectedFile('some/non/service/thing/foo_manifest.cc', [ @@ -2319,9 +2412,10 @@ errors = PRESUBMIT.CheckSecurityOwners( mock_input_api, mock_output_api) self.assertEqual([], errors) + self.assertEqual([], mock_output_api.more_cc) -class FuchsiaSecurityOwnerTest(unittest.TestCase): +class FuchsiaSecurityOwnerTest(_SecurityOwnersTestCase): def testFidlChangeNeedsSecurityOwner(self): mock_input_api = MockInputApi() mock_input_api.files = [ @@ -2329,13 +2423,20 @@ [ 'library test.fidl' ])] + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) mock_output_api = MockOutputApi() errors = PRESUBMIT.CheckSecurityOwners( mock_input_api, mock_output_api) - self.assertEqual(1, len(errors)) + self.assertEqual(2, len(errors)) self.assertEqual( - 'Found OWNERS files that need to be updated for IPC security review ' + - 'coverage.\nPlease update the OWNERS files below:', errors[0].message) + 'Found missing security reviewers:', errors[0].message) + self.assertEqual( + 'Found OWNERS files with missing per-file rules for security-sensitive ' + 'files.\nPlease update the OWNERS files below to ' + 'add the missing rules:', errors[1].message) def testComponentManifestV1ChangeNeedsSecurityOwner(self): mock_input_api = MockInputApi() @@ -2344,13 +2445,20 @@ [ '{ "that is no": "manifest!" }' ])] + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) mock_output_api = MockOutputApi() errors = PRESUBMIT.CheckSecurityOwners( mock_input_api, mock_output_api) - self.assertEqual(1, len(errors)) + self.assertEqual(2, len(errors)) self.assertEqual( - 'Found OWNERS files that need to be updated for IPC security review ' + - 'coverage.\nPlease update the OWNERS files below:', errors[0].message) + 'Found missing security reviewers:', errors[0].message) + self.assertEqual( + 'Found OWNERS files with missing per-file rules for security-sensitive ' + 'files.\nPlease update the OWNERS files below to ' + 'add the missing rules:', errors[1].message) def testComponentManifestV2NeedsSecurityOwner(self): mock_input_api = MockInputApi() @@ -2360,15 +2468,26 @@ '{ "that is no": "manifest!" }' ])] mock_output_api = MockOutputApi() + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) errors = PRESUBMIT.CheckSecurityOwners( mock_input_api, mock_output_api) - self.assertEqual(1, len(errors)) + self.assertEqual(2, len(errors)) self.assertEqual( - 'Found OWNERS files that need to be updated for IPC security review ' + - 'coverage.\nPlease update the OWNERS files below:', errors[0].message) + 'Found missing security reviewers:', errors[0].message) + self.assertEqual( + 'Found OWNERS files with missing per-file rules for security-sensitive ' + 'files.\nPlease update the OWNERS files below to ' + 'add the missing rules:', errors[1].message) def testThirdPartyTestsDoNotRequireSecurityOwner(self): mock_input_api = MockInputApi() + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) mock_input_api.files = [ MockAffectedFile('third_party/crashpad/test/tests.cmx', [ @@ -2381,6 +2500,10 @@ def testOtherFuchsiaChangesDoNotRequireSecurityOwner(self): mock_input_api = MockInputApi() + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) mock_input_api.files = [ MockAffectedFile('some/non/service/thing/fuchsia_fidl_cml_cmx_magic.cc', [ @@ -2392,17 +2515,7 @@ self.assertEqual([], errors) -class SecurityChangeTest(unittest.TestCase): - class _MockOwnersClient(object): - def ListOwners(self, f): - return ['apple@chromium.org', 'orange@chromium.org'] - - def _mockChangeOwnerAndReviewers(self, input_api, owner, reviewers): - def __MockOwnerAndReviewers(input_api, email_regexp, approval_needed=False): - return [owner, reviewers] - input_api.canned_checks.GetCodereviewOwnerAndReviewers = \ - __MockOwnerAndReviewers - +class SecurityChangeTest(_SecurityOwnersTestCase): def testDiffGetServiceSandboxType(self): mock_input_api = MockInputApi() mock_input_api.files = [ @@ -2452,64 +2565,68 @@ def testChangeOwnersMissing(self): mock_input_api = MockInputApi() - mock_input_api.owners_client = self._MockOwnersClient() + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) mock_input_api.is_committing = False mock_input_api.files = [ MockAffectedFile('file.cc', ['GetServiceSandboxType<Goat>(Sandbox)']) ] mock_output_api = MockOutputApi() - self._mockChangeOwnerAndReviewers( - mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api) self.assertEqual(1, len(result)) self.assertEqual(result[0].type, 'notify') self.assertEqual(result[0].message, - 'The following files change calls to security-sensive functions\n' \ + 'The following files change calls to security-sensitive functions\n' \ 'that need to be reviewed by ipc/SECURITY_OWNERS.\n' ' file.cc\n' ' content::GetServiceSandboxType<>()\n\n') def testChangeOwnersMissingAtCommit(self): mock_input_api = MockInputApi() - mock_input_api.owners_client = self._MockOwnersClient() + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) mock_input_api.is_committing = True mock_input_api.files = [ MockAffectedFile('file.cc', ['GetServiceSandboxType<mojom::Goat>()']) ] mock_output_api = MockOutputApi() - self._mockChangeOwnerAndReviewers( - mock_input_api, 'owner@chromium.org', ['banana@chromium.org']) result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api) self.assertEqual(1, len(result)) self.assertEqual(result[0].type, 'error') self.assertEqual(result[0].message, - 'The following files change calls to security-sensive functions\n' \ + 'The following files change calls to security-sensitive functions\n' \ 'that need to be reviewed by ipc/SECURITY_OWNERS.\n' ' file.cc\n' ' content::GetServiceSandboxType<>()\n\n') def testChangeOwnersPresent(self): mock_input_api = MockInputApi() - mock_input_api.owners_client = self._MockOwnersClient() + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'owner@chromium.org', + ['apple@chromium.org', 'banana@chromium.org']) mock_input_api.files = [ MockAffectedFile('file.cc', ['WithSandboxType(Sandbox)']) ] mock_output_api = MockOutputApi() - self._mockChangeOwnerAndReviewers( - mock_input_api, 'owner@chromium.org', - ['apple@chromium.org', 'banana@chromium.org']) result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api) self.assertEqual(0, len(result)) def testChangeOwnerIsSecurityOwner(self): mock_input_api = MockInputApi() - mock_input_api.owners_client = self._MockOwnersClient() + self._injectFakeOwnersClient(mock_input_api, + ['apple@chromium.org', 'orange@chromium.org']) + self._injectFakeChangeOwnerAndReviewers( + mock_input_api, 'orange@chromium.org', ['pear@chromium.org']) mock_input_api.files = [ MockAffectedFile('file.cc', ['GetServiceSandboxType<T>(Sandbox)']) ] mock_output_api = MockOutputApi() - self._mockChangeOwnerAndReviewers( - mock_input_api, 'orange@chromium.org', ['pear@chromium.org']) result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api) self.assertEqual(1, len(result))
diff --git a/android_webview/browser/gfx/display_scheduler_webview.cc b/android_webview/browser/gfx/display_scheduler_webview.cc index 6dde9b59..0463e24 100644 --- a/android_webview/browser/gfx/display_scheduler_webview.cc +++ b/android_webview/browser/gfx/display_scheduler_webview.cc
@@ -5,14 +5,25 @@ #include "android_webview/browser/gfx/display_scheduler_webview.h" #include "android_webview/browser/gfx/root_frame_sink.h" +#include "android_webview/browser/gfx/viz_compositor_thread_runner_webview.h" #include "base/trace_event/trace_event.h" +#include "components/viz/common/features.h" +#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" namespace android_webview { DisplaySchedulerWebView::DisplaySchedulerWebView( RootFrameSink* root_frame_sink, OverlaysInfoProvider* overlays_info_provider) : root_frame_sink_(root_frame_sink), - overlays_info_provider_(overlays_info_provider) {} + overlays_info_provider_(overlays_info_provider), + use_new_invalidate_heuristic_(base::FeatureList::IsEnabled( + features::kWebViewNewInvalidateHeuristic)) { + surface_manager_observation_.Observe( + VizCompositorThreadRunnerWebView::GetInstance() + ->GetFrameSinkManager() + ->surface_manager()); +} + DisplaySchedulerWebView::~DisplaySchedulerWebView() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } @@ -28,6 +39,10 @@ void DisplaySchedulerWebView::DidSwapBuffers() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + // Code below is part of old invalidation heuristic. + if (use_new_invalidate_heuristic_) + return; + bool needs_draw = false; for (auto it = damaged_frames_.begin(); it != damaged_frames_.end();) { DCHECK_GT(it->second, 0); @@ -59,6 +74,11 @@ void DisplaySchedulerWebView::OnDisplayDamaged(viz::SurfaceId surface_id) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // Code below is part of old invalidation heuristic. + if (use_new_invalidate_heuristic_) + return; + // We don't need to track damage of root frame sink as we submit frame to it // at DrawAndSwap and Root Renderer sink because Android View.Invalidation is // handled by SynchronousCompositorHost. @@ -81,4 +101,19 @@ root_frame_sink_->SetNeedsDraw(true); } } + +void DisplaySchedulerWebView::OnSurfaceHasNewUncommittedFrame( + const viz::SurfaceId& surface_id) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // We don't need to track damage of root frame sink as we submit frame to it + // at DrawAndSwap and Root Renderer sink because Android View.Invalidation is + // handled by SynchronousCompositorHost. + if (surface_id.frame_sink_id() != root_frame_sink_->root_frame_sink_id() && + !root_frame_sink_->IsChildSurface(surface_id.frame_sink_id()) && + !IsFrameSinkOverlayed(surface_id.frame_sink_id())) { + root_frame_sink_->OnNewUncommittedFrame(surface_id); + } +} + } // namespace android_webview
diff --git a/android_webview/browser/gfx/display_scheduler_webview.h b/android_webview/browser/gfx/display_scheduler_webview.h index ca1b000..37bdeb7b 100644 --- a/android_webview/browser/gfx/display_scheduler_webview.h +++ b/android_webview/browser/gfx/display_scheduler_webview.h
@@ -8,9 +8,12 @@ #include <map> #include "base/memory/raw_ptr.h" +#include "base/scoped_observation.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread_checker.h" #include "components/viz/service/display/display_scheduler.h" +#include "components/viz/service/surfaces/surface_manager.h" +#include "components/viz/service/surfaces/surface_observer.h" namespace android_webview { class RootFrameSink; @@ -20,7 +23,8 @@ virtual bool IsFrameSinkOverlayed(viz::FrameSinkId frame_sink_id) = 0; }; -class DisplaySchedulerWebView : public viz::DisplaySchedulerBase { +class DisplaySchedulerWebView : public viz::DisplaySchedulerBase, + public viz::SurfaceObserver { public: DisplaySchedulerWebView(RootFrameSink* root_frame_sink, OverlaysInfoProvider* overlays_info_provider); @@ -42,6 +46,10 @@ void OnRootFrameMissing(bool missing) override {} void OnPendingSurfacesChanged() override {} + // SurfaceObserver implementation. + void OnSurfaceHasNewUncommittedFrame( + const viz::SurfaceId& surface_id) override; + private: bool IsFrameSinkOverlayed(viz::FrameSinkId frame_sink_id); @@ -55,6 +63,11 @@ // destructor of this class. const raw_ptr<OverlaysInfoProvider> overlays_info_provider_; + base::ScopedObservation<viz::SurfaceManager, viz::SurfaceObserver> + surface_manager_observation_{this}; + + const bool use_new_invalidate_heuristic_; + THREAD_CHECKER(thread_checker_); }; } // namespace android_webview
diff --git a/android_webview/browser/gfx/display_webview.cc b/android_webview/browser/gfx/display_webview.cc index 047d01c..886292e 100644 --- a/android_webview/browser/gfx/display_webview.cc +++ b/android_webview/browser/gfx/display_webview.cc
@@ -6,6 +6,7 @@ #include "android_webview/browser/gfx/overlay_processor_webview.h" #include "base/memory/ptr_util.h" +#include "components/viz/common/features.h" #include "components/viz/service/display/overlay_processor_stub.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "gpu/config/gpu_finch_features.h" @@ -65,7 +66,10 @@ std::move(overlay_processor), std::move(scheduler), /*current_task_runner=*/nullptr), - overlay_processor_webview_(overlay_processor_webview) { + overlay_processor_webview_(overlay_processor_webview), + frame_sink_manager_(frame_sink_manager), + use_new_invalidate_heuristic_(base::FeatureList::IsEnabled( + features::kWebViewNewInvalidateHeuristic)) { if (overlay_processor_webview_) { frame_sink_manager_observation_.Observe(frame_sink_manager); } @@ -80,6 +84,18 @@ auto surface_id = overlay_processor_webview_->GetOverlaySurfaceId(frame_sink_id); if (surface_id.is_valid()) { + auto* surface = + frame_sink_manager_->surface_manager()->GetSurfaceForId(surface_id); + DCHECK(surface); + + if (use_new_invalidate_heuristic_) { + // For overlays we are going to display this frame immediately, so commit + // it. + surface->CommitFramesRecursively( + base::BindRepeating([](const viz::SurfaceId&, + const viz::BeginFrameId&) { return true; })); + } + // TODO(vasilyt): We don't need full aggregation here as we don't need // aggregated frame. aggregator_->Aggregate(current_surface_id_, base::TimeTicks::Now(), @@ -93,4 +109,11 @@ } } +std::vector<viz::SurfaceId> DisplayWebView::GetContainedSurfaceIds() { + std::vector<viz::SurfaceId> surfaces; + for (auto& surface : aggregator_->previous_contained_surfaces()) + surfaces.push_back(surface.first); + return surfaces; +} + } // namespace android_webview
diff --git a/android_webview/browser/gfx/display_webview.h b/android_webview/browser/gfx/display_webview.h index 195b650..5596bb92 100644 --- a/android_webview/browser/gfx/display_webview.h +++ b/android_webview/browser/gfx/display_webview.h
@@ -33,6 +33,8 @@ return overlay_processor_webview_; } + std::vector<viz::SurfaceId> GetContainedSurfaceIds(); + // viz::FrameSinkObserver implenentation: void OnRegisteredFrameSinkId(const viz::FrameSinkId& frame_sink_id) override { } @@ -67,8 +69,11 @@ viz::FrameSinkManagerImpl* frame_sink_manager); const raw_ptr<OverlayProcessorWebView> overlay_processor_webview_; + const raw_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_; base::ScopedObservation<viz::FrameSinkManagerImpl, viz::FrameSinkObserver> frame_sink_manager_observation_{this}; + + const bool use_new_invalidate_heuristic_; }; } // namespace android_webview
diff --git a/android_webview/browser/gfx/hardware_renderer_viz.cc b/android_webview/browser/gfx/hardware_renderer_viz.cc index f460fa1..c4ed963 100644 --- a/android_webview/browser/gfx/hardware_renderer_viz.cc +++ b/android_webview/browser/gfx/hardware_renderer_viz.cc
@@ -117,6 +117,7 @@ std::unique_ptr<viz::HitTestAggregator> hit_test_aggregator_; viz::SurfaceId child_surface_id_; const bool viz_frame_submission_; + const bool use_new_invalidate_heuristic_; bool expect_context_loss_ = false; // Initialized in ctor and never changes, so it's safe to access from both @@ -131,7 +132,9 @@ const scoped_refptr<RootFrameSink>& root_frame_sink) : without_gpu_(root_frame_sink), frame_sink_id_(without_gpu_->root_frame_sink_id()), - viz_frame_submission_(features::IsUsingVizFrameSubmissionForWebView()) { + viz_frame_submission_(features::IsUsingVizFrameSubmissionForWebView()), + use_new_invalidate_heuristic_(base::FeatureList::IsEnabled( + features::kWebViewNewInvalidateHeuristic)) { DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_); std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController> @@ -252,6 +255,49 @@ const auto& local_surface_id = without_gpu_->SubmitRootCompositorFrame(std::move(frame)); + if (use_new_invalidate_heuristic_) { + auto root_surface_id = + viz::SurfaceId(without_gpu_->root_frame_sink_id(), local_surface_id); + + auto commit_predicate = base::BindRepeating( + [](const viz::BeginFrameId& current_frame_id, + const viz::FrameSinkId& root_frame_sink_id, + const viz::FrameSinkId& child_frame_sink_id, + const viz::SurfaceId& surface_id, + const viz::BeginFrameId& frame_id) { + // Always commit frame from different begin frame sources, because we + // can't order with them. + if (frame_id.source_id != current_frame_id.source_id) { + // We always should have single source_id except for the manual + // acks. + DCHECK_EQ(frame_id.source_id, viz::BeginFrameArgs::kManualSourceId); + return true; + } + + // Commit all frames that are older than current one. + if (frame_id.sequence_number < current_frame_id.sequence_number) + return true; + + // All clients except root renderer and root surface are frame behind. + const bool is_frame_behind = + surface_id.frame_sink_id() != root_frame_sink_id && + surface_id.frame_sink_id() != child_frame_sink_id; + + // If this surface is not frame behind, commit it for current frame + // too. + if (!is_frame_behind && + frame_id.sequence_number == current_frame_id.sequence_number) + return true; + + return false; + }, + child_frame->begin_frame_args.frame_id, root_surface_id.frame_sink_id(), + child_surface_id_.frame_sink_id()); + + GetFrameSinkManager()->surface_manager()->CommitFramesInRangeRecursively( + viz::SurfaceRange(root_surface_id), commit_predicate); + } + if (root_local_surface_id_ != local_surface_id) { root_local_surface_id_ = local_surface_id; display_->SetLocalSurfaceId(local_surface_id, device_scale_factor); @@ -260,6 +306,8 @@ display_->Resize(viewport); auto now = base::TimeTicks::Now(); display_->DrawAndSwap({now, now}); + + without_gpu_->SetContainedSurfaces(display_->GetContainedSurfaceIds()); } void HardwareRendererViz::OnViz::PostDrawOnViz(
diff --git a/android_webview/browser/gfx/root_frame_sink.cc b/android_webview/browser/gfx/root_frame_sink.cc index 4fd9baa..c8d3f9e5 100644 --- a/android_webview/browser/gfx/root_frame_sink.cc +++ b/android_webview/browser/gfx/root_frame_sink.cc
@@ -9,9 +9,11 @@ #include "android_webview/browser/gfx/viz_compositor_thread_runner_webview.h" #include "base/memory/raw_ptr.h" #include "base/trace_event/trace_event.h" +#include "components/viz/common/features.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" +#include "components/viz/service/surfaces/surface.h" namespace android_webview { @@ -85,7 +87,10 @@ }; RootFrameSink::RootFrameSink(RootFrameSinkClient* client) - : root_frame_sink_id_(AllocateParentSinkId()), client_(client) { + : root_frame_sink_id_(AllocateParentSinkId()), + client_(client), + use_new_invalidate_heuristic_(base::FeatureList::IsEnabled( + features::kWebViewNewInvalidateHeuristic)) { constexpr bool is_root = true; GetFrameSinkManager()->RegisterFrameSinkId(root_frame_sink_id_, false /* report_activationa */); @@ -94,6 +99,14 @@ begin_frame_source_ = std::make_unique<viz::ExternalBeginFrameSource>(this); GetFrameSinkManager()->RegisterBeginFrameSource(begin_frame_source_.get(), root_frame_sink_id_); + + // Note, that this technically not part of the new heuristic. Without this + // line root CF will "request" BeginFrames for delivery of presentation + // feedback that we don't care about which leads to more begin frame requested + // than necessary. But to avoid any side effects on invalidation, fixing this + // is gates under same feature flag. + if (use_new_invalidate_heuristic_) + support_->SetBeginFrameSource(nullptr); } RootFrameSink::~RootFrameSink() { @@ -162,9 +175,21 @@ TRACE_EVENT_INSTANT1("android_webview", "RootFrameSink::OnNeedsBeginFrames", TRACE_EVENT_SCOPE_THREAD, "needs_begin_frames", needs_begin_frames); - needs_begin_frames_ = needs_begin_frames; - if (client_) - client_->SetNeedsBeginFrames(needs_begin_frames); + clients_need_begin_frames_ = needs_begin_frames; + + // Old heuristic doesn't need extra begin frames, so just forward client + // needs. + if (!use_new_invalidate_heuristic_) { + UpdateNeedsBeginFrames(clients_need_begin_frames_); + return; + } + + // Make sure that we subscribed to BF if client needs them. We don't + // unsubscribe from BF here to make sure that we invalidated for the latest + // frames in necessary. We will stop observing them later in BeginFrame() + // once we are done. + if (clients_need_begin_frames_) + UpdateNeedsBeginFrames(true); } void RootFrameSink::AddChildFrameSinkId(const viz::FrameSinkId& frame_sink_id) { @@ -182,20 +207,123 @@ frame_sink_id); } +void RootFrameSink::SetContainedSurfaces( + const std::vector<viz::SurfaceId>& ids) { + contained_surfaces_ = base::flat_set<viz::SurfaceId>(ids.begin(), ids.end()); + for (auto it = last_invalidated_frame_id_.begin(); + it != last_invalidated_frame_id_.end();) { + if (!contained_surfaces_.contains(it->first)) + it = last_invalidated_frame_id_.erase(it); + else + ++it; + } +} + +void RootFrameSink::UpdateNeedsBeginFrames(bool needs_begin_frames) { + if (needs_begin_frames_ != needs_begin_frames) { + needs_begin_frames_ = needs_begin_frames; + if (client_) + client_->SetNeedsBeginFrames(needs_begin_frames_); + } +} + +bool RootFrameSink::HasPendingDependency(const viz::SurfaceId& surface_id) { + auto* surface = + GetFrameSinkManager()->surface_manager()->GetSurfaceForId(surface_id); + + if (!surface || !surface->HasActiveFrame()) + return true; + + for (auto& range : surface->GetActiveFrame().metadata.referenced_surfaces) { + if (HasPendingDependency(range.end())) + return true; + } + return false; +} + +bool RootFrameSink::ProcessVisibleSurfacesInvalidation() { + if (!use_new_invalidate_heuristic_) { + // This handles only invalidation of sub clients, root client invalidation + // is handled by Invalidate() from cc to |SynchronousLayerTreeFrameSink|. So + // we return false unless we already have damage. + return needs_draw_; + } + + bool invalidate = false; + + // There are few possible cases: + // * viz::Surface is visible (i.e was embedded last frame and any scheduled + // draws don't change that). In this case surface is in `contained_surfaces` + // and we need to invalidate for any CompositorFrame that we haven't + // invalidated yet. This is a steady state. + // * viz::Surface is visible, but there are scheduled draws that remove it. In + // this case surface is in `contained_surfaces`, but technically there is no + // need to invalidate it. We can't know that it will disappear, so we + // invalidate anyway. + // * viz::Surface is visible, but has pending dependencies (embedded surfaces + // without active frame). In this case surface is in `contained_surfaces`, but + // the dependents aren't. Invalidate in this case pessimistically assuming + // there are uncommitted frames that can be activated on commit in dependent + // frames. + // * viz::Surface is not visible yet, but there is a pending draw that will + // embed it. In this case the surface is not in `contained_surfaces` yet, so + // we can't process it here. After the draw will happen it's possible that + // there are uncommitted frames that are already scheduled to draw, but have + // not been processed here. This can cause extra invalidation. + // * viz::Surface is not visible and there is no pending draw. This shouldn't + // be possible because the only way to embed a child surface is for the root + // renderer to submit a compositor frame and invalidation of it is handled + // separately. + + // If there is pending dependency, invalidate. + if (root_local_surface_id_allocator_.HasValidLocalSurfaceId()) { + auto surface_id = viz::SurfaceId( + root_frame_sink_id(), + root_local_surface_id_allocator_.GetCurrentLocalSurfaceId()); + invalidate = invalidate || HasPendingDependency(surface_id); + } + + for (auto& surface_id : contained_surfaces_) { + auto* surface = + GetFrameSinkManager()->surface_manager()->GetSurfaceForId(surface_id); + if (surface) { + // Track last frame_id that we invalidated for. Note, that this doesn't + // take into account what current frame is or what display compositor will + // draw. The intent here is to invalidate once for each surface we see. + auto& last_invalidated_id = last_invalidated_frame_id_[surface_id]; + auto uncommited_frame_id = + last_invalidated_id.IsSequenceValid() + ? surface->GetUncommitedFrameIdNewerThan(last_invalidated_id) + : surface->GetFirstUncommitedFrameId(); + if (uncommited_frame_id.has_value()) { + invalidate = true; + last_invalidated_id = uncommited_frame_id.value(); + } + } + } + + return invalidate; +} + bool RootFrameSink::BeginFrame(const viz::BeginFrameArgs& args, bool had_input_event) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // This handles only invalidation of sub clients, root client invalidation is - // handled by Invalidate() from cc to |SynchronousLayerTreeFrameSink|. So we - // return false unless we already have damage. - bool invalidate = had_input_event || needs_draw_; + // We call ProcessVisibleSurfacesInvalidation() to make sure heuristic updated + // it's state (e.g last invalidated begin frame args). + bool invalidate = ProcessVisibleSurfacesInvalidation() || had_input_event; TRACE_EVENT_INSTANT1("android_webview", "RootFrameSink::BeginFrame", TRACE_EVENT_SCOPE_THREAD, "invalidate", invalidate); - if (needs_begin_frames_) { + if (clients_need_begin_frames_) { begin_frame_source_->OnBeginFrame(args); + } else if (!invalidate) { + if (use_new_invalidate_heuristic_) { + // Client don't need begin frames and we didn't invalidate, so we don't + // need them either. + UpdateNeedsBeginFrames(false); + } } return invalidate; @@ -207,6 +335,9 @@ } void RootFrameSink::SetNeedsDraw(bool needs_draw) { + // Only old heuristic needs this. + DCHECK(!use_new_invalidate_heuristic_); + needs_draw_ = needs_draw; // It's possible that client submitted last frame and unsubscribed from @@ -217,6 +348,17 @@ } } +void RootFrameSink::OnNewUncommittedFrame(const viz::SurfaceId& surface_id) { + // Only new heurstic needs this. + if (!use_new_invalidate_heuristic_) + return; + + // If there is new uncommitted frame in visible surface, make sure we request + // a begin frame to check if we need to invalidate next frame. + if (contained_surfaces_.contains(surface_id)) + UpdateNeedsBeginFrames(true); +} + bool RootFrameSink::IsChildSurface(const viz::FrameSinkId& frame_sink_id) { return child_frame_sink_ids_.contains(frame_sink_id); } @@ -255,6 +397,10 @@ } viz::FrameTimingDetailsMap RootFrameSink::TakeChildFrameTimingDetailsMap() { + // Take timing for root CompositorFrameSinkSupport to avoid them accumulating. + // We don't use them anyhow. + std::ignore = support_->TakeFrameTimingDetailsMap(); + if (child_sink_support_) return child_sink_support_->support()->TakeFrameTimingDetailsMap(); return viz::FrameTimingDetailsMap();
diff --git a/android_webview/browser/gfx/root_frame_sink.h b/android_webview/browser/gfx/root_frame_sink.h index 856c25d..8b78aec 100644 --- a/android_webview/browser/gfx/root_frame_sink.h +++ b/android_webview/browser/gfx/root_frame_sink.h
@@ -65,9 +65,11 @@ bool BeginFrame(const viz::BeginFrameArgs& args, bool had_input_event); void SetBeginFrameSourcePaused(bool paused); void SetNeedsDraw(bool needs_draw); + void OnNewUncommittedFrame(const viz::SurfaceId& surface_id); bool IsChildSurface(const viz::FrameSinkId& frame_sink_id); void DettachClient(); void EvictChildSurface(const viz::SurfaceId& surface_id); + void SetContainedSurfaces(const std::vector<viz::SurfaceId>& ids); void SubmitChildCompositorFrame(ChildFrame* child_frame); viz::FrameTimingDetailsMap TakeChildFrameTimingDetailsMap(); @@ -96,6 +98,10 @@ uint32_t layer_tree_frame_sink_id, std::vector<viz::ReturnedResource> resources); + bool HasPendingDependency(const viz::SurfaceId& surface_id); + void UpdateNeedsBeginFrames(bool needs_begin_frame); + bool ProcessVisibleSurfacesInvalidation(); + const viz::FrameSinkId root_frame_sink_id_; base::flat_set<viz::FrameSinkId> child_frame_sink_ids_; std::unique_ptr<viz::CompositorFrameSinkSupport> support_; @@ -108,9 +114,15 @@ std::unique_ptr<ChildCompositorFrameSink> child_sink_support_; + bool clients_need_begin_frames_ = false; bool needs_begin_frames_ = false; + bool needs_draw_ = false; raw_ptr<RootFrameSinkClient> client_; + base::flat_set<viz::SurfaceId> contained_surfaces_; + std::map<viz::SurfaceId, viz::BeginFrameId> last_invalidated_frame_id_; + + const bool use_new_invalidate_heuristic_; THREAD_CHECKER(thread_checker_); };
diff --git a/android_webview/browser/gfx/viz_compositor_thread_runner_webview.cc b/android_webview/browser/gfx/viz_compositor_thread_runner_webview.cc index 37c02f7a..39af6fba 100644 --- a/android_webview/browser/gfx/viz_compositor_thread_runner_webview.cc +++ b/android_webview/browser/gfx/viz_compositor_thread_runner_webview.cc
@@ -13,6 +13,7 @@ #include "base/notreached.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread_restrictions.h" +#include "components/viz/common/features.h" #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" @@ -68,9 +69,18 @@ // SharedBitmap. server_shared_bitmap_manager_ = std::make_unique<viz::ServerSharedBitmapManager>(); - frame_sink_manager_ = std::make_unique<viz::FrameSinkManagerImpl>( - viz::FrameSinkManagerImpl::InitParams( - server_shared_bitmap_manager_.get())); + + auto init_params = viz::FrameSinkManagerImpl::InitParams( + server_shared_bitmap_manager_.get()); + + if (base::FeatureList::IsEnabled(features::kWebViewNewInvalidateHeuristic)) { + // HWUI has 2 frames pipelineing and we need another one because we force + // client to be frame behind. + init_params.max_uncommitted_frames = 3; + } + + frame_sink_manager_ = + std::make_unique<viz::FrameSinkManagerImpl>(init_params); } viz::FrameSinkManagerImpl*
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 696caa96..19658fa1 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -1773,6 +1773,9 @@ <message name="IDS_ASH_OVERVIEW_CLOSABLE_HIGHLIGHT_ITEM_A11Y_EXTRA_TIP" desc="The accessibility tooltip read by screen readers for a close-able overview item."> Press Ctrl + W to close. </message> + <message name="IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP" desc="The accessibility text read by screen readers for a closeable desk mini view when the close all feature is enabled."> + Press Ctrl + W to combine with <ph name="DESK_NAME">$1<ex>Desk 1</ex></ph>. Press Ctrl + Shift + W to close desk and windows. + </message> <message name="IDS_ASH_OVERVIEW_WINDOW_CLOSING_A11Y_ALERT" desc="The accessibility alert read by screen readers to alert the user that a window in overview mode is closing."> Window <ph name="WINDOW_TITILE">$1<ex>1</ex></ph> closed. </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 new file mode 100644 index 0000000..0b5e479 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1
@@ -0,0 +1 @@ +c0ffe8f27b8c2930819fe7b0648bbf06e1ac1c62 \ No newline at end of file
diff --git a/ash/capture_mode/video_recording_watcher.cc b/ash/capture_mode/video_recording_watcher.cc index 0b5d669..8f88c92 100644 --- a/ash/capture_mode/video_recording_watcher.cc +++ b/ash/capture_mode/video_recording_watcher.cc
@@ -240,8 +240,10 @@ std::make_unique<RecordingOverlayController>(window_being_recorded_, GetOverlayWidgetBounds()); } - if (features::IsProjectorEnabled()) - ProjectorControllerImpl::Get()->OnRecordingStarted(is_in_projector_mode_); + if (features::IsProjectorEnabled()) { + ProjectorControllerImpl::Get()->OnRecordingStarted(current_root_, + is_in_projector_mode_); + } } VideoRecordingWatcher::~VideoRecordingWatcher() { @@ -405,6 +407,9 @@ root_observer_ = std::make_unique<RecordedWindowRootObserver>(current_root_, this); controller_->OnRecordedWindowChangingRoot(window_being_recorded_, new_root); + + if (is_in_projector_mode_) + ProjectorControllerImpl::Get()->OnRecordedWindowChangingRoot(new_root); } void VideoRecordingWatcher::OnPaintLayer(const ui::PaintContext& context) {
diff --git a/ash/components/hid_detection/BUILD.gn b/ash/components/hid_detection/BUILD.gn index ff38a765..dc67411 100644 --- a/ash/components/hid_detection/BUILD.gn +++ b/ash/components/hid_detection/BUILD.gn
@@ -28,6 +28,20 @@ ] } +static_library("test_support") { + testonly = true + + sources = [ + "fake_bluetooth_hid_detector.cc", + "fake_bluetooth_hid_detector.h", + ] + + deps = [ + ":hid_detection", + "//base", + ] +} + source_set("unit_tests") { testonly = true
diff --git a/ash/components/hid_detection/fake_bluetooth_hid_detector.cc b/ash/components/hid_detection/fake_bluetooth_hid_detector.cc new file mode 100644 index 0000000..ffd8b0a3 --- /dev/null +++ b/ash/components/hid_detection/fake_bluetooth_hid_detector.cc
@@ -0,0 +1,58 @@ +// Copyright 2022 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 "ash/components/hid_detection/fake_bluetooth_hid_detector.h" + +namespace ash { +namespace hid_detection { + +FakeBluetoothHidDetector::FakeBluetoothHidDetector() = default; + +FakeBluetoothHidDetector::~FakeBluetoothHidDetector() = default; + +void FakeBluetoothHidDetector::SetInputDevicesStatus( + InputDevicesStatus input_devices_status) { + input_devices_status_ = input_devices_status; +} + +const BluetoothHidDetector::BluetoothHidDetectionStatus +FakeBluetoothHidDetector::GetBluetoothHidDetectionStatus() { + absl::optional<BluetoothHidMetadata> current_pairing_device; + if (current_pairing_device_.has_value()) { + current_pairing_device = + BluetoothHidMetadata{current_pairing_device_.value().name, + current_pairing_device_.value().type}; + } + + absl::optional<BluetoothHidPairingState> pairing_state; + if (current_pairing_state_.has_value()) { + pairing_state = BluetoothHidPairingState{ + current_pairing_state_.value().code, + current_pairing_state_.value().num_keys_entered}; + } + + return BluetoothHidDetectionStatus{std::move(current_pairing_device), + std::move(pairing_state)}; +} + +void FakeBluetoothHidDetector::SetBluetoothHidDetectionStatus( + absl::optional<BluetoothHidDetector::BluetoothHidMetadata> pairing_device, + absl::optional<BluetoothHidPairingState> pairing_state) { + current_pairing_device_ = std::move(pairing_device); + current_pairing_state_ = std::move(pairing_state); + NotifyBluetoothHidDetectionStatusChanged(); +} + +void FakeBluetoothHidDetector::PerformStartBluetoothHidDetection( + InputDevicesStatus input_devices_status) { + input_devices_status_ = input_devices_status; + is_bluetooth_hid_detection_active_ = true; +} + +void FakeBluetoothHidDetector::PerformStopBluetoothHidDetection() { + is_bluetooth_hid_detection_active_ = false; +} + +} // namespace hid_detection +} // namespace ash
diff --git a/ash/components/hid_detection/fake_bluetooth_hid_detector.h b/ash/components/hid_detection/fake_bluetooth_hid_detector.h new file mode 100644 index 0000000..6a9873ff --- /dev/null +++ b/ash/components/hid_detection/fake_bluetooth_hid_detector.h
@@ -0,0 +1,53 @@ +// Copyright 2022 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 ASH_COMPONENTS_HID_DETECTION_FAKE_BLUETOOTH_HID_DETECTOR_H_ +#define ASH_COMPONENTS_HID_DETECTION_FAKE_BLUETOOTH_HID_DETECTOR_H_ + +#include "ash/components/hid_detection/bluetooth_hid_detector.h" + +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace ash { +namespace hid_detection { + +class FakeBluetoothHidDetector : public BluetoothHidDetector { + public: + FakeBluetoothHidDetector(); + ~FakeBluetoothHidDetector() override; + + // BluetoothHidDetector: + void SetInputDevicesStatus(InputDevicesStatus input_devices_status) override; + const BluetoothHidDetectionStatus GetBluetoothHidDetectionStatus() override; + + // Updates the HID detection status returned by + // GetBluetoothHidDetectionStatus() and notifies the client. + void SetBluetoothHidDetectionStatus( + absl::optional<BluetoothHidDetector::BluetoothHidMetadata> pairing_device, + absl::optional<BluetoothHidPairingState> pairing_state); + + const InputDevicesStatus& input_devices_status() { + return input_devices_status_; + } + + bool is_bluetooth_hid_detection_active() { + return is_bluetooth_hid_detection_active_; + } + + private: + // BluetoothHidDetector: + void PerformStartBluetoothHidDetection( + InputDevicesStatus input_devices_status) override; + void PerformStopBluetoothHidDetection() override; + + InputDevicesStatus input_devices_status_; + absl::optional<BluetoothHidMetadata> current_pairing_device_; + absl::optional<BluetoothHidPairingState> current_pairing_state_; + bool is_bluetooth_hid_detection_active_ = false; +}; + +} // namespace hid_detection +} // namespace ash + +#endif // ASH_COMPONENTS_HID_DETECTION_FAKE_BLUETOOTH_HID_DETECTOR_H_
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 24bf0ee..d1bd87dd 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -39,6 +39,10 @@ const base::Feature kAllowAmbientEQ{"AllowAmbientEQ", base::FEATURE_DISABLED_BY_DEFAULT}; +// Allows pairing to Bluetooth devices created by Poly. See b/228118615. +const base::Feature kAllowPolyDevicePairing{"AllowPolyDevicePairing", + base::FEATURE_ENABLED_BY_DEFAULT}; + // Controls whether devices are updated before reboot after the first update. const base::Feature kAllowRepeatedUpdates{"AllowRepeatedUpdates", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -2067,6 +2071,10 @@ return base::FeatureList::IsEnabled(kPipRoundedCorners); } +bool IsPolyDevicePairingAllowed() { + return base::FeatureList::IsEnabled(kAllowPolyDevicePairing); +} + bool IsProductivityLauncherEnabled() { return base::FeatureList::IsEnabled(kProductivityLauncher); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 8ce0dcb..92afcf9 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -23,6 +23,8 @@ extern const base::Feature kAdjustSplitViewForVK; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAllowAmbientEQ; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kAllowPolyDevicePairing; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAllowRepeatedUpdates; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAllowScrollSettings; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAmbientModeFeature; @@ -726,6 +728,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPinAutosubmitBackfillFeatureEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPinAutosubmitFeatureEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPipRoundedCornersEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPolyDevicePairingAllowed(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProductivityLauncherEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProjectorEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProjectorAllUserEnabled();
diff --git a/ash/drag_drop/drag_drop_capture_delegate.cc b/ash/drag_drop/drag_drop_capture_delegate.cc index abc2829..2b7a266 100644 --- a/ash/drag_drop/drag_drop_capture_delegate.cc +++ b/ash/drag_drop/drag_drop_capture_delegate.cc
@@ -9,6 +9,7 @@ #include "ui/aura/window_delegate.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_observer.h" +#include "ui/aura/window_tracker.h" #include "ui/base/hit_test.h" #include "ui/events/event.h" #include "ui/events/event_target.h" @@ -40,10 +41,8 @@ window->delegate()->OnGestureEvent(&gesture_end); } -DragDropCaptureDelegate::DragDropCaptureDelegate() {} -DragDropCaptureDelegate::~DragDropCaptureDelegate() { - drag_drop_tracker_.reset(); -} +DragDropCaptureDelegate::DragDropCaptureDelegate() = default; +DragDropCaptureDelegate::~DragDropCaptureDelegate() = default; bool DragDropCaptureDelegate::TakeCapture( aura::Window* root_window, @@ -54,12 +53,24 @@ // We need to transfer the current gesture sequence and the GR's touch event // queue to the |drag_drop_tracker_|'s capture window so that when it takes // capture, it still gets a valid gesture state. - aura::Env::GetInstance()->gesture_recognizer()->TransferEventsTo( + aura::Window* capture_window = drag_drop_tracker_->capture_window(); + aura::WindowTracker tracker({source_window, capture_window}); + auto* gesture_recognizer = aura::Env::GetInstance()->gesture_recognizer(); + gesture_recognizer->TransferEventsTo( source_window, drag_drop_tracker_->capture_window(), behavior); - // We also send a gesture end and touch cancel to the source window so it can - // clear state. TODO(varunjain): Remove this whole block when gesture - // sequence transferring is properly done in the GR (http://crbug.com/160558) - NotifyWindowOfTouchDispatchGestureEnd(source_window); + if (tracker.Contains(source_window)) { + // We also send a gesture end and touch cancel to the source window so it + // can clear state. TODO(varunjain): Remove this whole block when gesture + // sequence transferring is properly done in the GR + // (http://crbug.com/160558) + NotifyWindowOfTouchDispatchGestureEnd(source_window); + } + if (!tracker.Contains(capture_window)) { + // This means the drag was cancelled during event transfer. + // See: crbug.com/1297209. + gesture_recognizer->CleanupStateForConsumer(capture_window); + return false; + } drag_drop_tracker_->TakeCapture(); return true; }
diff --git a/ash/drag_drop/drag_drop_capture_delegate.h b/ash/drag_drop/drag_drop_capture_delegate.h index 0c42535..52117c006 100644 --- a/ash/drag_drop/drag_drop_capture_delegate.h +++ b/ash/drag_drop/drag_drop_capture_delegate.h
@@ -29,7 +29,7 @@ DragDropCaptureDelegate(const DragDropCaptureDelegate&) = delete; DragDropCaptureDelegate& operator=(const DragDropCaptureDelegate&) = delete; - ~DragDropCaptureDelegate(); + virtual ~DragDropCaptureDelegate(); // Conditionally takes capture of top level touch events, returning whether // this was successful.
diff --git a/ash/drag_drop/drag_drop_capture_delegate_unittest.cc b/ash/drag_drop/drag_drop_capture_delegate_unittest.cc index ca69fcb9..ddb3744 100644 --- a/ash/drag_drop/drag_drop_capture_delegate_unittest.cc +++ b/ash/drag_drop/drag_drop_capture_delegate_unittest.cc
@@ -151,6 +151,8 @@ EXPECT_EQ(source_window_delegate.motion_event.GetAction(), ui::MotionEvent::Action::CANCEL); + + drag_drop_controller->DragCancel(); } } // namespace ash
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc index f763716..5492d4c 100644 --- a/ash/drag_drop/drag_drop_controller.cc +++ b/ash/drag_drop/drag_drop_controller.cc
@@ -154,20 +154,21 @@ current_drag_event_source_ = source; capture_delegate_ = nullptr; - bool touch_captured = false; + const bool is_touch_source = source == ui::mojom::DragEventSource::kTouch; + bool touch_capture_attempted = false; // When an extended drag is started, a capture window will be created to // handle moving gestures between different wl surfaces to support dragging // chrome tabs into and out of browsers. - if (source == ui::mojom::DragEventSource::kTouch && - toplevel_window_drag_delegate_) { - touch_captured = true; - toplevel_window_drag_delegate_->TakeCapture( - root_window, source_window, - base::BindRepeating(&DragDropController::CancelIfInProgress, - base::Unretained(this)), - ui::TransferTouchesBehavior::kCancel); - capture_delegate_ = toplevel_window_drag_delegate_; + if (is_touch_source && toplevel_window_drag_delegate_) { + touch_capture_attempted = true; + if (toplevel_window_drag_delegate_->TakeCapture( + root_window, source_window, + base::BindRepeating(&DragDropController::CancelIfInProgress, + base::Unretained(this)), + ui::TransferTouchesBehavior::kCancel)) { + capture_delegate_ = toplevel_window_drag_delegate_; + } } drag_source_window_ = source_window; @@ -199,43 +200,50 @@ } if (TabDragDropDelegate::IsChromeTabDrag(*drag_data_)) { + // TODO(aluh): Figure out why this allocation is outside the inner if-block. DCHECK(!tab_drag_drop_delegate_); tab_drag_drop_delegate_ = std::make_unique<TabDragDropDelegate>( root_window, drag_source_window_, start_location_); static_cast<DragImageView*>(drag_image_widget_->GetContentsView()) ->SetTouchDragOperationHintOff(); // Avoid taking capture twice. - if (!touch_captured && source == ui::mojom::DragEventSource::kTouch) { - touch_captured = true; - tab_drag_drop_delegate_->TakeCapture( - root_window, source_window, - base::BindRepeating(&DragDropController::CancelIfInProgress, - base::Unretained(this)), - ui::TransferTouchesBehavior::kDontCancel); - capture_delegate_ = tab_drag_drop_delegate_.get(); + if (is_touch_source && !touch_capture_attempted) { + touch_capture_attempted = true; + if (tab_drag_drop_delegate_->TakeCapture( + root_window, source_window, + base::BindRepeating(&DragDropController::CancelIfInProgress, + base::Unretained(this)), + ui::TransferTouchesBehavior::kDontCancel)) { + capture_delegate_ = tab_drag_drop_delegate_.get(); + } } } // If touch is not captured by either extended drag nor tab drag, start // a normal drag-and-drop using DragDropCaptureDelegate. - if (!touch_captured && source == ui::mojom::DragEventSource::kTouch) { - touch_captured = true; + if (is_touch_source && !touch_capture_attempted) { + touch_capture_attempted = true; // For other type of touch drag, use normal DDCaptureDelegate; touch_drag_drop_delegate_ = std::make_unique<DragDropCaptureDelegate>(); - touch_drag_drop_delegate_->TakeCapture( - root_window, source_window, - base::BindRepeating(&DragDropController::CancelIfInProgress, - base::Unretained(this)), - ui::TransferTouchesBehavior::kDontCancel); - capture_delegate_ = touch_drag_drop_delegate_.get(); + if (touch_drag_drop_delegate_->TakeCapture( + root_window, source_window, + base::BindRepeating(&DragDropController::CancelIfInProgress, + base::Unretained(this)), + ui::TransferTouchesBehavior::kDontCancel)) { + capture_delegate_ = touch_drag_drop_delegate_.get(); + } } - if (test_loop_closure_) { - while (!quit_closure_.is_null()) - test_loop_closure_.Run(); + if (touch_capture_attempted && !capture_delegate_) { + Cleanup(); } else { - base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - quit_closure_ = run_loop.QuitClosure(); - run_loop.Run(); + if (test_loop_closure_) { + while (!quit_closure_.is_null()) + test_loop_closure_.Run(); + } else { + base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); + quit_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + } } if (!cancel_animation_.get() || !cancel_animation_->is_animating() ||
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc index bf121164..a347d5d 100644 --- a/ash/drag_drop/drag_drop_controller_unittest.cc +++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -13,6 +13,8 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test_shell_delegate.h" +#include "ash/wm/splitview/split_view_controller.h" +#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "base/command_line.h" @@ -1566,6 +1568,8 @@ EXPECT_TRUE(delegate.current_location().has_value()); EXPECT_EQ(gfx::PointF(5, 5), *delegate.current_location()); EXPECT_EQ(0, delegate.events_forwarded()); + + drag_drop_controller_->DragCancel(); } TEST_F(DragDropControllerTest, ToplevelWindowDragDelegateWithTouch2) { @@ -1638,6 +1642,56 @@ drag_drop_controller_.reset(); } +// Regression test for crbug.com/1297209. +// In tablet mode split view, with the browser tab strip on one side and desks +// overview (or any other window) on the other, touch and hold a desk mini view +// (or that other window) and drag a browser tab simultaneously. +TEST_F(DragDropControllerTest, TabletSplitViewDragTwoBrowserTabs) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kWebUITabStripTabDragIntegration); + + // Enter tablet mode. Avoid TabletModeController::OnGetSwitchStates() from + // disabling tablet mode. + base::RunLoop().RunUntilIdle(); + ash::TabletModeControllerTestApi().EnterTabletMode(); + + // Enter tablet split view mode by snapping a tab window on each side. + // A generic top level window is enough to fake a chrome tab. + std::unique_ptr<aura::Window> tab_window1 = CreateToplevelTestWindow(); + std::unique_ptr<aura::Window> tab_window2 = CreateToplevelTestWindow(); + SplitViewController* const split_view_controller = + SplitViewController::Get(tab_window1.get()); + split_view_controller->SnapWindow(tab_window1.get(), + SplitViewController::SnapPosition::LEFT); + split_view_controller->SnapWindow(tab_window2.get(), + SplitViewController::SnapPosition::RIGHT); + EXPECT_TRUE(split_view_controller->InTabletSplitViewMode()); + + // Touch and hold the right tab window. + GetEventGenerator()->PressTouch( + tab_window2->GetBoundsInScreen().CenterPoint()); + + // Prepare to drag the left tab window. + EXPECT_CALL(*mock_shell_delegate(), IsTabDrag(_)).WillOnce(Return(true)); + + // Drag and drop needs a drag image to work. + auto data = std::make_unique<ui::OSExchangeData>(); + data->SetString(u"I am being dragged"); + gfx::ImageSkiaRep image_rep(gfx::Size(10, 20), 1.0f); + gfx::ImageSkia image_skia(image_rep); + data->provider().SetDragImage(image_skia, gfx::Vector2d()); + + // Start drag and drop on the left tab window. + auto drag_operation = drag_drop_controller_->StartDragAndDrop( + std::move(data), tab_window1->GetRootWindow(), tab_window1.get(), + tab_window1->GetBoundsInScreen().CenterPoint(), + ui::DragDropTypes::DRAG_MOVE, ui::mojom::DragEventSource::kTouch); + EXPECT_EQ(drag_operation, DragOperation::kNone); + EXPECT_FALSE(drag_drop_controller_->IsDragDropInProgress()); + EXPECT_FALSE(drag_drop_controller_->get_capture_delegate()); + EXPECT_FALSE(tab_window1->HasObserver(drag_drop_controller_.get())); +} + namespace { class MockDataTransferPolicyController
diff --git a/ash/drag_drop/tab_drag_drop_delegate.cc b/ash/drag_drop/tab_drag_drop_delegate.cc index ad06a46..9b00c7b 100644 --- a/ash/drag_drop/tab_drag_drop_delegate.cc +++ b/ash/drag_drop/tab_drag_drop_delegate.cc
@@ -167,16 +167,20 @@ const gfx::Point& location_in_screen, aura::Window* new_window) { auto is_lacros = IsLacrosWindow(source_window_); - if (!new_window && is_lacros && - !crosapi::lacros_startup_state::IsLacrosPrimaryEnabled()) { - LOG(ERROR) - << "New browser window creation for tab detaching failed.\n" - << "Check whether about:flags#lacros-primary is enabled or " - << "--enable-features=LacrosPrimary is passed in when launching Ash"; + + // https://crbug.com/1286203: + // It's possible new window is created when the dragged WebContents + // closes itself during the drag session. + if (!new_window) { + if (is_lacros && !crosapi::lacros_startup_state::IsLacrosPrimaryEnabled()) { + LOG(ERROR) + << "New browser window creation for tab detaching failed.\n" + << "Check whether about:flags#lacros-primary is enabled or " + << "--enable-features=LacrosPrimary is passed in when launching Ash"; + } return; } - DCHECK(new_window) << "New browser window creation for tab detaching failed."; const gfx::Rect area = screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( root_window_);
diff --git a/ash/drag_drop/tab_drag_drop_delegate.h b/ash/drag_drop/tab_drag_drop_delegate.h index 22254fb4..60b5d873 100644 --- a/ash/drag_drop/tab_drag_drop_delegate.h +++ b/ash/drag_drop/tab_drag_drop_delegate.h
@@ -45,7 +45,7 @@ TabDragDropDelegate(aura::Window* root_window, aura::Window* source_window, const gfx::Point& start_location_in_screen); - ~TabDragDropDelegate(); + ~TabDragDropDelegate() override; TabDragDropDelegate(const TabDragDropDelegate&) = delete; TabDragDropDelegate& operator=(const TabDragDropDelegate&) = delete; @@ -61,6 +61,8 @@ const ui::OSExchangeData& drop_data); private: + FRIEND_TEST_ALL_PREFIXES(TabDragDropDelegateTest, DropWithoutNewWindow); + // Scales or transforms the source window if appropriate for this drag. // |candidate_snap_position| is where the dragged tab will be snapped // if dropped immediately.
diff --git a/ash/drag_drop/tab_drag_drop_delegate_unittest.cc b/ash/drag_drop/tab_drag_drop_delegate_unittest.cc index ea9726e..c949239 100644 --- a/ash/drag_drop/tab_drag_drop_delegate_unittest.cc +++ b/ash/drag_drop/tab_drag_drop_delegate_unittest.cc
@@ -567,4 +567,15 @@ "Ash.TabDrag.PresentationTime.MaxLatency.TabletMode", 1); } +// There are edge cases where a dragging tab closes itself before being dropped. +// In these cases new window will be nullptr and it +// should be handled gracefully. https://crbug.com/1286203 +TEST_F(TabDragDropDelegateTest, DropWithoutNewWindow) { + std::unique_ptr<aura::Window> source_window = CreateToplevelTestWindow(); + const gfx::Point drag_location = source_window->bounds().CenterPoint(); + auto delegate = std::make_unique<TabDragDropDelegate>( + Shell::GetPrimaryRootWindow(), source_window.get(), drag_location); + delegate->OnNewBrowserWindowCreated(drag_location, /*new_window=*/nullptr); +} + } // namespace ash
diff --git a/ash/drag_drop/toplevel_window_drag_delegate.h b/ash/drag_drop/toplevel_window_drag_delegate.h index 3eaf9ab..0f2c6d78 100644 --- a/ash/drag_drop/toplevel_window_drag_delegate.h +++ b/ash/drag_drop/toplevel_window_drag_delegate.h
@@ -38,7 +38,7 @@ virtual void OnToplevelWindowDragEvent(ui::LocatedEvent* event) = 0; protected: - virtual ~ToplevelWindowDragDelegate() = default; + ~ToplevelWindowDragDelegate() override = default; }; } // namespace ash
diff --git a/ash/projector/projector_controller_impl.cc b/ash/projector/projector_controller_impl.cc index 55df2a4..2adc2db 100644 --- a/ash/projector/projector_controller_impl.cc +++ b/ash/projector/projector_controller_impl.cc
@@ -287,13 +287,14 @@ ui_controller_->OnCanvasInitialized(success); } -void ProjectorControllerImpl::OnRecordingStarted(bool is_in_projector_mode) { +void ProjectorControllerImpl::OnRecordingStarted(aura::Window* current_root, + bool is_in_projector_mode) { if (!is_in_projector_mode) { OnNewScreencastPreconditionChanged(); return; } if (ui_controller_) - ui_controller_->ShowToolbar(); + ui_controller_->ShowToolbar(current_root); StartSpeechRecognition(); metadata_controller_->OnRecordingStarted(); @@ -316,6 +317,13 @@ RecordCreationFlowMetrics(ProjectorCreationFlow::kRecordingEnded); } +void ProjectorControllerImpl::OnRecordedWindowChangingRoot( + aura::Window* new_root) { + DCHECK(projector_session_->is_active()); + + ui_controller_->OnRecordedWindowChangingRoot(new_root); +} + void ProjectorControllerImpl::OnDlpRestrictionCheckedAtVideoEnd( bool is_in_projector_mode, bool user_deleted_video_file,
diff --git a/ash/projector/projector_controller_impl.h b/ash/projector/projector_controller_impl.h index def9107..a4c38b0 100644 --- a/ash/projector/projector_controller_impl.h +++ b/ash/projector/projector_controller_impl.h
@@ -14,6 +14,10 @@ #include "ash/public/cpp/projector/projector_controller.h" #include "third_party/skia/include/core/SkColor.h" +namespace aura { +class Window; +} // namespace aura + namespace base { class FilePath; } // namespace base @@ -83,14 +87,17 @@ CreateScreencastContainerFolderCallback callback); // Called by Capture Mode to notify with the state of a video recording. - // `is_in_projector_mode` indicates whether it's a projector-initiated video - // recording. `user_deleted_video_file` will be true, if the user deletes the - // file from a DLP warning dialog that can be shown after recording ends. - // `thumbnail` contains an image representation of the video, which can be - // empty if there were errors during recording. - void OnRecordingStarted(bool is_in_projector_mode); + // `current_root` is the window being recorded. `is_in_projector_mode` + // indicates whether it's a projector-initiated video recording. + void OnRecordingStarted(aura::Window* current_root, + bool is_in_projector_mode); void OnRecordingEnded(bool is_in_projector_mode); + // Called only when recording is in projector mode. When the window being + // recorded is moved from one display to another, we need to move the + // projector annotation tray to follow it. + void OnRecordedWindowChangingRoot(aura::Window* new_root); + // Called when the status of the video is confirmed. DLP can potentially show // users a dialog to warn them about restricted contents in the video, and // recommending that they delete the file. In this case,
diff --git a/ash/projector/projector_controller_unittest.cc b/ash/projector/projector_controller_unittest.cc index ce19fab65..a6fceb57 100644 --- a/ash/projector/projector_controller_unittest.cc +++ b/ash/projector/projector_controller_unittest.cc
@@ -19,6 +19,7 @@ #include "ash/projector/test/mock_projector_ui_controller.h" #include "ash/public/cpp/projector/projector_new_screencast_precondition.h" #include "ash/public/cpp/projector/projector_session.h" +#include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "base/bind.h" #include "base/callback_forward.h" @@ -245,9 +246,10 @@ EXPECT_CALL(mock_client_, StartSpeechRecognition()); EXPECT_CALL(*mock_metadata_controller_, OnRecordingStarted()); // Verify that |CloseToolbar| in |ProjectorUiController| is called. - EXPECT_CALL(*mock_ui_controller_, ShowToolbar()).Times(1); + auto* root = Shell::GetPrimaryRootWindow(); + EXPECT_CALL(*mock_ui_controller_, ShowToolbar(root)).Times(1); - controller_->OnRecordingStarted(/*is_in_projector_mode=*/true); + controller_->OnRecordingStarted(root, /*is_in_projector_mode=*/true); histogram_tester_.ExpectUniqueSample( kProjectorCreationFlowHistogramName, /*sample=*/ProjectorCreationFlow::kRecordingStarted, /*count=*/1); @@ -273,7 +275,8 @@ kProjectorCreationFlowHistogramName, /*sample=*/ProjectorCreationFlow::kSessionStarted, /*count=*/1); - controller_->OnRecordingStarted(/*is_in_projector_mode=*/true); + controller_->OnRecordingStarted(Shell::GetPrimaryRootWindow(), + /*is_in_projector_mode=*/true); histogram_tester_.ExpectBucketCount( kProjectorCreationFlowHistogramName, /*sample=*/ProjectorCreationFlow::kRecordingStarted, /*count=*/1); @@ -343,7 +346,8 @@ kProjectorCreationFlowHistogramName, /*sample=*/ProjectorCreationFlow::kSessionStarted, /*count=*/1); - controller_->OnRecordingStarted(/*is_in_projector_mode=*/true); + controller_->OnRecordingStarted(Shell::GetPrimaryRootWindow(), + /*is_in_projector_mode=*/true); histogram_tester_.ExpectBucketCount( kProjectorCreationFlowHistogramName, /*sample=*/ProjectorCreationFlow::kRecordingStarted, /*count=*/1);
diff --git a/ash/projector/projector_ui_controller.cc b/ash/projector/projector_ui_controller.cc index 544e1af..09dafc2d 100644 --- a/ash/projector/projector_ui_controller.cc +++ b/ash/projector/projector_ui_controller.cc
@@ -49,6 +49,32 @@ constexpr char kProjectorSaveErrorNotificationId[] = "projector_save_error_notification"; +ProjectorAnnotationTray* GetProjectorAnnotationTrayForRoot(aura::Window* root) { + DCHECK(root); + DCHECK(root->IsRootWindow()); + + // Recording can end when a display being fullscreen-captured gets removed, in + // this case, we don't need to hide the button. + if (root->is_destroying()) + return nullptr; + + // Can be null while shutting down. + auto* root_window_controller = RootWindowController::ForWindow(root); + if (!root_window_controller) + return nullptr; + + auto* projector_annotation_tray = + root_window_controller->GetStatusAreaWidget() + ->projector_annotation_tray(); + DCHECK(projector_annotation_tray); + return projector_annotation_tray; +} + +void SetProjectorAnnotationTrayVisibility(aura::Window* root, bool visible) { + if (auto* projector_annotation_tray = GetProjectorAnnotationTrayForRoot(root)) + projector_annotation_tray->SetVisiblePreferred(visible); +} + void ToggleAnnotator() { auto* capture_mode_controller = CaptureModeController::Get(); // TODO(b/200292852): This check should not be necessary, but because @@ -120,23 +146,23 @@ ProjectorUiController::~ProjectorUiController() = default; -void ProjectorUiController::ShowToolbar() { - // Show the tray icon - auto* projector_annotation_tray = Shell::GetPrimaryRootWindowController() - ->GetStatusAreaWidget() - ->projector_annotation_tray(); - DCHECK(projector_annotation_tray); - projector_annotation_tray->SetVisiblePreferred(true); +void ProjectorUiController::ShowToolbar(aura::Window* current_root) { + current_root_ = current_root; + + // Show the tray icon. + SetProjectorAnnotationTrayVisibility(current_root_, /*visible=*/true); } void ProjectorUiController::CloseToolbar() { ResetTools(); - // Hide the tray icon - auto* projector_annotation_tray = Shell::GetPrimaryRootWindowController() - ->GetStatusAreaWidget() - ->projector_annotation_tray(); - DCHECK(projector_annotation_tray); - projector_annotation_tray->HideAnnotationTray(); + // Hide the tray icon. + if (auto* projector_annotation_tray = + GetProjectorAnnotationTrayForRoot(current_root_)) { + projector_annotation_tray->HideAnnotationTray(); + } + + should_enable_annotation_tray_button_.reset(); + current_root_ = nullptr; } void ProjectorUiController::OnMarkerPressed() { @@ -162,17 +188,30 @@ } } +// TODO(b/232419423): Rename this function. void ProjectorUiController::OnCanvasInitialized(bool success) { - auto* projector_annotation_tray = Shell::GetPrimaryRootWindowController() - ->GetStatusAreaWidget() - ->projector_annotation_tray(); - DCHECK(projector_annotation_tray); - projector_annotation_tray->SetEnabled(success); - if (!success) { - projector_annotation_tray->OnCanvasInitializationFailed(); + should_enable_annotation_tray_button_ = success; + + if (auto* projector_annotation_tray = + GetProjectorAnnotationTrayForRoot(current_root_)) { + projector_annotation_tray->SetEnabled( + *should_enable_annotation_tray_button_); + if (!*should_enable_annotation_tray_button_) + projector_annotation_tray->OnCanvasInitializationFailed(); } } +void ProjectorUiController::OnRecordedWindowChangingRoot( + aura::Window* new_root) { + DCHECK_NE(new_root, current_root_); + + SetProjectorAnnotationTrayVisibility(current_root_, /*visible=*/false); + SetProjectorAnnotationTrayVisibility(new_root, /*visible=*/true); + current_root_ = new_root; + if (should_enable_annotation_tray_button_) + OnCanvasInitialized(*should_enable_annotation_tray_button_); +} + void ProjectorUiController::OnProjectorSessionActiveStateChanged(bool active) { if (!active) ResetTools();
diff --git a/ash/projector/projector_ui_controller.h b/ash/projector/projector_ui_controller.h index e1021f2..f40608f 100644 --- a/ash/projector/projector_ui_controller.h +++ b/ash/projector/projector_ui_controller.h
@@ -9,8 +9,13 @@ #include "ash/projector/projector_metrics.h" #include "ash/public/cpp/projector/projector_session.h" #include "base/scoped_observation.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkColor.h" +namespace aura { +class Window; +} // namespace aura + namespace ash { class ProjectorControllerImpl; @@ -32,8 +37,8 @@ ProjectorUiController& operator=(const ProjectorUiController&) = delete; ~ProjectorUiController() override; - // Show Projector toolbar. Virtual for testing. - virtual void ShowToolbar(); + // Show Projector toolbar for `current_root`. Virtual for testing. + virtual void ShowToolbar(aura::Window* current_root); // Close Projector toolbar. Virtual for testing. virtual void CloseToolbar(); // Invoked when marker button is pressed. Virtual for testing. @@ -45,6 +50,8 @@ // Invoked when the canvas has either succeeded or failed to initialize. void OnCanvasInitialized(bool success); + void OnRecordedWindowChangingRoot(aura::Window* new_root); + bool is_annotator_enabled() { return annotator_enabled_; } private: @@ -55,6 +62,11 @@ bool annotator_enabled_ = false; + // The current root window in which the video recording is happening. + aura::Window* current_root_ = nullptr; + + absl::optional<bool> should_enable_annotation_tray_button_; + base::ScopedObservation<ProjectorSession, ProjectorSessionObserver> projector_session_observation_{this}; };
diff --git a/ash/projector/projector_ui_controller_unittest.cc b/ash/projector/projector_ui_controller_unittest.cc index 8893cf04..8abd6e822 100644 --- a/ash/projector/projector_ui_controller_unittest.cc +++ b/ash/projector/projector_ui_controller_unittest.cc
@@ -89,7 +89,7 @@ auto* projector_annotation_tray = Shell::GetPrimaryRootWindowController() ->GetStatusAreaWidget() ->projector_annotation_tray(); - controller_->ShowToolbar(); + controller_->ShowToolbar(Shell::GetPrimaryRootWindow()); EXPECT_TRUE(projector_annotation_tray->visible_preferred()); controller_->CloseToolbar(); EXPECT_FALSE(projector_annotation_tray->visible_preferred()); @@ -101,7 +101,7 @@ auto* projector_annotation_tray = Shell::GetPrimaryRootWindowController() ->GetStatusAreaWidget() ->projector_annotation_tray(); - controller_->ShowToolbar(); + controller_->ShowToolbar(Shell::GetPrimaryRootWindow()); EXPECT_TRUE(projector_annotation_tray->visible_preferred()); controller_->OnMarkerPressed(); @@ -233,6 +233,7 @@ auto* projector_annotation_tray = Shell::GetPrimaryRootWindowController() ->GetStatusAreaWidget() ->projector_annotation_tray(); + controller_->ShowToolbar(Shell::GetPrimaryRootWindow()); EXPECT_FALSE(projector_annotation_tray->GetEnabled());
diff --git a/ash/projector/test/mock_projector_ui_controller.h b/ash/projector/test/mock_projector_ui_controller.h index ca81be7..7d10608 100644 --- a/ash/projector/test/mock_projector_ui_controller.h +++ b/ash/projector/test/mock_projector_ui_controller.h
@@ -27,7 +27,7 @@ ~MockProjectorUiController() override; // ProjectorUiController: - MOCK_METHOD0(ShowToolbar, void()); + MOCK_METHOD1(ShowToolbar, void(aura::Window*)); MOCK_METHOD0(CloseToolbar, void()); MOCK_METHOD0(OnMarkerPressed, void()); MOCK_METHOD1(SetAnnotatorTool, void(const AnnotatorTool&));
diff --git a/ash/system/power/adaptive_charging_nudge_controller_unittest.cc b/ash/system/power/adaptive_charging_nudge_controller_unittest.cc index 0976073..c5b0e73 100644 --- a/ash/system/power/adaptive_charging_nudge_controller_unittest.cc +++ b/ash/system/power/adaptive_charging_nudge_controller_unittest.cc
@@ -32,13 +32,13 @@ widget_observation_.Observe(widget); } - void WaitForClose() { + void WaitForDestruction() { run_loop_ = std::make_unique<base::RunLoop>(); run_loop_->Run(); } // views::WidgetObserver: - void OnWidgetClosing(views::Widget* widget) override { + void OnWidgetDestroying(views::Widget* widget) override { if (run_loop_) run_loop_->Quit(); } @@ -75,8 +75,8 @@ AdaptiveChargingNudgeController* GetController() { return controller_.get(); } - void WaitForWidgetClose(AdaptiveChargingNudgeController* controller, - SystemNudge* nudge) { + void WaitForWidgetDestruction(AdaptiveChargingNudgeController* controller, + SystemNudge* nudge) { views::Widget* nudge_widget = nudge->widget(); ASSERT_TRUE(nudge_widget); EXPECT_FALSE(nudge_widget->IsClosed()); @@ -86,12 +86,12 @@ ui::ScopedAnimationDurationScaleMode::SLOW_DURATION); // Pretend the hide nudge timer has elapsed. - NudgeWidgetObserver widget_close_observer(nudge_widget); + NudgeWidgetObserver widget_destruction_observer(nudge_widget); controller->FireHideNudgeTimerForTesting(); EXPECT_TRUE(nudge_widget->GetLayer()->GetAnimator()->is_animating()); - widget_close_observer.WaitForClose(); + widget_destruction_observer.WaitForDestruction(); } private: @@ -109,7 +109,7 @@ SystemNudge* nudge = controller->GetSystemNudgeForTesting(); ASSERT_TRUE(nudge); - WaitForWidgetClose(controller, nudge); + WaitForWidgetDestruction(controller, nudge); } TEST_F(AdaptiveChargingNudgeControllerTest, NoNudgeShowForDisabledFeature) { @@ -135,7 +135,7 @@ controller->GetNudgeDelayTimerForTesting()->FireNow(); SystemNudge* nudge1 = controller->GetSystemNudgeForTesting(); ASSERT_TRUE(nudge1); - WaitForWidgetClose(controller, nudge1); + WaitForWidgetDestruction(controller, nudge1); // No nudge for the second time. controller->ShowNudge();
diff --git a/ash/system/time/time_view.cc b/ash/system/time/time_view.cc index 56daefd8..bfbed6500 100644 --- a/ash/system/time/time_view.cc +++ b/ash/system/time/time_view.cc
@@ -58,7 +58,7 @@ // Padding between the left/right edge of the shelf and the left edge of the // vertical clock with date. -const int kVerticalDateClockHorizontalPadding = 4; +const int kVerticalDateClockHorizontalPadding = 8; // Padding on top/bottom of the vertical clock date view. const int kVerticalDateVerticalPadding = 2;
diff --git a/ash/system/toast/toast_manager_impl.cc b/ash/system/toast/toast_manager_impl.cc index eaa71ab..1b34568 100644 --- a/ash/system/toast/toast_manager_impl.cc +++ b/ash/system/toast/toast_manager_impl.cc
@@ -36,7 +36,7 @@ *existing_toast = data; existing_toast->time_created = old_time_created; } else { - if (current_toast_data_ && current_toast_data_->id == id) { + if (IsRunning(id)) { // Replace the visible toast by adding the new toast data to the front of // the queue and hiding the visible toast. Once the visible toast finishes // hiding, the new toast will be displayed. @@ -53,7 +53,7 @@ } void ToastManagerImpl::Cancel(const std::string& id) { - if (current_toast_data_ && current_toast_data_->id == id) { + if (IsRunning(id)) { overlay_->Show(false); return; } @@ -76,6 +76,10 @@ ShowLatest(); } +bool ToastManagerImpl::IsRunning(const std::string& id) const { + return overlay_ && current_toast_data_ && current_toast_data_->id == id; +} + void ToastManagerImpl::ShowLatest() { DCHECK(!overlay_); DCHECK(!current_toast_data_);
diff --git a/ash/system/toast/toast_manager_impl.h b/ash/system/toast/toast_manager_impl.h index e8bd2b5..a41dacc 100644 --- a/ash/system/toast/toast_manager_impl.h +++ b/ash/system/toast/toast_manager_impl.h
@@ -46,6 +46,9 @@ friend class AutoConnectNotifierTest; friend class DesksTestApi; + // Tells if the toast with the provided ID is running. + bool IsRunning(const std::string& id) const; + void ShowLatest(); void OnDurationPassed(int toast_number);
diff --git a/ash/webui/personalization_app/resources/PRESUBMIT.py b/ash/webui/personalization_app/resources/PRESUBMIT.py new file mode 100644 index 0000000..67fd32e --- /dev/null +++ b/ash/webui/personalization_app/resources/PRESUBMIT.py
@@ -0,0 +1,44 @@ +# Copyright 2022 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. +"""Presubmit script for Personalization app. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into depot_tools. +""" + +USE_PYTHON3 = True + +import sys + +# Use existing SemanticCssChecker to advise use of cros approved colors +# and semantic variables which support dark-mode display. +# See: ui/chromeos/styles/semantic_css_checker.py +def _CheckSemanticCssColors(input_api, output_api): + original_sys_path = sys.path + join = input_api.os_path.join + src_root = input_api.change.RepositoryRoot() + try: + # Change the system path to SemanticCssChecker's directory to be + # able to import it. + sys.path.append(join(src_root, 'ui', 'chromeos', 'styles')) + from semantic_css_checker import SemanticCssChecker + finally: + sys.path = original_sys_path + + return SemanticCssChecker.RunChecks(input_api, output_api) + + +def _CommonChecks(input_api, output_api): + """Checks common to both upload and commit.""" + results = [] + results.extend(_CheckSemanticCssColors(input_api, output_api)) + return results + + +def CheckChangeOnUpload(input_api, output_api): + return _CommonChecks(input_api, output_api) + + +def CheckChangeOnCommit(input_api, output_api): + return _CommonChecks(input_api, output_api)
diff --git a/ash/webui/personalization_app/resources/common/constants.ts b/ash/webui/personalization_app/resources/common/constants.ts index 8b0f3afd..b71a25d6 100644 --- a/ash/webui/personalization_app/resources/common/constants.ts +++ b/ash/webui/personalization_app/resources/common/constants.ts
@@ -21,7 +21,7 @@ export const trustedOrigin = 'chrome://personalization'; -export const kMaximumLocalImagePreviews = 3; +export const kMaximumLocalImagePreviews = 4; export enum EventType { SEND_COLLECTIONS = 'send_collections',
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html index 4f0d4056..f1ae773 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html
@@ -159,14 +159,15 @@ width: 100%; } + #albumTitleTooltip::part(tooltip) { + align-items: flex-end; + display: flex; + flex-direction: row; + height: 18px; + padding: 3px 8px; + } + #albumTitleTooltip { - --paper-tooltip: { - align-items: flex-end; - display: flex; - flex-direction: row; - height: 18px; - padding: 3px 8px; - }; --paper-tooltip-background: var(--cros-tooltip-background-color); --paper-tooltip-opacity: 0.8; --paper-tooltip-text-color: var(--cros-tooltip-label-color);
diff --git a/ash/webui/personalization_app/resources/untrusted/collections_grid.html b/ash/webui/personalization_app/resources/untrusted/collections_grid.html index c2f5bed0..5e26557 100644 --- a/ash/webui/personalization_app/resources/untrusted/collections_grid.html +++ b/ash/webui/personalization_app/resources/untrusted/collections_grid.html
@@ -48,7 +48,8 @@ padding: 4px; } - .photo-images-container.photo-images-container-3 img { + .photo-images-container.photo-images-container-3 img, + .photo-images-container.photo-images-container-4 img { height: 50%; }
diff --git a/ash/wm/desks/desk_mini_view.cc b/ash/wm/desks/desk_mini_view.cc index 4d3ad79..4f8e380 100644 --- a/ash/wm/desks/desk_mini_view.cc +++ b/ash/wm/desks/desk_mini_view.cc
@@ -328,14 +328,25 @@ : IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP)); } - if (DesksController::Get()->CanRemoveDesks()) { - // TODO(sammiequon): Update this once we get strings from UX writing since - // close all supports Ctrl+Shift+W. - node_data->AddStringAttribute( - ax::mojom::StringAttribute::kDescription, - l10n_util::GetStringUTF8( - IDS_ASH_OVERVIEW_CLOSABLE_HIGHLIGHT_ITEM_A11Y_EXTRA_TIP)); + // If the desk can be combined or closed, add a tip to let the user know they + // can use an accelerator. + if (!DesksController::Get()->CanRemoveDesks()) + return; + + std::string extra_tip; + if (features::IsDesksCloseAllEnabled()) { + const std::u16string target_desk_name = + DesksController::Get()->GetCombineDesksTargetName(desk_); + extra_tip = l10n_util::GetStringFUTF8( + IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP, + target_desk_name); + } else { + extra_tip = l10n_util::GetStringUTF8( + IDS_ASH_OVERVIEW_CLOSABLE_HIGHLIGHT_ITEM_A11Y_EXTRA_TIP); } + + node_data->AddStringAttribute(ax::mojom::StringAttribute::kDescription, + extra_tip); } void DeskMiniView::OnThemeChanged() {
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc index f5451e39..08ccaf2 100644 --- a/ash/wm/desks/desks_controller.cc +++ b/ash/wm/desks/desks_controller.cc
@@ -76,7 +76,8 @@ namespace { -constexpr char kCloseAllToastID[] = "UndoCloseAllToast"; +// Used to initialize toasts to undo desk removal with different IDs. +unsigned int g_close_desk_toast_counter = 0; constexpr char kNewDeskHistogramName[] = "Ash.Desks.NewDesk2"; constexpr char kDesksCountHistogramName[] = "Ash.Desks.DesksCount3"; @@ -207,10 +208,11 @@ return active_window == app_list_controller->GetWindow(); } -void ShowDeskRemovalUndoToast(base::RepeatingClosure dismiss_callback, +void ShowDeskRemovalUndoToast(const std::string& toast_id, + base::RepeatingClosure dismiss_callback, base::RepeatingClosure expired_callback) { ToastData undo_toast_data( - kCloseAllToastID, ash::ToastCatalogName::kUndoCloseAll, + toast_id, ash::ToastCatalogName::kUndoCloseAll, l10n_util::GetStringUTF16(IDS_ASH_DESKS_CLOSE_ALL_TOAST_TEXT), ToastData::kDefaultToastDuration, /*visible_on_lock_screen=*/false, @@ -228,7 +230,11 @@ class DesksController::RemovedDeskData { public: RemovedDeskData(std::unique_ptr<Desk> desk, int index) - : was_active_(desk->is_active()), desk_(std::move(desk)), index_(index) { + : toast_id_(base::StringPrintf("UndoCloseAllToast_%d", + ++g_close_desk_toast_counter)), + was_active_(desk->is_active()), + desk_(std::move(desk)), + index_(index) { desk_->set_is_desk_being_removed(true); } @@ -236,16 +242,20 @@ RemovedDeskData& operator=(const RemovedDeskData&) = delete; ~RemovedDeskData() { - if (desk_) + if (desk_) { + ToastManager::Get()->Cancel(toast_id_); DesksController::Get()->FinalizeDeskRemoval(this); + } } + const std::string& toast_id() const { return toast_id_; } bool was_active() const { return was_active_; } Desk* desk() { return desk_.get(); } int index() const { return index_; } std::unique_ptr<Desk> AcquireDesk() { return std::move(desk_); } private: + const std::string toast_id_; const bool was_active_; std::unique_ptr<Desk> desk_; const int index_; @@ -458,9 +468,10 @@ base::AutoReset<bool> in_progress(&are_desks_being_modified_, true); - // Cancelling the close-all toast closes the toast and also runs the callback - // that deletes any existing data in `temporary_removed_desk_`. - ToastManager::Get()->Cancel(kCloseAllToastID); + // We do not want this function to run here when there is no + // `temporary_removed_desk_` because that will incorrectly record metrics. + if (temporary_removed_desk_) + MaybeCommitPendingDeskRemoval(); // The first default desk should not overwrite any desks restore data, nor // should it trigger any UMA stats reports. @@ -1356,9 +1367,10 @@ void DesksController::RemoveDeskInternal(const Desk* desk, DesksCreationRemovalSource source, DeskCloseType close_type) { - // Cancelling the close-all toast closes the toast and also runs the callback - // that deletes any existing data in `temporary_removed_desk_`. - ToastManager::Get()->Cancel(kCloseAllToastID); + // We do not want this function to run here when there is no + // `temporary_removed_desk_` because that will incorrectly record metrics. + if (temporary_removed_desk_) + MaybeCommitPendingDeskRemoval(); DCHECK(CanRemoveDesks()); @@ -1382,7 +1394,7 @@ } } - // Keep the removed desk alive until at least the end of this function. + // Keep the removed desk's data alive until at least the end of this function. auto temporary_removed_desk = std::make_unique<RemovedDeskData>(std::move(*iter), removed_desk_index); auto* temporary_removed_desk_ptr = temporary_removed_desk.get(); @@ -1534,11 +1546,14 @@ if (close_type == DeskCloseType::kCloseAllWindowsAndWait) { ShowDeskRemovalUndoToast( - /*dismiss_callback=*/base::BindRepeating( - &DesksController::UndoDeskRemoval, base::Unretained(this)), - /*expired_callback=*/base::BindRepeating( - &DesksController::CommitPendingDeskRemoval, - base::Unretained(this))); + temporary_removed_desk_->toast_id(), + /*dismiss_callback=*/ + base::BindRepeating(&DesksController::UndoDeskRemoval, + base::Unretained(this)), + /*expired_callback=*/ + base::BindRepeating(&DesksController::MaybeCommitPendingDeskRemoval, + base::Unretained(this), + temporary_removed_desk_->toast_id())); } } @@ -1583,6 +1598,7 @@ non_const_desk->RecordLifetimeHistogram(removed_desk_data->index()); non_const_desk->RecordAndResetConsecutiveDailyVisits( /*being_removed=*/true); + // Record number of windows being closed by desk removal. UMA_HISTOGRAM_COUNTS_100(kNumberOfWindowsClosed, removed_desk->windows().size()); @@ -1630,14 +1646,19 @@ std::move(closing_window_tracker)), kCloseAllWindowCloseTimeout); - // Remove the desk. - temporary_removed_desk_.reset(); + // `temporary_removed_desk_` should not be set at this point. + DCHECK(!temporary_removed_desk_); } -void DesksController::CommitPendingDeskRemoval() { +void DesksController::MaybeCommitPendingDeskRemoval( + const std::string& toast_id) { // This method will be invoked on both undo and expired toast. base::UmaHistogramBoolean(kCloseAllUndoAndExpiredHistogramName, true); - temporary_removed_desk_.reset(); + + if (toast_id.empty() || (temporary_removed_desk_ && + temporary_removed_desk_->toast_id() == toast_id)) { + temporary_removed_desk_.reset(); + } } void DesksController::CleanUpClosedAppWindowsTask(
diff --git a/ash/wm/desks/desks_controller.h b/ash/wm/desks/desks_controller.h index 6f379356..97c4fe3 100644 --- a/ash/wm/desks/desks_controller.h +++ b/ash/wm/desks/desks_controller.h
@@ -381,7 +381,10 @@ // this function in the combine desks process. void FinalizeDeskRemoval(RemovedDeskData* removed_desk_data); - void CommitPendingDeskRemoval(); + // Saves metrics and resets `temporary_removed_desk_` if `toast_id` is empty + // or it matches the toast ID stored in `temporary_removed_desk_`. + void MaybeCommitPendingDeskRemoval( + const std::string& toast_id = std::string()); // Forcefully cleans up app windows that should be closed. void CleanUpClosedAppWindowsTask(
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index 64e80d6..e04faed 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -7112,6 +7112,16 @@ ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); } + void ClickOnUndoDeskRemovalButton() { + views::LabelButton* dismiss_button = + DesksTestApi::GetCloseAllUndoToastDismissButton(); + const gfx::Point button_center = + dismiss_button->GetBoundsInScreen().CenterPoint(); + auto* event_generator = GetEventGenerator(); + event_generator->MoveMouseTo(button_center); + event_generator->ClickLeftButton(); + } + // DesksTest: void SetUp() override { scoped_feature_list_.InitAndEnableFeature(features::kDesksCloseAll); @@ -7372,13 +7382,7 @@ if (test_case.restore_desk) { // When `desk_1` is restored it should be back in its original position // and should be active again. - views::LabelButton* dismiss_button = - DesksTestApi::GetCloseAllUndoToastDismissButton(); - const gfx::Point button_center = - dismiss_button->GetBoundsInScreen().CenterPoint(); - auto* event_generator = GetEventGenerator(); - event_generator->MoveMouseTo(button_center); - event_generator->ClickLeftButton(); + ClickOnUndoDeskRemovalButton(); EXPECT_FALSE(desk_1->is_desk_being_removed()); EXPECT_EQ(2u, controller->desks().size()); EXPECT_TRUE(desk_1->is_active()); @@ -7794,6 +7798,25 @@ EXPECT_TRUE(DesksTestApi::IsContextMenuRunningForDesk(0)); } +// Tests that desks can be closed in quick succession while still saving the +// removed desk. +TEST_F(DesksCloseAllTest, CanCloseMultipleDesksInSuccessionAndUndo) { + NewDesk(); + NewDesk(); + auto* controller = DesksController::Get(); + ASSERT_EQ(3u, controller->desks().size()); + + EnterOverview(); + ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); + + ClickOnCloseAllButtonForDesk(0); + ASSERT_TRUE(DesksTestApi::DesksControllerCanUndoDeskRemoval()); + ClickOnCloseAllButtonForDesk(0); + ASSERT_TRUE(DesksTestApi::DesksControllerCanUndoDeskRemoval()); + ClickOnUndoDeskRemovalButton(); + EXPECT_EQ(2u, controller->desks().size()); +} + // TODO(afakhry): Add more tests: // - Always on top windows are not tracked by any desk. // - Reusing containers when desks are removed and created.
diff --git a/ash/wm/desks/templates/saved_desk_item_view.cc b/ash/wm/desks/templates/saved_desk_item_view.cc index 7293a251..f53d3ca 100644 --- a/ash/wm/desks/templates/saved_desk_item_view.cc +++ b/ash/wm/desks/templates/saved_desk_item_view.cc
@@ -335,15 +335,8 @@ } void SavedDeskItemView::Layout() { - const int previous_name_view_width = name_view_->width(); - views::View::Layout(); - // A change in the `name_view_`'s width might mean the need to elide the text - // differently. - if (previous_name_view_width != name_view_->width()) - OnTemplateNameChanged(desk_template_->template_name()); - if (delete_button_) { const gfx::Size delete_button_size = delete_button_->GetPreferredSize(); DCHECK_EQ(delete_button_size.width(), delete_button_size.height());
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h index 7bb6be1..d021c0a 100644 --- a/base/allocator/partition_allocator/partition_page.h +++ b/base/allocator/partition_allocator/partition_page.h
@@ -117,8 +117,9 @@ // booted out of the active list. If there are no suitable active slot spans // found, an empty or decommitted slot spans (if one exists) will be pulled // from the empty/decommitted list on to the active list. +#pragma pack(push, 1) template <bool thread_safe> -struct __attribute__((packed)) SlotSpanMetadata { +struct SlotSpanMetadata { private: PartitionFreelistEntry* freelist_head = nullptr; @@ -302,6 +303,7 @@ empty_cache_index_(0), unused2_(0) {} }; +#pragma pack(pop) static_assert(sizeof(SlotSpanMetadata<ThreadSafe>) <= kPageMetadataSize, "SlotSpanMetadata must fit into a Page Metadata slot."); @@ -324,11 +326,12 @@ // first page of a slot span, describes that slot span. If a slot span spans // more than 1 page, the page metadata may contain rudimentary additional // information. +// "Pack" the union so that common page metadata still fits within +// kPageMetadataSize. (SlotSpanMetadata is also "packed".) +#pragma pack(push, 1) template <bool thread_safe> -struct __attribute__((packed)) PartitionPage { - // "Pack" the union so that common page metadata still fits within - // kPageMetadataSize. (SlotSpanMetadata is also "packed".) - union __attribute__((packed)) { +struct PartitionPage { + union { SlotSpanMetadata<thread_safe> slot_span_metadata; SubsequentPageMetadata subsequent_page_metadata; @@ -366,7 +369,7 @@ ALWAYS_INLINE static PartitionPage* FromAddr(uintptr_t address); }; - +#pragma pack(pop) static_assert(sizeof(PartitionPage<ThreadSafe>) == kPageMetadataSize, "PartitionPage must be able to fit in a metadata slot");
diff --git a/base/allocator/partition_allocator/thread_cache.h b/base/allocator/partition_allocator/thread_cache.h index 3c388aa..a13c32b 100644 --- a/base/allocator/partition_allocator/thread_cache.h +++ b/base/allocator/partition_allocator/thread_cache.h
@@ -509,12 +509,13 @@ } PA_DCHECK(bucket.count != 0); - auto* result = bucket.freelist_head; + internal::PartitionFreelistEntry* result = bucket.freelist_head; // Passes the bucket size to |GetNext()|, so that in case of freelist // corruption, we know the bucket size that lead to the crash, helping to // narrow down the search for culprit. |bucket| was touched just now, so this // does not introduce another cache miss. - auto* next = result->GetNextForThreadCache<true>(bucket.slot_size); + internal::PartitionFreelistEntry* next = + result->GetNextForThreadCache<true>(bucket.slot_size); PA_DCHECK(result != next); bucket.count--; PA_DCHECK(bucket.count != 0 || !next);
diff --git a/base/bits.h b/base/bits.h index f71bc3f..c22a8cd 100644 --- a/base/bits.h +++ b/base/bits.h
@@ -25,6 +25,8 @@ namespace bits { // Returns true iff |value| is a power of 2. +// +// TODO(pkasting): When C++20 is available, replace with std::has_single_bit(). template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>> constexpr bool IsPowerOfTwo(T value) { // From "Hacker's Delight": Section 2.1 Manipulating Rightmost Bits. @@ -79,6 +81,9 @@ // // Prefer the clang path on Windows, as _BitScanReverse() and friends are not // constexpr. +// +// TODO(pkasting): When C++20 is available, replace with std::countl_zero() and +// similar. #if defined(COMPILER_MSVC) && !defined(__clang__) template <typename T, unsigned bits = sizeof(T) * 8> @@ -153,13 +158,9 @@ #endif } -ALWAYS_INLINE uint32_t CountLeadingZeroBits32(uint32_t x) { - return CountLeadingZeroBits(x); -} - -ALWAYS_INLINE uint64_t CountLeadingZeroBits64(uint64_t x) { - return CountLeadingZeroBits(x); -} +// Used in place of "constexpr" below for things which are conditionally +// constexpr depending on whether the functions above are constexpr. +#define BASE_BITOPS_CONSTEXPR #elif defined(COMPILER_GCC) || defined(__clang__) @@ -191,29 +192,38 @@ : bits; } -ALWAYS_INLINE constexpr uint32_t CountLeadingZeroBits32(uint32_t x) { - return CountLeadingZeroBits(x); -} - -ALWAYS_INLINE constexpr uint64_t CountLeadingZeroBits64(uint64_t x) { - return CountLeadingZeroBits(x); -} +#define BASE_BITOPS_CONSTEXPR constexpr #endif -ALWAYS_INLINE constexpr size_t CountLeadingZeroBitsSizeT(size_t x) { +ALWAYS_INLINE BASE_BITOPS_CONSTEXPR uint32_t +CountLeadingZeroBits32(uint32_t x) { return CountLeadingZeroBits(x); } -ALWAYS_INLINE constexpr size_t CountTrailingZeroBitsSizeT(size_t x) { +ALWAYS_INLINE BASE_BITOPS_CONSTEXPR uint64_t +CountLeadingZeroBits64(uint64_t x) { + return CountLeadingZeroBits(x); +} + +ALWAYS_INLINE BASE_BITOPS_CONSTEXPR size_t CountLeadingZeroBitsSizeT(size_t x) { + return CountLeadingZeroBits(x); +} + +ALWAYS_INLINE BASE_BITOPS_CONSTEXPR size_t +CountTrailingZeroBitsSizeT(size_t x) { return CountTrailingZeroBits(x); } +#undef BASE_BITOPS_CONSTEXPR + // Returns the integer i such as 2^i <= n < 2^(i+1). // // There is a common `BitLength` function, which returns the number of bits // required to represent a value. Rather than implement that function, // use `Log2Floor` and add 1 to the result. +// +// TODO(pkasting): When C++20 is available, replace with std::bit_xxx(). constexpr int Log2Floor(uint32_t n) { return 31 - CountLeadingZeroBits(n); }
diff --git a/base/compiler_specific.h b/base/compiler_specific.h index 1ee8074..bb43ab3 100644 --- a/base/compiler_specific.h +++ b/base/compiler_specific.h
@@ -24,6 +24,13 @@ #define HAS_CPP_ATTRIBUTE(x) 0 #endif +// A wrapper around `__has_attribute`, similar to HAS_CPP_ATTRIBUTE. +#if defined(__has_attribute) +#define HAS_ATTRIBUTE(x) __has_attribute(x) +#else +#define HAS_ATTRIBUTE(x) 0 +#endif + // A wrapper around `__has_builtin`, similar to HAS_CPP_ATTRIBUTE. #if defined(__has_builtin) #define HAS_BUILTIN(x) __has_builtin(x) @@ -58,7 +65,7 @@ // prevent code folding, see NO_CODE_FOLDING() in base/debug/alias.h. // Use like: // void NOT_TAIL_CALLED FooBar(); -#if defined(__clang__) && __has_attribute(not_tail_called) +#if defined(__clang__) && HAS_ATTRIBUTE(not_tail_called) #define NOT_TAIL_CALLED __attribute__((not_tail_called)) #else #define NOT_TAIL_CALLED @@ -126,11 +133,9 @@ // __attribute__((format(wprintf, format_param, dots_param))) // Sanitizers annotations. -#if defined(__has_attribute) -#if __has_attribute(no_sanitize) +#if HAS_ATTRIBUTE(no_sanitize) #define NO_SANITIZE(what) __attribute__((no_sanitize(what))) #endif -#endif #if !defined(NO_SANITIZE) #define NO_SANITIZE(what) #endif @@ -238,7 +243,7 @@ #endif #endif -#if defined(__clang__) && __has_attribute(uninitialized) +#if defined(__clang__) && HAS_ATTRIBUTE(uninitialized) // Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for // the specified variable. // Library-wide alternative is @@ -285,13 +290,9 @@ // In some cases it's desirable to remove this, e.g. on hot functions, or if // we have purposely changed the reference canary. #if defined(COMPILER_GCC) || defined(__clang__) -#if defined(__has_attribute) -#if __has_attribute(__no_stack_protector__) +#if HAS_ATTRIBUTE(__no_stack_protector__) #define NO_STACK_PROTECTOR __attribute__((__no_stack_protector__)) -#else // __has_attribute(__no_stack_protector__) -#define NO_STACK_PROTECTOR __attribute__((__optimize__("-fno-stack-protector"))) -#endif -#else // defined(__has_attribute) +#else #define NO_STACK_PROTECTOR __attribute__((__optimize__("-fno-stack-protector"))) #endif #else @@ -328,7 +329,7 @@ #endif // defined(__clang_analyzer__) // Use nomerge attribute to disable optimization of merging multiple same calls. -#if defined(__clang__) && __has_attribute(nomerge) +#if defined(__clang__) && HAS_ATTRIBUTE(nomerge) #define NOMERGE [[clang::nomerge]] #else #define NOMERGE @@ -355,7 +356,7 @@ // See also: // https://clang.llvm.org/docs/AttributeReference.html#trivial-abi // https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html -#if defined(__clang__) && __has_attribute(trivial_abi) +#if defined(__clang__) && HAS_ATTRIBUTE(trivial_abi) #define TRIVIAL_ABI [[clang::trivial_abi]] #else #define TRIVIAL_ABI @@ -364,7 +365,7 @@ // Marks a member function as reinitializing a moved-from variable. // See also // https://clang.llvm.org/extra/clang-tidy/checks/bugprone-use-after-move.html#reinitialization -#if defined(__clang__) && __has_attribute(reinitializes) +#if defined(__clang__) && HAS_ATTRIBUTE(reinitializes) #define REINITIALIZES_AFTER_MOVE [[clang::reinitializes]] #else #define REINITIALIZES_AFTER_MOVE @@ -373,11 +374,9 @@ // Requires constant initialization. See constinit in C++20. Allows to rely on a // variable being initialized before execution, and not requiring a global // constructor. -#if defined(__has_attribute) -#if __has_attribute(require_constant_initialization) +#if HAS_ATTRIBUTE(require_constant_initialization) #define CONSTINIT __attribute__((require_constant_initialization)) #endif -#endif #if !defined(CONSTINIT) #define CONSTINIT #endif
diff --git a/base/sys_byteorder.h b/base/sys_byteorder.h index 5516be7..df3b1e5 100644 --- a/base/sys_byteorder.h +++ b/base/sys_byteorder.h
@@ -19,10 +19,20 @@ #include <stdlib.h> #endif +#if defined(COMPILER_MSVC) && !defined(__clang__) +// TODO(pkasting): See +// https://developercommunity.visualstudio.com/t/Mark-some-built-in-functions-as-constexp/362558 +// https://developercommunity.visualstudio.com/t/constexpr-byte-swapping-optimization/983963 +#define BASE_BYTESWAPS_CONSTEXPR +#else +#define BASE_BYTESWAPS_CONSTEXPR constexpr +#endif + namespace base { // Returns a value with all bytes in |x| swapped, i.e. reverses the endianness. -inline uint16_t ByteSwap(uint16_t x) { +// TODO(pkasting): Once C++23 is available, replace with std::byteswap. +inline BASE_BYTESWAPS_CONSTEXPR uint16_t ByteSwap(uint16_t x) { #if defined(COMPILER_MSVC) && !defined(__clang__) return _byteswap_ushort(x); #else @@ -30,7 +40,7 @@ #endif } -inline constexpr uint32_t ByteSwap(uint32_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint32_t ByteSwap(uint32_t x) { #if defined(COMPILER_MSVC) && !defined(__clang__) return _byteswap_ulong(x); #else @@ -38,7 +48,7 @@ #endif } -inline constexpr uint64_t ByteSwap(uint64_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint64_t ByteSwap(uint64_t x) { // Per build/build_config.h, clang masquerades as MSVC on Windows. If we are // actually using clang, we can rely on the builtin. // @@ -53,7 +63,7 @@ #endif } -inline constexpr uintptr_t ByteSwapUintPtrT(uintptr_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uintptr_t ByteSwapUintPtrT(uintptr_t x) { // We do it this way because some build configurations are ILP32 even when // defined(ARCH_CPU_64_BITS). Unfortunately, we can't use sizeof in #ifs. But, // because these conditionals are constexprs, the irrelevant branches will @@ -68,21 +78,21 @@ // Converts the bytes in |x| from host order (endianness) to little endian, and // returns the result. -inline uint16_t ByteSwapToLE16(uint16_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint16_t ByteSwapToLE16(uint16_t x) { #if defined(ARCH_CPU_LITTLE_ENDIAN) return x; #else return ByteSwap(x); #endif } -inline uint32_t ByteSwapToLE32(uint32_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint32_t ByteSwapToLE32(uint32_t x) { #if defined(ARCH_CPU_LITTLE_ENDIAN) return x; #else return ByteSwap(x); #endif } -inline uint64_t ByteSwapToLE64(uint64_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint64_t ByteSwapToLE64(uint64_t x) { #if defined(ARCH_CPU_LITTLE_ENDIAN) return x; #else @@ -92,21 +102,21 @@ // Converts the bytes in |x| from network to host order (endianness), and // returns the result. -inline uint16_t NetToHost16(uint16_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint16_t NetToHost16(uint16_t x) { #if defined(ARCH_CPU_LITTLE_ENDIAN) return ByteSwap(x); #else return x; #endif } -inline uint32_t NetToHost32(uint32_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint32_t NetToHost32(uint32_t x) { #if defined(ARCH_CPU_LITTLE_ENDIAN) return ByteSwap(x); #else return x; #endif } -inline uint64_t NetToHost64(uint64_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint64_t NetToHost64(uint64_t x) { #if defined(ARCH_CPU_LITTLE_ENDIAN) return ByteSwap(x); #else @@ -116,21 +126,21 @@ // Converts the bytes in |x| from host to network order (endianness), and // returns the result. -inline uint16_t HostToNet16(uint16_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint16_t HostToNet16(uint16_t x) { #if defined(ARCH_CPU_LITTLE_ENDIAN) return ByteSwap(x); #else return x; #endif } -inline uint32_t HostToNet32(uint32_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint32_t HostToNet32(uint32_t x) { #if defined(ARCH_CPU_LITTLE_ENDIAN) return ByteSwap(x); #else return x; #endif } -inline uint64_t HostToNet64(uint64_t x) { +inline BASE_BYTESWAPS_CONSTEXPR uint64_t HostToNet64(uint64_t x) { #if defined(ARCH_CPU_LITTLE_ENDIAN) return ByteSwap(x); #else @@ -140,4 +150,6 @@ } // namespace base +#undef BASE_BYTESWAPS_CONSTEXPR + #endif // BASE_SYS_BYTEORDER_H_
diff --git a/base/time/time_win.cc b/base/time/time_win.cc index 54bb918..eabcc10 100644 --- a/base/time/time_win.cc +++ b/base/time/time_win.cc
@@ -40,7 +40,6 @@ #include <atomic> -#include "base/atomicops.h" #include "base/bit_cast.h" #include "base/check_op.h" #include "base/cpu.h" @@ -407,7 +406,7 @@ // "rollover" counter. union LastTimeAndRolloversState { // The state as a single 32-bit opaque value. - subtle::Atomic32 as_opaque_32; + std::atomic<int32_t> as_opaque_32; // The state as usable values. struct { @@ -423,7 +422,7 @@ uint16_t rollovers; } as_values; }; -subtle::Atomic32 g_last_time_and_rollovers = 0; +std::atomic<int32_t> g_last_time_and_rollovers = 0; static_assert( sizeof(LastTimeAndRolloversState) <= sizeof(g_last_time_and_rollovers), "LastTimeAndRolloversState does not fit in a single atomic word"); @@ -442,7 +441,8 @@ // incrementing the "rollovers" counter if the tick-value has wrapped back // around. Atomic operations ensure that both "last" and "rollovers" are // always updated together. - int32_t original = subtle::Acquire_Load(&g_last_time_and_rollovers); + int32_t original = + g_last_time_and_rollovers.load(std::memory_order_acquire); state.as_opaque_32 = original; now = g_tick_function(); uint8_t now_8 = static_cast<uint8_t>(now >> 24); @@ -456,8 +456,8 @@ // Save the changed state. If the existing value is unchanged from the // original, exit the loop. - int32_t check = subtle::Release_CompareAndSwap( - &g_last_time_and_rollovers, original, state.as_opaque_32); + int32_t check = g_last_time_and_rollovers.compare_exchange_strong( + original, state.as_opaque_32, std::memory_order_release); if (check == original) break; @@ -596,7 +596,7 @@ TickFunctionType ticker) { TickFunctionType old = g_tick_function; g_tick_function = ticker; - subtle::NoBarrier_Store(&g_last_time_and_rollovers, 0); + g_last_time_and_rollovers.store(0, std::memory_order_relaxed); return old; }
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc index dd6aa98..dafeb24 100644 --- a/base/win/windows_version.cc +++ b/base/win/windows_version.cc
@@ -26,7 +26,7 @@ #endif #if !defined(NTDDI_WIN10_FE) -#error Windows 10.0.20348.0SDK or higher required. +#error Windows 10.0.20348.0 SDK or higher required. #endif namespace base {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index a94199a..7cc19e7 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -418,6 +418,7 @@ "//chrome/browser/safety_check/android:java", "//chrome/browser/search_engines/android:java", "//chrome/browser/segmentation_platform:factory_java", + "//chrome/browser/selection/android:java", "//chrome/browser/settings:java", "//chrome/browser/share:java", "//chrome/browser/share/android:java_resources",
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java index 660baf4e..70e34fd 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java
@@ -29,6 +29,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.toolbar.top.Toolbar; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.xsurface.FeedLaunchReliabilityLogger.SurfaceType; @@ -64,7 +65,8 @@ @NewTabPageLaunchOrigin int launchOrigin, @NonNull Supplier<Toolbar> toolbarSupplier, long embeddingSurfaceConstructedTimeNs, FeedSwipeRefreshLayout swipeRefreshLayout, ViewGroup parentView, Supplier<Tab> parentTabSupplier, SnackbarManager snackbarManager, - Supplier<ShareDelegate> shareDelegateSupplier, WindowAndroid windowAndroid) { + Supplier<ShareDelegate> shareDelegateSupplier, WindowAndroid windowAndroid, + TabModelSelector tabModelSelector) { mActivity = activity; mExploreSurfaceNavigationDelegate = new ExploreSurfaceNavigationDelegate(parentTabSupplier); mIsPlaceholderShownInitially = isPlaceholderShown; @@ -79,7 +81,7 @@ SurfaceType.START_SURFACE, embeddingSurfaceConstructedTimeNs, swipeRefreshLayout, /*overScrollDisabled=*/true, parentView, new ExploreSurfaceActionDelegate(snackbarManager, new BookmarkBridge(profile)), - HelpAndFeedbackLauncherImpl.getInstance()); + HelpAndFeedbackLauncherImpl.getInstance(), tabModelSelector); mFeedSurfaceCoordinator.getView().setId(R.id.start_surface_explore_view); // TODO(crbug.com/982018): Customize surface background for incognito and dark mode.
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinatorFactory.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinatorFactory.java index 9f97ff2dd6..2645e1ba 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinatorFactory.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinatorFactory.java
@@ -99,6 +99,6 @@ mBottomSheetController, mScrollableContainerDelegate, launchOrigin, mToolbarSupplier, mEmbeddingSurfaceConstructedTimeNs, mSwipeRefreshLayout, mParentView, mParentTabSupplier, mSnackbarManager, mShareDelegateSupplier, - mWindowAndroid); + mWindowAndroid, mTabModelSelector); } }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java index a8e49a5..6559e28 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -49,6 +49,10 @@ import org.chromium.chrome.browser.settings.SettingsLauncherImpl; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabSelectionType; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.toolbar.top.Toolbar; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.ui.native_page.TouchEnabledDelegate; @@ -237,7 +241,7 @@ * purposes, or |null| if the view returned by HybridListRenderer is to be used. * @param actionDelegate Implements some Feed actions. * @param helpAndFeedbackLauncher A HelpAndFeedbackLauncher. - * @param feedHooks A @{link FeedHooks} instance. + * @param tabModelSelector TabModelSelector used to get TabModels we can observe. */ public FeedSurfaceCoordinator(Activity activity, SnackbarManager snackbarManager, WindowAndroid windowAndroid, @Nullable SnapScrollHelper snapScrollHelper, @@ -251,7 +255,8 @@ @NonNull Supplier<Toolbar> toolbarSupplier, @SurfaceType int surfaceType, long embeddingSurfaceCreatedTimeNs, @Nullable FeedSwipeRefreshLayout swipeRefreshLayout, boolean overScrollDisabled, @Nullable ViewGroup viewportView, - FeedActionDelegate actionDelegate, HelpAndFeedbackLauncher helpAndFeedbackLauncher) { + FeedActionDelegate actionDelegate, HelpAndFeedbackLauncher helpAndFeedbackLauncher, + TabModelSelector tabModelSelector) { mActivity = activity; mSnackbarManager = snackbarManager; mNtpHeader = ntpHeader; @@ -273,6 +278,19 @@ mSurfaceType = surfaceType; mEmbeddingSurfaceCreatedTimeNs = embeddingSurfaceCreatedTimeNs; + TabModelObserver tabModelObserver = new TabModelObserver() { + @Override + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { + if (mReliabilityLogger != null) { + mReliabilityLogger.onSwitchTabs(); + } + } + }; + tabModelSelector.getModel(/*incognito=*/false).addObserver(tabModelObserver); + // The feed isn't shown in incognito tabs, but we add the observer to record when the user + // switches to an incognito tab from the feed. + tabModelSelector.getModel(/*incognito=*/true).addObserver(tabModelObserver); + Resources resources = mActivity.getResources(); mRootView = new RootView(mActivity);
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpFeedSurfaceLifecycleManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpFeedSurfaceLifecycleManager.java index f1bcc4735..20f60095 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpFeedSurfaceLifecycleManager.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpFeedSurfaceLifecycleManager.java
@@ -77,6 +77,10 @@ @Override public void onPageLoadStarted(Tab tab, GURL url) { saveInstanceState(); + FeedReliabilityLogger logger = coordinator.getReliabilityLogger(); + if (logger != null) { + logger.onPageLoadStarted(); + } } }; mTab.addObserver(mTabObserver);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index b190c17..73b62a0e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -148,6 +148,7 @@ import org.chromium.chrome.browser.printing.TabPrinter; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.read_later.ReadingListUtils; +import org.chromium.chrome.browser.selection.SelectionPopupBackPressHandler; import org.chromium.chrome.browser.settings.SettingsLauncherImpl; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.share.ShareDelegateImpl; @@ -399,6 +400,8 @@ protected BackPressManager mBackPressManager = new BackPressManager(); private TextBubbleBackPressHandler mTextBubbleBackPressHandler; + private SelectionPopupBackPressHandler mSelectionPopupBackPressHandler; + private Callback<TabModelSelector> mSelectionPopupBackPressInitCallback; protected ChromeActivity() { mIntentHandler = new IntentHandler(this, createIntentHandlerDelegate()); @@ -1593,6 +1596,11 @@ mTextBubbleBackPressHandler = null; } + if (mSelectionPopupBackPressHandler != null) { + mSelectionPopupBackPressHandler.destroy(); + mSelectionPopupBackPressHandler = null; + } + mActivityTabProvider.destroy(); ChromeActivitySessionTracker.getInstance().unregisterTabModelSelectorSupplier(this); @@ -2323,12 +2331,12 @@ mCompositorViewHolderSupplier.get().getLayoutManager(); if (layoutManager != null && layoutManager.onBackPressed()) return; } - } - SelectionPopupController controller = getSelectionPopupController(); - if (controller != null && controller.isSelectActionBarShowing()) { - controller.clearSelection(); - return; + SelectionPopupController controller = getSelectionPopupController(); + if (controller != null && controller.isSelectActionBarShowing()) { + controller.clearSelection(); + return; + } } if (!BackPressManager.isEnabled()) { @@ -2368,6 +2376,16 @@ mBackPressManager.addHandler(layoutManager, Type.LAYOUT_MANAGER); }); + mSelectionPopupBackPressInitCallback = (tabModelSelector) -> { + assert !mBackPressManager.has(Type.SELECTION_POPUP) + : "Tab Model Selector should be set at most once"; + mSelectionPopupBackPressHandler = + new SelectionPopupBackPressHandler(tabModelSelector); + mBackPressManager.addHandler(mSelectionPopupBackPressHandler, Type.SELECTION_POPUP); + getTabModelSelectorSupplier().removeObserver(mSelectionPopupBackPressInitCallback); + }; + getTabModelSelectorSupplier().addObserver(mSelectionPopupBackPressInitCallback); + mBrowserControlsManagerSupplier.addObserver((controlManager) -> { assert !mBackPressManager.has(Type.FULLSCREEN) : "BrowserControlManager should be set at most once";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillExpirationDateFixFlowPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillExpirationDateFixFlowPrompt.java index 1f15e2da..4cf87f3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillExpirationDateFixFlowPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillExpirationDateFixFlowPrompt.java
@@ -53,7 +53,7 @@ AutofillExpirationDateFixFlowPromptDelegate delegate, String title, int drawableId, String cardLabel, String confirmButtonLabel) { return new AutofillExpirationDateFixFlowPrompt( - context, delegate, title, drawableId, cardLabel, confirmButtonLabel, false); + context, delegate, title, drawableId, cardLabel, null, confirmButtonLabel, false); } /** @@ -63,14 +63,15 @@ * @param delegate A {@link AutofillExpirationDateFixFlowPromptDelegate} to handle events. * @param title Title of the dialog prompt. * @param cardLabel Label representing a card which will be saved. + * @param cardholderAccount The Google account where a card will be saved. * @param confirmButtonLabel Label for the confirm button. * @return The prompt to confirm expiration data. */ public static AutofillExpirationDateFixFlowPrompt createAsMessageFixFlowPrompt(Context context, AutofillExpirationDateFixFlowPromptDelegate delegate, String title, String cardLabel, - String confirmButtonLabel) { + String cardholderAccount, String confirmButtonLabel) { return new AutofillExpirationDateFixFlowPrompt( - context, delegate, title, cardLabel, confirmButtonLabel); + context, delegate, title, cardLabel, cardholderAccount, confirmButtonLabel); } private final AutofillExpirationDateFixFlowPromptDelegate mDelegate; @@ -87,9 +88,10 @@ */ private AutofillExpirationDateFixFlowPrompt(Context context, AutofillExpirationDateFixFlowPromptDelegate delegate, String title, int drawableId, - String cardLabel, String confirmButtonLabel, boolean filledConfirmButton) { + String cardLabel, String cardholderAccount, String confirmButtonLabel, + boolean filledConfirmButton) { super(context, delegate, R.layout.autofill_expiration_date_fix_flow, title, drawableId, - confirmButtonLabel, filledConfirmButton); + cardholderAccount, confirmButtonLabel, filledConfirmButton); mDelegate = delegate; mErrorMessage = (TextView) mDialogView.findViewById(R.id.error_message); TextView cardDetailsMasked = (TextView) mDialogView.findViewById(R.id.cc_details_masked); @@ -112,9 +114,10 @@ private AutofillExpirationDateFixFlowPrompt(Context context, AutofillExpirationDateFixFlowPromptDelegate delegate, String title, String cardLabel, - String confirmButtonLabel) { + String cardholderAccount, String confirmButtonLabel) { // Set drawable id as 0 to remove the icon on the title. - this(context, delegate, title, /*drawableId=*/0, cardLabel, confirmButtonLabel, true); + this(context, delegate, title, /*drawableId=*/0, cardLabel, cardholderAccount, + confirmButtonLabel, true); mDialogView.findViewById(R.id.message_divider).setVisibility(View.VISIBLE); mDialogView.findViewById(R.id.google_pay_logo).setVisibility(View.VISIBLE); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillMessageConfirmFlowBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillMessageConfirmFlowBridge.java index 3b87868..c096949 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillMessageConfirmFlowBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillMessageConfirmFlowBridge.java
@@ -76,7 +76,7 @@ @Override public void onLinkClicked(String url) { - AutofillMessageConfirmFlowBridgeJni.get().onLegalMessageLinkClicked( + AutofillMessageConfirmFlowBridgeJni.get().onLinkClicked( mNativeSaveCardMessageConfirmDelegate, url); } @@ -102,12 +102,13 @@ } @CalledByNative - private void fixDate(String title, String cardLabel, String confirmButtonLabel) { + private void fixDate( + String title, String cardLabel, String cardholderAccount, String confirmButtonLabel) { Activity activity = mWindowAndroid.getActivity().get(); if (!prepareToShowDialog(activity)) return; if (mSaveCardPrompt == null) { mSaveCardPrompt = AutofillExpirationDateFixFlowPrompt.createAsMessageFixFlowPrompt( - activity, this, title, cardLabel, confirmButtonLabel); + activity, this, title, cardLabel, cardholderAccount, confirmButtonLabel); for (LegalMessageLine line : mLegalMessageLines) { mSaveCardPrompt.addLegalMessageLine(line); } @@ -116,13 +117,13 @@ } @CalledByNative - private void fixName( - String title, String inferredName, String cardLabel, String confirmButtonLabel) { + private void fixName(String title, String inferredName, String cardLabel, + String cardholderAccount, String confirmButtonLabel) { Activity activity = mWindowAndroid.getActivity().get(); if (!prepareToShowDialog(activity)) return; if (mSaveCardPrompt == null) { - mSaveCardPrompt = AutofillNameFixFlowPrompt.createAsMessageFixFlowPrompt( - activity, this, inferredName, title, cardLabel, confirmButtonLabel); + mSaveCardPrompt = AutofillNameFixFlowPrompt.createAsMessageFixFlowPrompt(activity, this, + inferredName, title, cardLabel, cardholderAccount, confirmButtonLabel); for (LegalMessageLine line : mLegalMessageLines) { mSaveCardPrompt.addLegalMessageLine(line); } @@ -131,12 +132,13 @@ } @CalledByNative - private void confirmSaveCard(String title, String cardLabel, String confirmButtonLabel) { + private void confirmSaveCard( + String title, String cardLabel, String cardholderAccount, String confirmButtonLabel) { Activity activity = mWindowAndroid.getActivity().get(); if (!prepareToShowDialog(activity)) return; if (mSaveCardPrompt == null) { mSaveCardPrompt = AutofillSaveCardConfirmFlowPrompt.createPrompt( - activity, this, title, cardLabel, confirmButtonLabel); + activity, this, title, cardLabel, cardholderAccount, confirmButtonLabel); for (LegalMessageLine line : mLegalMessageLines) { mSaveCardPrompt.addLegalMessageLine(line); } @@ -183,7 +185,7 @@ void onDateConfirmed(long nativeSaveCardMessageConfirmDelegate, String month, String year); void onNameConfirmed(long nativeSaveCardMessageConfirmDelegate, String name); void onSaveCardConfirmed(long nativeSaveCardMessageConfirmDelegate); - void onLegalMessageLinkClicked(long nativeSaveCardMessageConfirmDelegate, String url); + void onLinkClicked(long nativeSaveCardMessageConfirmDelegate, String url); void dialogDismissed(long nativeSaveCardMessageConfirmDelegate); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowPrompt.java index 0ee5715..04ccb4c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowPrompt.java
@@ -57,8 +57,8 @@ public static AutofillNameFixFlowPrompt createAsInfobarFixFlowPrompt(Context context, AutofillNameFixFlowPromptDelegate delegate, String inferredName, String title, int drawableId, String confirmButtonLabel) { - return new AutofillNameFixFlowPrompt( - context, delegate, inferredName, title, drawableId, confirmButtonLabel, false); + return new AutofillNameFixFlowPrompt(context, delegate, inferredName, title, drawableId, + null, confirmButtonLabel, false); } /** @@ -69,14 +69,15 @@ * @param inferredName Name inferred from the account. Empty string for user to fill in. * @param title Title of the prompt. * @param cardLabel Label representing a card which will be saved. + * @param cardholderAccount The Google account where a card will be saved. * @param confirmButtonLabel Label for the confirm button. * @return A {@link AutofillNameFixFlowPrompt} to confirm name. */ public static AutofillNameFixFlowPrompt createAsMessageFixFlowPrompt(Context context, AutofillNameFixFlowPromptDelegate delegate, String inferredName, String title, - String cardLabel, String confirmButtonLabel) { - return new AutofillNameFixFlowPrompt( - context, delegate, inferredName, title, cardLabel, confirmButtonLabel); + String cardLabel, String cardholderAccount, String confirmButtonLabel) { + return new AutofillNameFixFlowPrompt(context, delegate, inferredName, title, cardLabel, + cardholderAccount, confirmButtonLabel); } private final AutofillNameFixFlowPromptDelegate mDelegate; @@ -89,10 +90,10 @@ * Fix flow prompt to confirm user name before saving the card to Google. */ private AutofillNameFixFlowPrompt(Context context, AutofillNameFixFlowPromptDelegate delegate, - String inferredName, String title, int drawableId, String confirmButtonLabel, - boolean filledConfirmButton) { + String inferredName, String title, int drawableId, String cardholderAccount, + String confirmButtonLabel, boolean filledConfirmButton) { super(context, delegate, R.layout.autofill_name_fixflow, title, drawableId, - confirmButtonLabel, filledConfirmButton); + cardholderAccount, confirmButtonLabel, filledConfirmButton); mDelegate = delegate; mUserNameInput = (EditText) mDialogView.findViewById(R.id.cc_name_edit); mUserNameInput.setText(inferredName, BufferType.EDITABLE); @@ -121,8 +122,10 @@ } private AutofillNameFixFlowPrompt(Context context, AutofillNameFixFlowPromptDelegate delegate, - String inferredName, String title, String cardLabel, String confirmButtonLabel) { - this(context, delegate, inferredName, title, /*drawableId=*/0, confirmButtonLabel, true); + String inferredName, String title, String cardLabel, String cardholderAccount, + String confirmButtonLabel) { + this(context, delegate, inferredName, title, /*drawableId=*/0, cardholderAccount, + confirmButtonLabel, true); mDialogView.findViewById(R.id.cc_details).setVisibility(View.VISIBLE); TextView detailsMasked = mDialogView.findViewById(R.id.cc_details_masked); detailsMasked.setText(cardLabel);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillSaveCardConfirmFlowPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillSaveCardConfirmFlowPrompt.java index 48840b0..31f9ede 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillSaveCardConfirmFlowPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillSaveCardConfirmFlowPrompt.java
@@ -35,14 +35,15 @@ * @param delegate A {@link AutofillSaveCardConfirmFlowPromptDelegate} to handle events. * @param title Title of the dialog prompt. * @param cardLabel Label representing a card which will be saved. + * @param cardholderAccount The Google account where a card will be saved. * @param confirmButtonLabel Label for the confirm button. * @return A {@link AutofillSaveCardConfirmFlowPrompt} to confirm saving card. */ public static AutofillSaveCardConfirmFlowPrompt createPrompt(Context context, AutofillSaveCardConfirmFlowPromptDelegate delegate, String title, String cardLabel, - String confirmButtonLabel) { + String cardholderAccount, String confirmButtonLabel) { return new AutofillSaveCardConfirmFlowPrompt( - context, delegate, title, cardLabel, confirmButtonLabel); + context, delegate, title, cardLabel, cardholderAccount, confirmButtonLabel); } private final AutofillSaveCardConfirmFlowPromptDelegate mDelegate; @@ -52,8 +53,8 @@ */ private AutofillSaveCardConfirmFlowPrompt(Context context, AutofillSaveCardConfirmFlowPromptDelegate delegate, String title, String cardLabel, - String confirmButtonLabel) { - super(context, delegate, 0, title, 0, confirmButtonLabel, true); + String cardholderAccount, String confirmButtonLabel) { + super(context, delegate, 0, title, 0, cardholderAccount, confirmButtonLabel, true); mDelegate = delegate; TextView cardDetailsMasked = (TextView) mDialogView.findViewById(R.id.cc_details_masked); cardDetailsMasked.setText(cardLabel);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillSaveCardPromptBase.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillSaveCardPromptBase.java index 5e53218b..6981711 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillSaveCardPromptBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillSaveCardPromptBase.java
@@ -6,8 +6,10 @@ import android.app.Activity; import android.content.Context; +import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.Spanned; +import android.text.TextUtils; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.view.LayoutInflater; @@ -21,6 +23,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogProperties; @@ -42,7 +45,7 @@ interface AutofillSaveCardPromptBaseDelegate { /** - * Called when link in legal lines is clicked. + * Called when a link is clicked. */ void onLinkClicked(String url); @@ -64,13 +67,14 @@ * @param contentLayoutId The content of the prompt dialog. Set 0 to make content empty. * @param title Title of the prompt dialog. * @param titleIcon Icon near the title. Set 0 to ignore this icon. + * @param cardholderAccount The Google account where a card will be saved. * @param confirmButtonLabel The text of confirm button. * @param filledConfirmButton Whether to use a button of filled style. */ protected AutofillSaveCardPromptBase(Context context, AutofillSaveCardPromptBaseDelegate delegate, @LayoutRes int contentLayoutId, - String title, @DrawableRes int titleIcon, String confirmButtonLabel, - boolean filledConfirmButton) { + String title, @DrawableRes int titleIcon, String cardholderAccount, + String confirmButtonLabel, boolean filledConfirmButton) { mBaseDelegate = delegate; LayoutInflater inflater = LayoutInflater.from(context); mDialogView = inflater.inflate(R.layout.autofill_save_card_base_layout, null); @@ -86,8 +90,23 @@ DIALOG_V2_ENABLED_PARAM_NAME, false)) { TextView description = mDialogView.findViewById(R.id.description); description.setVisibility(View.VISIBLE); - description.setText( - R.string.autofill_mobile_save_card_to_cloud_confirmation_dialog_explanation); + if (!TextUtils.isEmpty(cardholderAccount)) { + SpannableString formattedCardholderAccount = new SpannableString(cardholderAccount); + formattedCardholderAccount.setSpan(new ClickableSpan() { + @Override + public void onClick(View view) { + mBaseDelegate.onLinkClicked(UrlConstants.GOOGLE_ACCOUNT_HOME_URL); + } + }, 0, cardholderAccount.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + description.setText(TextUtils.expandTemplate( + context.getString( + R.string.autofill_mobile_save_card_to_cloud_confirmation_dialog_explanation_with_account_name), + formattedCardholderAccount)); + description.setMovementMethod(LinkMovementMethod.getInstance()); + } else { + description.setText( + R.string.autofill_mobile_save_card_to_cloud_confirmation_dialog_explanation); + } } PropertyModel.Builder builder =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/RelatedSearchesControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/RelatedSearchesControl.java index 4ff8f51..3041afb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/RelatedSearchesControl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/RelatedSearchesControl.java
@@ -489,7 +489,7 @@ boolean isRelatedSearchesSuggestion = suggestionIndex > 0 || !mDisplayDefaultQuery; ContextualSearchUma.logAllSearches(isRelatedSearchesSuggestion); - mControlView.scrollToPosition(suggestionIndex); + mControlView.smoothScrollToPosition(suggestionIndex); } /** The position of the first Related Searches suggestion in the carousel UI. */ @@ -579,12 +579,12 @@ } /** - * Scroll to the view in the position. + * Smoothly scroll to the view in the position. * @param position the position of the view to scroll to. */ - private void scrollToPosition(int position) { + private void smoothScrollToPosition(int position) { RecyclerView recyclerView = (RecyclerView) mChipsCoordinator.getView(); - recyclerView.scrollToPosition(position); + recyclerView.smoothScrollToPosition(position); } /** Returns the view for this control. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index 480418a..ad5813b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -148,6 +148,7 @@ private final int mTabStripAndToolbarHeight; private final Supplier<Toolbar> mToolbarSupplier; + private final TabModelSelector mTabModelSelector; @Override public void onControlsOffsetChanged(int topOffset, int topControlsMinHeightOffset, @@ -340,6 +341,7 @@ mToolbarSupplier = toolbarSupplier; mMostVisitedTileClickObservers = new ObserverList<>(); mBrowserControlsStateProvider = browserControlsStateProvider; + mTabModelSelector = tabModelSelector; Profile profile = Profile.fromWebContents(mTab.getWebContents()); @@ -483,7 +485,7 @@ SurfaceType.NEW_TAB_PAGE, mConstructedTimeNs, FeedSwipeRefreshLayout.create(activity, R.id.toolbar_container), /* overScrollDisabled= */ false, /* viewportView= */ null, actionDelegate, - HelpAndFeedbackLauncherImpl.getInstance()); + HelpAndFeedbackLauncherImpl.getInstance(), mTabModelSelector); mFeedSurfaceProvider = feedSurfaceCoordinator; // Record the timestamp at which the new tab page's construction started.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinatorTest.java index 1d515e8..5b173d3 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinatorTest.java
@@ -60,6 +60,9 @@ import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; import org.chromium.chrome.browser.signin.services.SigninManager; +import org.chromium.chrome.browser.tabmodel.EmptyTabModel; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.xsurface.FeedLaunchReliabilityLogger; import org.chromium.chrome.browser.xsurface.FeedLaunchReliabilityLogger.SurfaceType; @@ -76,6 +79,8 @@ import org.chromium.components.signin.identitymanager.IdentityManager; import org.chromium.ui.base.WindowAndroid; +import java.util.ArrayList; + /** * Tests for {@link FeedSurfaceCoordinator}. * @@ -115,6 +120,23 @@ } } + private class TestTabModel extends EmptyTabModel { + public ArrayList<TabModelObserver> mObservers = new ArrayList<TabModelObserver>(); + + @Override + public void addObserver(TabModelObserver observer) { + mObservers.add(observer); + } + + void selectTab() { + for (TabModelObserver observer : mObservers) { + observer.didSelectTab(null, 0, 0); + } + } + } + private TestTabModel mTabModel = new TestTabModel(); + private TestTabModel mTabModelIncognito = new TestTabModel(); + private FeedSurfaceCoordinator mCoordinator; @Rule @@ -195,6 +217,8 @@ private PrivacyPreferencesManagerImpl mPrivacyPreferencesManager; @Mock private Tracker mTracker; + @Mock + private TabModelSelector mTabModelSelector; @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -242,6 +266,8 @@ when(mRenderer.bind(mContentManagerCaptor.capture(), isNull())).thenReturn(mRecyclerView); when(mSurfaceScope.getFeedLaunchReliabilityLogger()).thenReturn(mLaunchReliabilityLogger); TrackerFactory.setTrackerForTests(mTracker); + when(mTabModelSelector.getModel(eq(false))).thenReturn(mTabModel); + when(mTabModelSelector.getModel(eq(true))).thenReturn(mTabModelIncognito); mCoordinator = createCoordinator(); @@ -408,6 +434,24 @@ .logUiStarting(SURFACE_TYPE, SURFACE_CREATION_TIME_NS); } + @Test + public void testLogSwitchTabs() { + when(mLaunchReliabilityLogger.isLaunchInProgress()).thenReturn(true); + mTabModel.selectTab(); + verify(mLaunchReliabilityLogger, times(1)) + .logLaunchFinished( + anyLong(), eq(DiscoverLaunchResult.NAVIGATED_TO_ANOTHER_TAB.getNumber())); + } + + @Test + public void testLogSwitchTabsIncognito() { + when(mLaunchReliabilityLogger.isLaunchInProgress()).thenReturn(true); + mTabModelIncognito.selectTab(); + verify(mLaunchReliabilityLogger, times(1)) + .logLaunchFinished( + anyLong(), eq(DiscoverLaunchResult.NAVIGATED_TO_ANOTHER_TAB.getNumber())); + } + private boolean hasStreamBound() { if (mCoordinator.getMediatorForTesting().getCurrentStreamForTesting() == null) { return false; @@ -425,6 +469,6 @@ -> { return null; }, SURFACE_TYPE, SURFACE_CREATION_TIME_NS, null, false, /*viewportView=*/null, mFeedActionDelegate, - /*helpAndFeedbackLauncher=*/null); + /*helpAndFeedbackLauncher=*/null, mTabModelSelector); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpFeedSurfaceLifecycleManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpFeedSurfaceLifecycleManagerTest.java index a55e3c2..0a153db 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpFeedSurfaceLifecycleManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpFeedSurfaceLifecycleManagerTest.java
@@ -56,6 +56,8 @@ private PrefService mPrefService; @Mock private FeedSurfaceCoordinator mCoordinator; + @Mock + private FeedReliabilityLogger mFeedReliabilityLogger; private NtpFeedSurfaceLifecycleManager mNtpStreamLifecycleManager; @@ -67,6 +69,7 @@ when(mPrefService.getBoolean(anyString())).thenReturn(true); doNothing().when(mPrefService).setBoolean(anyString(), anyBoolean()); NtpFeedSurfaceLifecycleManager.setPrefServiceForTesting(mPrefService); + when(mCoordinator.getFeedReliabilityLogger()).thenReturn(mFeedReliabilityLogger); ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.CREATED); mNtpStreamLifecycleManager = @@ -300,4 +303,11 @@ ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.PAUSED); verify(mCoordinator).onActivityPaused(); } + + @Test + @SmallTest + public void testLogPageLoadStarted() { + mNtpStreamLifecycleManager.getTabObserverForTesting().onPageLoadStarted(null, null); + verify(mFeedReliabilityLogger, times(1)).onPageLoadStarted(); + } }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5a21d7b..b70b9dc8 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -393,6 +393,8 @@ "dips/cookie_access_filter.cc", "dips/cookie_access_filter.h", "dips/cookie_access_type.h", + "dips/cookie_mode.cc", + "dips/cookie_mode.h", "dips/dips_bounce_detector.cc", "dips/dips_bounce_detector.h", "dips/dips_helper.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index c58c4be..de5742d24 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -219,7 +219,7 @@ #include "components/content_creation/notes/core/note_features.h" #include "components/content_creation/reactions/core/reactions_features.h" #include "components/translate/content/android/translate_message.h" -#include "components/webapps/browser/android/features.h" +#include "components/webapps/browser/features.h" #else // BUILDFLAG(IS_ANDROID) #include "chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h" #include "chrome/browser/media/router/media_router_feature.h" @@ -3410,6 +3410,10 @@ {"vertical-snap", flag_descriptions::kVerticalSnapName, flag_descriptions::kVerticalSnapDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::wm::features::kVerticalSnap)}, + {"allow-poly-device-pairing", + flag_descriptions::kAllowPolyDevicePairingName, + flag_descriptions::kAllowPolyDevicePairingDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kAllowPolyDevicePairing)}, {"ash-bento-bar", flag_descriptions::kBentoBarName, flag_descriptions::kBentoBarDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kBentoBar)},
diff --git a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc index 5378c1f..1e7dc71 100644 --- a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc +++ b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/profiles/profile.h" #include "components/webapps/browser/android/webapps_icon_utils.h" #include "components/webapps/browser/android/webapps_utils.h" +#include "components/webapps/browser/features.h" #include "components/webapps/browser/installable/installable_manager.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" @@ -117,10 +118,10 @@ params.valid_manifest = true; params.prefer_maskable_icon = webapps::WebappsIconUtils::DoesAndroidSupportMaskableIcons(); - params.has_worker = true; + params.has_worker = !webapps::features::SkipInstallServiceWorkerCheck(); + params.wait_for_worker = !webapps::features::SkipInstallServiceWorkerCheck(); params.valid_primary_icon = true; params.valid_splash_icon = true; - params.wait_for_worker = true; webapps::InstallableManager* installable_manager = webapps::InstallableManager::FromWebContents(web_contents()); installable_manager->GetData(
diff --git a/chrome/browser/apps/app_service/extension_apps_utils.cc b/chrome/browser/apps/app_service/extension_apps_utils.cc index 5186bd91..a761c17 100644 --- a/chrome/browser/apps/app_service/extension_apps_utils.cc +++ b/chrome/browser/apps/app_service/extension_apps_utils.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/apps/app_service/extension_apps_utils.h" #include "base/files/file_path.h" +#include "base/strings/escape.h" #include "base/strings/string_split.h" #include "chrome/browser/profiles/profile.h" @@ -54,4 +55,14 @@ const char kExtensionAppMuxedIdDelimiter[] = "###"; #endif // IS_CHROMEOS +#if BUILDFLAG(IS_CHROMEOS_ASH) +std::string GetEscapedAppId(const std::string& app_id, AppType app_type) { + // Normally app ids would only contain alphanumerics, but standalone + // browser extension app uses '#' as a delimiter, which needs to be escaped. + return app_type == apps::AppType::kStandaloneBrowserChromeApp + ? base::EscapeAllExceptUnreserved(app_id) + : app_id; +} +#endif + } // namespace apps
diff --git a/chrome/browser/apps/app_service/extension_apps_utils.h b/chrome/browser/apps/app_service/extension_apps_utils.h index ec39e532..866dacd 100644 --- a/chrome/browser/apps/app_service/extension_apps_utils.h +++ b/chrome/browser/apps/app_service/extension_apps_utils.h
@@ -10,6 +10,7 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#include "components/services/app_service/public/cpp/app_types.h" class Profile; @@ -46,6 +47,11 @@ extern const char kExtensionAppMuxedIdDelimiter[]; #endif // IS_CHROMEOS +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Returns the escaped app_id to be passed to chrome::ShowAppManagementPage(). +std::string GetEscapedAppId(const std::string& app_id, AppType app_type); +#endif + } // namespace apps #endif // CHROME_BROWSER_APPS_APP_SERVICE_EXTENSION_APPS_UTILS_H_
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc index 2e86e40..2bacbb0 100644 --- a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc
@@ -43,6 +43,8 @@ #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/mojom/url_response_head.mojom.h" +#include "third_party/icu/source/common/unicode/locid.h" +#include "third_party/icu/source/common/unicode/utypes.h" #include "url/gurl.h" namespace wallpaper_handlers { @@ -182,6 +184,32 @@ return url; } +// Returns a language tag for the device's locale. This tag is a maximized +// version of the default locale, i.e., an attempt is made to infer the region +// code when the default locale has none. Subtags other than language and region +// are omitted, and if there is a failure while obtaining the language tag, an +// empty string is returned. +std::string GetLanguageTag() { + auto locale = icu::Locale::getDefault(); + if (!locale.getLanguage() || base::StringPiece(locale.getLanguage()).empty()) + return ""; + + UErrorCode status = U_ZERO_ERROR; + + // Attempt to infer a region code if the device's locale does not have one. + if (!locale.getCountry() || base::StringPiece(locale.getCountry()).empty()) { + locale.addLikelySubtags(status); + if (U_FAILURE(status)) + return ""; + } + + // Return a language tag with only the language and region codes, excluding + // extraneous subtags such as script type that may have been added above. + auto language_tag = icu::Locale(locale.getLanguage(), locale.getCountry()) + .toLanguageTag<std::string>(status); + return U_SUCCESS(status) ? language_tag : ""; +} + // Attempts to parse `photo` as a `GooglePhotosPhoto`. If successful, adds the // parsed photo to `parsed_response`. void AddGooglePhotosPhotoIfValid( @@ -605,6 +633,11 @@ "application/json"); resource_request->headers.SetHeader(net::HttpRequestHeaders::kAuthorization, "Bearer " + token_info.token); + auto language_tag = GetLanguageTag(); + if (!language_tag.empty()) { + resource_request->headers.SetHeader( + net::HttpRequestHeaders::kAcceptLanguage, language_tag); + } auto loader = network::SimpleURLLoader::Create(std::move(resource_request), traffic_annotation_);
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc index 3bf38da..6d132b79 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/run_loop.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/banners/app_banner_manager_browsertest_base.h" @@ -27,6 +28,7 @@ #include "components/webapps/browser/banners/app_banner_manager.h" #include "components/webapps/browser/banners/app_banner_metrics.h" #include "components/webapps/browser/banners/app_banner_settings_helper.h" +#include "components/webapps/browser/features.h" #include "components/webapps/browser/installable/installable_logging.h" #include "components/webapps/browser/installable/installable_manager.h" #include "components/webapps/browser/installable/installable_metrics.h" @@ -36,6 +38,7 @@ #include "content/public/test/mock_web_contents_observer.h" #include "content/public/test/prerender_test_util.h" #include "net/dns/mock_host_resolver.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace webapps { @@ -85,6 +88,10 @@ on_banner_prompt_reply_ = std::move(on_banner_prompt_reply); } + void SetWaitForServiceWorker(bool wait_for_worker) { + wait_for_worker_ = wait_for_worker; + } + protected: // All calls to RequestAppBanner should terminate in one of Stop() (not // showing banner), UpdateState(State::PENDING_ENGAGEMENT) (waiting for @@ -123,6 +130,13 @@ } } + InstallableParams ParamsToPerformInstallableWebAppCheck() override { + InstallableParams params = + AppBannerManager::ParamsToPerformInstallableWebAppCheck(); + params.wait_for_worker = wait_for_worker_; + return params; + } + void OnBannerPromptReply( mojo::Remote<blink::mojom::AppBannerController> controller, blink::mojom::AppBannerPromptReply reply) override { @@ -165,6 +179,8 @@ std::unique_ptr<bool> banner_shown_; std::unique_ptr<WebappInstallSource> install_source_; + bool wait_for_worker_ = true; + base::WeakPtrFactory<AppBannerManagerTest> weak_factory_{this}; }; @@ -871,5 +887,126 @@ EXPECT_EQ(manager->state(), AppBannerManager::State::INACTIVE); } +enum class ServiceWorkerCriteriaType { + kDisabled, + kSkipForInstalls, + kSkipAll, +}; + +class AppBannerServiceWorkerCriteriaTest + : public AppBannerManagerBrowserTest, + public testing::WithParamInterface<ServiceWorkerCriteriaType> { + public: + AppBannerServiceWorkerCriteriaTest() { + switch (GetParam()) { + case ServiceWorkerCriteriaType::kDisabled: + scoped_feature_list_.InitWithFeatures( + {}, {features::kSkipServiceWorkerCheckAll, + features::kSkipServiceWorkerCheckInstallOnly}); + break; + case ServiceWorkerCriteriaType::kSkipForInstalls: + scoped_feature_list_.InitWithFeatures( + {features::kSkipServiceWorkerCheckInstallOnly}, + {features::kSkipServiceWorkerCheckAll}); + break; + case ServiceWorkerCriteriaType::kSkipAll: + scoped_feature_list_.InitWithFeatures( + {features::kSkipServiceWorkerCheckAll}, + {features::kSkipServiceWorkerCheckInstallOnly}); + break; + } + } + ~AppBannerServiceWorkerCriteriaTest() override = default; + + AppBannerServiceWorkerCriteriaTest( + const AppBannerServiceWorkerCriteriaTest&) = delete; + AppBannerServiceWorkerCriteriaTest& operator=( + const AppBannerServiceWorkerCriteriaTest&) = delete; + + void SetUpOnMainThread() override { + AppBannerManagerBrowserTest::SetUpOnMainThread(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +IN_PROC_BROWSER_TEST_P(AppBannerServiceWorkerCriteriaTest, ShowBanner) { + std::unique_ptr<AppBannerManagerTest> manager( + CreateAppBannerManager(browser())); + RunBannerTest( + browser(), manager.get(), + embedded_test_server()->GetURL("/banners/manifest_test_page.html"), + absl::nullopt); + EXPECT_EQ(manager->state(), AppBannerManager::State::PENDING_PROMPT); +} + +IN_PROC_BROWSER_TEST_P(AppBannerServiceWorkerCriteriaTest, NoServiceWorker) { + std::unique_ptr<AppBannerManagerTest> manager( + CreateAppBannerManager(browser())); + // Set not wait for service worker so it will not timeout. + manager->SetWaitForServiceWorker(false); + + absl::optional<InstallableStatusCode> expected_code; + switch (GetParam()) { + case ServiceWorkerCriteriaType::kDisabled: + expected_code = NO_MATCHING_SERVICE_WORKER; + break; + case ServiceWorkerCriteriaType::kSkipForInstalls: + expected_code = SERVICE_WORKER_NOT_REQUIRED; + break; + case ServiceWorkerCriteriaType::kSkipAll: + expected_code = absl::nullopt; + break; + } + + RunBannerTest(browser(), manager.get(), + embedded_test_server()->GetURL( + "/banners/manifest_no_service_worker.html"), + expected_code); + + if (expected_code) { + EXPECT_EQ(manager->state(), AppBannerManager::State::COMPLETE); + } else { + EXPECT_EQ(manager->state(), AppBannerManager::State::PENDING_PROMPT); + } +} + +IN_PROC_BROWSER_TEST_P(AppBannerServiceWorkerCriteriaTest, NoFetchHandler) { + std::unique_ptr<AppBannerManagerTest> manager( + CreateAppBannerManager(browser())); + + absl::optional<InstallableStatusCode> expected_code; + switch (GetParam()) { + case ServiceWorkerCriteriaType::kDisabled: + expected_code = NOT_OFFLINE_CAPABLE; + break; + case ServiceWorkerCriteriaType::kSkipForInstalls: + expected_code = SERVICE_WORKER_NOT_REQUIRED; + break; + case ServiceWorkerCriteriaType::kSkipAll: + expected_code = absl::nullopt; + break; + } + + RunBannerTest(browser(), manager.get(), + embedded_test_server()->GetURL( + "/banners/no_sw_fetch_handler_test_page.html"), + expected_code); + + if (expected_code) { + EXPECT_EQ(manager->state(), AppBannerManager::State::COMPLETE); + } else { + EXPECT_EQ(manager->state(), AppBannerManager::State::PENDING_PROMPT); + } +} + +INSTANTIATE_TEST_SUITE_P( + All, + AppBannerServiceWorkerCriteriaTest, + testing::Values(ServiceWorkerCriteriaType::kDisabled, + ServiceWorkerCriteriaType::kSkipForInstalls, + ServiceWorkerCriteriaType::kSkipAll)); + } // namespace } // namespace webapps
diff --git a/chrome/browser/browser_switcher/bho/BUILD.gn b/chrome/browser/browser_switcher/bho/BUILD.gn index 63fa7d4..a8b790f 100644 --- a/chrome/browser/browser_switcher/bho/BUILD.gn +++ b/chrome/browser/browser_switcher/bho/BUILD.gn
@@ -86,13 +86,24 @@ ] } -assert(is_clang) +if (is_clang) { + browser_switcher_x64_toolchain = "//build/toolchain/win:win_clang_x64" + if (!is_asan) { + browser_switcher_x86_toolchain = "//build/toolchain/win:win_clang_x86" + } +} else { + browser_switcher_x64_toolchain = "//build/toolchain/win:x64" + if (!is_asan) { + browser_switcher_x86_toolchain = "//build/toolchain/win:x86" + } +} + browser_switcher_x64_label = - ":browser_switcher_bho(//build/toolchain/win:win_clang_x64)" + ":browser_switcher_bho($browser_switcher_x64_toolchain)" if (!is_asan) { browser_switcher_x86_label = - ":browser_switcher_bho(//build/toolchain/win:win_clang_x86)" + ":browser_switcher_bho($browser_switcher_x86_toolchain)" copy("copy_browser_switcher_binaries") { # Make sure we have both bitnesses in the root out directory.
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 431ac31..a017873 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -137,6 +137,7 @@ #include "chrome/browser/ui/login/login_handler.h" #include "chrome/browser/ui/login/login_navigation_throttle.h" #include "chrome/browser/ui/login/login_tab_helper.h" +#include "chrome/browser/ui/passwords/password_manager_navigation_throttle.h" #include "chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h" #include "chrome/browser/ui/prefs/pref_watcher.h" #include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h" @@ -313,6 +314,7 @@ #include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "third_party/blink/public/common/navigation/navigation_policy.h" #include "third_party/blink/public/common/permissions/permission_utils.h" +#include "third_party/blink/public/common/permissions_policy/permissions_policy.h" #include "third_party/blink/public/common/switches.h" #include "third_party/blink/public/mojom/browsing_topics/browsing_topics.mojom.h" #include "third_party/blink/public/public_buildflags.h" @@ -1972,6 +1974,27 @@ #endif } +blink::ParsedPermissionsPolicy +ChromeContentBrowserClient::GetPermissionsPolicyForIsolatedApp( + content::BrowserContext* browser_context, + const url::Origin& app_origin) { +#if !BUILDFLAG(IS_ANDROID) + Profile* profile = Profile::FromBrowserContext(browser_context); + auto& registrar = + web_app::WebAppProvider::GetForWebApps(profile)->registrar(); + std::vector<web_app::AppId> app_ids_for_origin = + registrar.FindAppsInScope(app_origin.GetURL()); + if (app_ids_for_origin.empty()) { + return blink::ParsedPermissionsPolicy(); + } + + return registrar.GetPermissionsPolicy(app_ids_for_origin[0]); +#else + NOTIMPLEMENTED(); + return blink::ParsedPermissionsPolicy(); +#endif +} + bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost( content::BrowserContext* browser_context, const GURL& url) { @@ -4306,6 +4329,10 @@ WellKnownChangePasswordNavigationThrottle::MaybeCreateThrottleFor(handle), &throttles); + MaybeAddThrottle( + PasswordManagerNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); + throttles.push_back(std::make_unique<PolicyBlocklistNavigationThrottle>( handle, handle->GetWebContents()->GetBrowserContext()));
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 1b36ff5..93a29511 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -201,6 +201,9 @@ const GURL& site_url) override; bool MayReuseHost(content::RenderProcessHost* process_host) override; size_t GetProcessCountToIgnoreForLimit() override; + blink::ParsedPermissionsPolicy GetPermissionsPolicyForIsolatedApp( + content::BrowserContext* browser_context, + const url::Origin& app_origin) override; bool ShouldTryToUseExistingProcessHost( content::BrowserContext* browser_context, const GURL& url) override;
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index f1dee9f..efd9c62 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -1385,13 +1385,13 @@ auto client = std::make_unique<policy::ChromePolicyConversionsClient>( browser_context()); - base::Value all_policies_array = + base::Value::Dict all_policies_dict = policy::DictionaryPolicyConversions(std::move(client)) .EnableDeviceLocalAccountPolicies(true) .EnableDeviceInfo(true) - .ToValue(); + .ToValueDict(); - return RespondNow(OneArgument(std::move(all_policies_array))); + return RespondNow(OneArgument(base::Value(std::move(all_policies_dict)))); } ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc index 811c5c9d..9fd700c 100644 --- a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc +++ b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
@@ -164,7 +164,13 @@ << message_; } -IN_PROC_BROWSER_TEST_F(FileSystemProviderApiTest, Unmount) { +// TODO(crbug.com/1324887): Re-enable this test +#if defined(MEMORY_SANITIZER) +#define MAYBE_Unmount DISABLED_Unmount +#else +#define MAYBE_Unmount Unmount +#endif +IN_PROC_BROWSER_TEST_F(FileSystemProviderApiTest, MAYBE_Unmount) { ASSERT_TRUE(RunExtensionTest("file_system_provider/unmount", {.launch_as_platform_app = true}, {.load_as_component = true}))
diff --git a/chrome/browser/dips/cookie_mode.cc b/chrome/browser/dips/cookie_mode.cc new file mode 100644 index 0000000..8471aad3 --- /dev/null +++ b/chrome/browser/dips/cookie_mode.cc
@@ -0,0 +1,56 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/dips/cookie_mode.h" + +#include "base/strings/string_piece.h" + +DIPSCookieMode GetDIPSCookieMode(bool is_otr, bool block_third_party_cookies) { + if (is_otr) { + if (block_third_party_cookies) { + return DIPSCookieMode::kOffTheRecord_Block3PC; + } + return DIPSCookieMode::kOffTheRecord; + } + + if (block_third_party_cookies) { + return DIPSCookieMode::kBlock3PC; + } + + return DIPSCookieMode::kStandard; +} + +base::StringPiece GetHistogramSuffix(DIPSCookieMode mode) { + // Any changes here need to be reflected in DIPSCookieMode in + // tools/metrics/histograms/metadata/others/histograms.xml + switch (mode) { + case DIPSCookieMode::kStandard: + return ".Standard"; + case DIPSCookieMode::kOffTheRecord: + return ".OffTheRecord"; + case DIPSCookieMode::kBlock3PC: + return ".Block3PC"; + case DIPSCookieMode::kOffTheRecord_Block3PC: + return ".OffTheRecord_Block3PC"; + } + DCHECK(false) << "Invalid DIPSCookieMode"; + return base::StringPiece(); +} + +const char* DIPSCookieModeToString(DIPSCookieMode mode) { + switch (mode) { + case DIPSCookieMode::kStandard: + return "Standard"; + case DIPSCookieMode::kOffTheRecord: + return "OffTheRecord"; + case DIPSCookieMode::kBlock3PC: + return "Block3PC"; + case DIPSCookieMode::kOffTheRecord_Block3PC: + return "OffTheRecord_Block3PC"; + } +} + +std::ostream& operator<<(std::ostream& os, DIPSCookieMode mode) { + return os << DIPSCookieModeToString(mode); +}
diff --git a/chrome/browser/dips/cookie_mode.h b/chrome/browser/dips/cookie_mode.h new file mode 100644 index 0000000..04c8687 --- /dev/null +++ b/chrome/browser/dips/cookie_mode.h
@@ -0,0 +1,27 @@ +// Copyright 2022 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_DIPS_COOKIE_MODE_H_ +#define CHROME_BROWSER_DIPS_COOKIE_MODE_H_ + +#include <ostream> + +#include "base/strings/string_piece_forward.h" + +enum class DIPSCookieMode { + kStandard, + kOffTheRecord, + kBlock3PC, // block third-party cookies + kOffTheRecord_Block3PC +}; + +DIPSCookieMode GetDIPSCookieMode(bool is_otr, bool block_third_party_cookies); + +base::StringPiece GetHistogramSuffix(DIPSCookieMode mode); + +const char* DIPSCookieModeToString(DIPSCookieMode mode); + +std::ostream& operator<<(std::ostream& os, DIPSCookieMode mode); + +#endif // CHROME_BROWSER_DIPS_COOKIE_MODE_H_
diff --git a/chrome/browser/dips/dips_bounce_detector.cc b/chrome/browser/dips/dips_bounce_detector.cc index 1d6d785..de6be872 100644 --- a/chrome/browser/dips/dips_bounce_detector.cc +++ b/chrome/browser/dips/dips_bounce_detector.cc
@@ -6,10 +6,16 @@ #include <vector> +#include "base/metrics/histogram_functions.h" +#include "base/strings/strcat.h" #include "chrome/browser/dips/cookie_access_filter.h" +#include "chrome/browser/dips/cookie_mode.h" +#include "chrome/browser/dips/dips_service.h" #include "components/site_engagement/content/site_engagement_service.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/cookie_access_details.h" #include "content/public/browser/navigation_handle.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" using content::NavigationHandle; @@ -28,11 +34,42 @@ const char kBounceDetectionStateKey[] = "BounceDetectionState"; +std::string GetSite(const GURL& url) { + const auto domain = net::registry_controlled_domains::GetDomainAndRegistry( + url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + return domain.empty() ? url.host() : domain; +} + +RedirectCategory ClassifyRedirect(CookieAccessType access, double engagement) { + switch (access) { + case CookieAccessType::kNone: + return engagement > 0 ? RedirectCategory::kNoCookies_HasEngagement + : RedirectCategory::kNoCookies_NoEngagement; + case CookieAccessType::kRead: + return engagement > 0 ? RedirectCategory::kReadCookies_HasEngagement + : RedirectCategory::kReadCookies_NoEngagement; + case CookieAccessType::kWrite: + return engagement > 0 ? RedirectCategory::kWriteCookies_HasEngagement + : RedirectCategory::kWriteCookies_NoEngagement; + case CookieAccessType::kReadWrite: + return engagement > 0 ? RedirectCategory::kReadWriteCookies_HasEngagement + : RedirectCategory::kReadWriteCookies_NoEngagement; + } +} + +inline void UmaHistogramBounceCategory(RedirectCategory category, + DIPSCookieMode mode) { + const std::string histogram_name = + base::StrCat({"Privacy.DIPS.BounceCategory", GetHistogramSuffix(mode)}); + base::UmaHistogramEnumeration(histogram_name, category); +} + } // namespace DIPSBounceDetector::DIPSBounceDetector(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), content::WebContentsUserData<DIPSBounceDetector>(*web_contents), + dips_service_(DIPSService::Get(web_contents->GetBrowserContext())), site_engagement_service_(site_engagement::SiteEngagementService::Get( web_contents->GetBrowserContext())), // It's safe to use unretained because the callback is owned by this. @@ -46,13 +83,27 @@ DIPSBounceDetector::~DIPSBounceDetector() = default; +DIPSCookieMode DIPSBounceDetector::GetCookieMode() const { + return GetDIPSCookieMode( + web_contents()->GetBrowserContext()->IsOffTheRecord(), + dips_service_->ShouldBlockThirdPartyCookies()); +} + void DIPSBounceDetector::HandleStatefulRedirect(const GURL& prev_url, const GURL& url, const GURL& next_url, CookieAccessType access) { + const std::string site = GetSite(url); + // TODO(rtarpine): all the calls to HandleStatefulRedirect() for a redirect + // chain call GetSite() on the same prev_url and next_url. Be more efficient. + if (site == GetSite(prev_url) || site == GetSite(next_url)) { + // Ignore same-site redirects. + return; + } + double score = site_engagement_service_->GetScore(url); - (void)score; - // TODO: fire UKM metric + RedirectCategory category = ClassifyRedirect(access, score); + UmaHistogramBounceCategory(category, GetCookieMode()); } void DIPSBounceDetector::HandleStatefulServerRedirect(
diff --git a/chrome/browser/dips/dips_bounce_detector.h b/chrome/browser/dips/dips_bounce_detector.h index 2035537a..8aa25bf 100644 --- a/chrome/browser/dips/dips_bounce_detector.h +++ b/chrome/browser/dips/dips_bounce_detector.h
@@ -8,6 +8,7 @@ #include "base/callback.h" #include "base/memory/raw_ptr.h" #include "chrome/browser/dips/cookie_access_type.h" +#include "chrome/browser/dips/cookie_mode.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -15,6 +16,8 @@ class SiteEngagementService; } +class DIPSService; + class DIPSBounceDetector : public content::WebContentsObserver, public content::WebContentsUserData<DIPSBounceDetector> { @@ -43,6 +46,8 @@ // So WebContentsUserData::CreateForWebContents() can call the constructor. friend class content::WebContentsUserData<DIPSBounceDetector>; + DIPSCookieMode GetCookieMode() const; + // Called when any stateful redirect is detected. // // `prev_url` is the page previously committed before starting the chain of @@ -65,6 +70,11 @@ void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; + // raw_ptr<> is safe here DIPSService is a KeyedService, associated with the + // BrowserContext/Profile which will outlive the WebContents that + // DIPSBounceDetector is observing. + raw_ptr<DIPSService> dips_service_; + // raw_ptr<> is safe here for the same reasons as above. raw_ptr<site_engagement::SiteEngagementService> site_engagement_service_; // By default, this just calls this->HandleStatefulServerRedirect(), but it // can be overridden for tests. @@ -76,4 +86,21 @@ WEB_CONTENTS_USER_DATA_KEY_DECL(); }; +// RedirectCategory is basically the cross-product of CookieAccessType and a +// boolean value indicating site engagement. It's used in UMA enum histograms. +// +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class RedirectCategory { + kNoCookies_NoEngagement = 0, + kReadCookies_NoEngagement = 1, + kWriteCookies_NoEngagement = 2, + kReadWriteCookies_NoEngagement = 3, + kNoCookies_HasEngagement = 4, + kReadCookies_HasEngagement = 5, + kWriteCookies_HasEngagement = 6, + kReadWriteCookies_HasEngagement = 7, + kMaxValue = kReadWriteCookies_HasEngagement, +}; + #endif // CHROME_BROWSER_DIPS_DIPS_BOUNCE_DETECTOR_H_
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc index 3e993230..18873b9a 100644 --- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc +++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -430,3 +430,48 @@ "b.test/cross-site/c.test/cross-site/d.test/404 -> " "d.test/404"))); } + +using base::Bucket; + +IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest, + Histograms_BounceCategory) { + GURL initial_url = embedded_test_server()->GetURL("a.test", "/title1.html"); + GURL redirect_url = embedded_test_server()->GetURL( + "a.test", + "/cross-site-with-cookie/b.test/cross-site/c.test/cross-site/d.test/" + "title1.html"); + GURL final_url = embedded_test_server()->GetURL("d.test", "/title1.html"); + content::WebContents* web_contents = GetActiveWebContents(); + + // Set cookies on a.test and b.test. Note that browser-initiated navigations + // like these are treated as a sign of user engagement. + ASSERT_TRUE(content::NavigateToURL( + web_contents, + embedded_test_server()->GetURL("a.test", "/set-cookie?name=value"))); + ASSERT_TRUE(content::NavigateToURL( + web_contents, + embedded_test_server()->GetURL("b.test", "/set-cookie?name=value"))); + // Navigate to starting page. + ASSERT_TRUE(content::NavigateToURLFromRenderer(web_contents, initial_url)); + + // Visit the redirect and monitor the histograms. + base::HistogramTester histograms; + ASSERT_TRUE(content::NavigateToURLFromRenderer(web_contents, redirect_url, + final_url)); + + // Verify the correct histogram was used for all samples. + base::HistogramTester::CountsMap expected_counts; + expected_counts["Privacy.DIPS.BounceCategory.Standard"] = 2; + EXPECT_THAT( + histograms.GetTotalCountsForPrefix("Privacy.DIPS.BounceCategory."), + testing::ContainerEq(expected_counts)); + // Verify the proper values were recorded. Note that the a.test redirect was + // not reported because the previously committed page was also on a.test. + EXPECT_THAT( + histograms.GetAllSamples("Privacy.DIPS.BounceCategory.Standard"), + testing::ElementsAre( + // c.test + Bucket((int)RedirectCategory::kNoCookies_NoEngagement, 1), + // b.test + Bucket((int)RedirectCategory::kReadCookies_HasEngagement, 1))); +}
diff --git a/chrome/browser/dips/dips_helper.cc b/chrome/browser/dips/dips_helper.cc index a3c460f..6e587ed 100644 --- a/chrome/browser/dips/dips_helper.cc +++ b/chrome/browser/dips/dips_helper.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/metrics/histogram_functions.h" +#include "base/strings/strcat.h" #include "base/time/default_clock.h" #include "chrome/browser/dips/dips_service.h" #include "chrome/browser/dips/dips_storage.h" @@ -19,26 +20,8 @@ inline void UmaHistogramTimeToInteraction(base::TimeDelta sample, DIPSCookieMode mode) { - // Any changes here need to be reflected in DIPSCookieMode in - // tools/metrics/histograms/metadata/others/histograms.xml - const char* name; - switch (mode) { - case DIPSCookieMode::kStandard: - name = "Privacy.DIPS.TimeFromStorageToInteraction.Standard"; - break; - case DIPSCookieMode::kOffTheRecord: - name = "Privacy.DIPS.TimeFromStorageToInteraction.OffTheRecord"; - break; - case DIPSCookieMode::kBlock3PC: - name = "Privacy.DIPS.TimeFromStorageToInteraction.Block3PC"; - break; - case DIPSCookieMode::kOffTheRecord_Block3PC: - name = "Privacy.DIPS.TimeFromStorageToInteraction.OffTheRecord_Block3PC"; - break; - default: - NOTREACHED() << "Invalid DIPSCookieMode: " << mode; - return; - } + const std::string name = base::StrCat( + {"Privacy.DIPS.TimeFromStorageToInteraction", GetHistogramSuffix(mode)}); base::UmaHistogramCustomTimes(name, sample, /*min=*/base::TimeDelta(), @@ -47,26 +30,8 @@ inline void UmaHistogramTimeToStorage(base::TimeDelta sample, DIPSCookieMode mode) { - // Any changes here need to be reflected in DIPSCookieMode in - // tools/metrics/histograms/metadata/others/histograms.xml - const char* name; - switch (mode) { - case DIPSCookieMode::kStandard: - name = "Privacy.DIPS.TimeFromInteractionToStorage.Standard"; - break; - case DIPSCookieMode::kOffTheRecord: - name = "Privacy.DIPS.TimeFromInteractionToStorage.OffTheRecord"; - break; - case DIPSCookieMode::kBlock3PC: - name = "Privacy.DIPS.TimeFromInteractionToStorage.Block3PC"; - break; - case DIPSCookieMode::kOffTheRecord_Block3PC: - name = "Privacy.DIPS.TimeFromInteractionToStorage.OffTheRecord_Block3PC"; - break; - default: - NOTREACHED() << "Invalid DIPSCookieMode: " << mode; - return; - } + const std::string name = base::StrCat( + {"Privacy.DIPS.TimeFromInteractionToStorage", GetHistogramSuffix(mode)}); base::UmaHistogramCustomTimes(name, sample, /*min=*/base::TimeDelta(), @@ -80,23 +45,6 @@ } // namespace -const char* DIPSCookieModeToString(DIPSCookieMode mode) { - switch (mode) { - case DIPSCookieMode::kStandard: - return "Standard"; - case DIPSCookieMode::kOffTheRecord: - return "OffTheRecord"; - case DIPSCookieMode::kBlock3PC: - return "Block3PC"; - case DIPSCookieMode::kOffTheRecord_Block3PC: - return "OffTheRecord_Block3PC"; - } -} - -std::ostream& operator<<(std::ostream& os, DIPSCookieMode mode) { - return os << DIPSCookieModeToString(mode); -} - DIPSTabHelper::DIPSTabHelper(content::WebContents* web_contents, DIPSService* service) : content::WebContentsObserver(web_contents), @@ -107,17 +55,9 @@ } DIPSCookieMode DIPSTabHelper::GetCookieMode() const { - bool isOTR = web_contents()->GetBrowserContext()->IsOffTheRecord(); - bool block3PC = service_->ShouldBlockThirdPartyCookies(); - if (isOTR) { - if (block3PC) { - return DIPSCookieMode::kOffTheRecord_Block3PC; - } - return DIPSCookieMode::kOffTheRecord; - } else if (block3PC) { - return DIPSCookieMode::kBlock3PC; - } - return DIPSCookieMode::kStandard; + return GetDIPSCookieMode( + web_contents()->GetBrowserContext()->IsOffTheRecord(), + service_->ShouldBlockThirdPartyCookies()); } DIPSState DIPSTabHelper::StateForURL(const GURL& url) {
diff --git a/chrome/browser/dips/dips_helper.h b/chrome/browser/dips/dips_helper.h index 6bdb4ce..e42de722 100644 --- a/chrome/browser/dips/dips_helper.h +++ b/chrome/browser/dips/dips_helper.h
@@ -5,8 +5,7 @@ #ifndef CHROME_BROWSER_DIPS_DIPS_HELPER_H_ #define CHROME_BROWSER_DIPS_DIPS_HELPER_H_ -#include <ostream> - +#include "chrome/browser/dips/cookie_mode.h" #include "chrome/browser/dips/dips_state.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -17,17 +16,6 @@ class DIPSService; -enum class DIPSCookieMode { - kStandard, - kOffTheRecord, - kBlock3PC, // block third-party cookies - kOffTheRecord_Block3PC -}; - -const char* DIPSCookieModeToString(DIPSCookieMode mode); - -std::ostream& operator<<(std::ostream& os, DIPSCookieMode mode); - // A WebContentsObserver subclass that listens for storage and user interaction // events that DIPSService is interested in. class DIPSTabHelper : public content::WebContentsObserver,
diff --git a/chrome/browser/enterprise/reporting/policy_info_unittest.cc b/chrome/browser/enterprise/reporting/policy_info_unittest.cc index a917fa94..d1f0204 100644 --- a/chrome/browser/enterprise/reporting/policy_info_unittest.cc +++ b/chrome/browser/enterprise/reporting/policy_info_unittest.cc
@@ -113,7 +113,7 @@ policy::DictionaryPolicyConversions(std::move(client)) .EnableConvertTypes(false) .EnablePrettyPrint(false) - .ToValue(), + .ToValueDict(), &profile_info); EXPECT_EQ(2, profile_info.chrome_policies_size()); @@ -162,7 +162,7 @@ policy::DictionaryPolicyConversions(std::move(client)) .EnableConvertTypes(false) .EnablePrettyPrint(false) - .ToValue(), + .ToValueDict(), &profile_info); // The second extension is not in the report because it has no policy. EXPECT_EQ(1, profile_info.extension_policies_size());
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc index 3b8aca8..a0a25d9 100644 --- a/chrome/browser/extensions/content_script_apitest.cc +++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -1553,11 +1553,20 @@ // https://crbug.com/963420. IN_PROC_BROWSER_TEST_F(ContentScriptRelatedFrameTest, MatchAboutBlank_NullParent) { - content::DOMMessageQueue message_queue; NavigateParams navigate_params(browser(), null_document_url(), ui::PAGE_TRANSITION_TYPED); navigate_params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; - Navigate(&navigate_params); + + // Save the WebContents instance that will be created by this navigation, as + // the dom message that we later wait for is sent in this instance. + content::WebContents* web_contents = nullptr; + { + content::WebContentsAddedObserver new_web_contents_observer; + Navigate(&navigate_params); + web_contents = new_web_contents_observer.GetWebContents(); + } + + content::DOMMessageQueue message_queue(web_contents); std::string result; // We can't rely on the navigation observer logic, because the frame is // destroyed before it finishes loading. Instead, it sends a message through
diff --git a/chrome/browser/extensions/extension_keeplist_ash.cc b/chrome/browser/extensions/extension_keeplist_ash.cc index a19916d..6d3c307c 100644 --- a/chrome/browser/extensions/extension_keeplist_ash.cc +++ b/chrome/browser/extensions/extension_keeplist_ash.cc
@@ -19,28 +19,23 @@ namespace extensions { bool ExtensionRunsInAsh(const std::string& extension_id) { - static base::NoDestructor<std::set<base::StringPiece>> keep_list({ -#if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION) - extension_misc::kHangoutServiceExtensionId, -#endif - extension_misc::kEspeakSpeechSynthesisExtensionId, - extension_misc::kGoogleSpeechSynthesisExtensionId, - extension_misc::kEnhancedNetworkTtsExtensionId, - extension_misc::kSelectToSpeakExtensionId, - extension_misc::kAccessibilityCommonExtensionId, - extension_misc::kChromeVoxExtensionId, - extension_misc::kSwitchAccessExtensionId, - extension_misc::kSigninProfileTestExtensionId, - extension_misc::kAssessmentAssistantExtensionId, - extension_misc::kQuickOfficeComponentExtensionId, - extension_misc::kQuickOfficeInternalExtensionId, - extension_misc::kQuickOfficeExtensionId, - extension_misc::kGuestModeTestExtensionId, - extension_misc::kKeyboardExtensionId, - extension_misc::kHelpAppExtensionId, extension_misc::kGCSEExtensionId, - extension_misc::kGnubbyV3ExtensionId, - file_manager::kImageLoaderExtensionId - }); + static base::NoDestructor<std::set<base::StringPiece>> keep_list( + {extension_misc::kEspeakSpeechSynthesisExtensionId, + extension_misc::kGoogleSpeechSynthesisExtensionId, + extension_misc::kEnhancedNetworkTtsExtensionId, + extension_misc::kSelectToSpeakExtensionId, + extension_misc::kAccessibilityCommonExtensionId, + extension_misc::kChromeVoxExtensionId, + extension_misc::kSwitchAccessExtensionId, + extension_misc::kSigninProfileTestExtensionId, + extension_misc::kQuickOfficeComponentExtensionId, + extension_misc::kQuickOfficeInternalExtensionId, + extension_misc::kQuickOfficeExtensionId, + extension_misc::kGuestModeTestExtensionId, + extension_misc::kKeyboardExtensionId, + extension_misc::kHelpAppExtensionId, extension_misc::kGCSEExtensionId, + extension_misc::kGnubbyV3ExtensionId, + file_manager::kImageLoaderExtensionId}); return base::Contains(*keep_list, extension_id) || ash::input_method::ComponentExtensionIMEManagerDelegateImpl:: IsIMEExtensionID(extension_id);
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 8a9dc73..a1142cb6 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -2790,7 +2790,7 @@ const char* kDefaultCSP = GetParam() == ManifestVersion::kTwo ? "script-src 'self' blob: filesystem:; " "object-src 'self' blob: filesystem:;" - : "script-src 'self' 'wasm-unsafe-eval'; " + : "script-src 'self'; " "object-src 'self';"; ExtensionTestMessageListener csp_modified_listener(kDefaultCSP, false); csp_modified_listener.set_extension_id(extension_id);
diff --git a/chrome/browser/extensions/wasm_mv3_browsertest.cc b/chrome/browser/extensions/wasm_mv3_browsertest.cc index 68752b6a1..370cd0da 100644 --- a/chrome/browser/extensions/wasm_mv3_browsertest.cc +++ b/chrome/browser/extensions/wasm_mv3_browsertest.cc
@@ -28,6 +28,12 @@ ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); } +// Test web assembly usage without explicit CSP allowing it. +IN_PROC_BROWSER_TEST_F(WasmMV3BrowserTest, ExtensionPageNoCSP) { + ASSERT_TRUE(RunExtensionTest("no_wasm_mv3", {.page_url = "page.html"})) + << message_; +} + // Test web assembly usage in an extension page. IN_PROC_BROWSER_TEST_F(WasmMV3BrowserTest, ExtensionPage) { ASSERT_TRUE(RunExtensionTest("wasm_mv3", {.page_url = "page.html"}))
diff --git a/chrome/browser/feed/android/BUILD.gn b/chrome/browser/feed/android/BUILD.gn index 7edf94c31..95b3c0a 100644 --- a/chrome/browser/feed/android/BUILD.gn +++ b/chrome/browser/feed/android/BUILD.gn
@@ -159,10 +159,10 @@ android_resources("feed_java_resources") { sources = [ - "java/res/color/chip_hairline_color.xml", + "java/res/color/chip_hairline_color_list.xml", "java/res/color/header_title_text_color_list.xml", - "java/res/color/menu_footer_chip_background.xml", "java/res/color/menu_footer_chip_background_baseline.xml", + "java/res/color/menu_footer_chip_background_list.xml", "java/res/color/tab_layout_text_color_list.xml", "java/res/drawable-hdpi/follow_accelerator_shadow.9.png", "java/res/drawable-mdpi/follow_accelerator_shadow.9.png",
diff --git a/chrome/browser/feed/android/java/res/color/chip_hairline_color.xml b/chrome/browser/feed/android/java/res/color/chip_hairline_color_list.xml similarity index 100% rename from chrome/browser/feed/android/java/res/color/chip_hairline_color.xml rename to chrome/browser/feed/android/java/res/color/chip_hairline_color_list.xml
diff --git a/chrome/browser/feed/android/java/res/color/menu_footer_chip_background.xml b/chrome/browser/feed/android/java/res/color/menu_footer_chip_background_list.xml similarity index 100% rename from chrome/browser/feed/android/java/res/color/menu_footer_chip_background.xml rename to chrome/browser/feed/android/java/res/color/menu_footer_chip_background_list.xml
diff --git a/chrome/browser/feed/android/java/res/values/styles.xml b/chrome/browser/feed/android/java/res/values/styles.xml index 4823947..13549343 100644 --- a/chrome/browser/feed/android/java/res/values/styles.xml +++ b/chrome/browser/feed/android/java/res/values/styles.xml
@@ -21,7 +21,7 @@ <style name="MenuFooterChipInverse" parent="MenuFooterChip"> <item name="chipColor">@android:color/transparent</item> - <item name="chipStrokeColor">@color/chip_hairline_color</item> + <item name="chipStrokeColor">@color/chip_hairline_color_list</item> <item name="solidColorChip">false</item> </style>
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedReliabilityLogger.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedReliabilityLogger.java index 10d1394..eaa545e 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedReliabilityLogger.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedReliabilityLogger.java
@@ -50,6 +50,29 @@ DiscoverLaunchResult.VOICE_SEARCH_TAPPED, /*userMightComeBack=*/true); } + /** + * Call this when the user has navigated to a webpage. If it was a card tap, instead use + * CARD_TAPPED. + */ + public void onPageLoadStarted() { + logLaunchFinishedIfInProgress( + DiscoverLaunchResult.NAVIGATED_AWAY_IN_APP, /*userMightComeBack=*/false); + } + + /** + * Call this when the user has pressed the back button and it will cause the feed to disappear. + */ + public void onNavigateBack() { + logLaunchFinishedIfInProgress( + DiscoverLaunchResult.NAVIGATED_BACK, /*userMightComeBack=*/false); + } + + /** Call this when the user selects a tab. */ + public void onSwitchTabs() { + logLaunchFinishedIfInProgress(DiscoverLaunchResult.NAVIGATED_TO_ANOTHER_TAB, + /*userMightComeBack=*/false); + } + // UrlFocusChangeListener @Override
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedReliabilityLoggerTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedReliabilityLoggerTest.java index 49f596e..75a75ee 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedReliabilityLoggerTest.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedReliabilityLoggerTest.java
@@ -105,4 +105,30 @@ mFeedReliabilityLogger.onUrlFocusChange(/*hasFocus=*/false); verify(mLaunchLogger, never()).cancelPendingFinished(); } + + @Test + public void testOnPageLoadStarted() { + when(mLaunchLogger.isLaunchInProgress()).thenReturn(true); + mFeedReliabilityLogger.onPageLoadStarted(); + verify(mLaunchLogger) + .logLaunchFinished( + anyLong(), eq(DiscoverLaunchResult.NAVIGATED_AWAY_IN_APP.getNumber())); + } + + @Test + public void testOnNavigateBack() { + when(mLaunchLogger.isLaunchInProgress()).thenReturn(true); + mFeedReliabilityLogger.onNavigateBack(); + verify(mLaunchLogger) + .logLaunchFinished(anyLong(), eq(DiscoverLaunchResult.NAVIGATED_BACK.getNumber())); + } + + @Test + public void testOnSwitchTabs() { + when(mLaunchLogger.isLaunchInProgress()).thenReturn(true); + mFeedReliabilityLogger.onSwitchTabs(); + verify(mLaunchLogger) + .logLaunchFinished( + anyLong(), eq(DiscoverLaunchResult.NAVIGATED_TO_ANOTHER_TAB.getNumber())); + } } \ No newline at end of file
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItem.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItem.java index 244771c..7f6cb3c 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItem.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItem.java
@@ -92,7 +92,7 @@ mFollowingChipView.getPrimaryTextView().setTextColor(textColor); mFollowChipView.getPrimaryTextView().setTextColor(textColor); final ColorStateList backgroundColor = AppCompatResources.getColorStateList( - mContext, R.color.menu_footer_chip_background); + mContext, R.color.menu_footer_chip_background_list); mFollowChipView.setBackgroundTintList(backgroundColor); } }
diff --git a/chrome/browser/feedback/show_feedback_page.cc b/chrome/browser/feedback/show_feedback_page.cc index 7d7a516..7cc5ab0b 100644 --- a/chrome/browser/feedback/show_feedback_page.cc +++ b/chrome/browser/feedback/show_feedback_page.cc
@@ -16,7 +16,9 @@ #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/ui_features.h" +#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/webui/feedback/feedback_dialog.h" +#include "chrome/browser/web_applications/system_web_apps/system_web_app_types.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" @@ -101,9 +103,6 @@ const std::string& description_placeholder_text, const std::string& category_tag, const std::string& extra_diagnostics) { - extensions::FeedbackPrivateAPI* api = - extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile); - feedback_private::FeedbackFlow flow = source == kFeedbackSourceSadTabPage ? feedback_private::FeedbackFlow::FEEDBACK_FLOW_SADTABCRASH @@ -111,22 +110,31 @@ bool include_bluetooth_logs = false; bool show_questionnaire = false; + bool use_os_feedback = false; #if BUILDFLAG(IS_CHROMEOS_ASH) if (IsGoogleInternalAccount(profile)) { flow = feedback_private::FeedbackFlow::FEEDBACK_FLOW_GOOGLEINTERNAL; include_bluetooth_logs = IsFromUserInteraction(source); show_questionnaire = IsFromUserInteraction(source); } + use_os_feedback = base::FeatureList::IsEnabled(ash::features::kOsFeedback); #endif - auto info = api->CreateFeedbackInfo( - description_template, description_placeholder_text, category_tag, - extra_diagnostics, page_url, flow, source == kFeedbackSourceAssistant, - include_bluetooth_logs, show_questionnaire, - source == kFeedbackSourceChromeLabs || - source == kFeedbackSourceKaleidoscope); + if (use_os_feedback) { + web_app::LaunchSystemWebAppAsync(profile, + web_app::SystemAppType::OS_FEEDBACK); + } else { + extensions::FeedbackPrivateAPI* api = + extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile); + auto info = api->CreateFeedbackInfo( + description_template, description_placeholder_text, category_tag, + extra_diagnostics, page_url, flow, source == kFeedbackSourceAssistant, + include_bluetooth_logs, show_questionnaire, + source == kFeedbackSourceChromeLabs || + source == kFeedbackSourceKaleidoscope); - FeedbackDialog::CreateOrShow(profile, *info); + FeedbackDialog::CreateOrShow(profile, *info); + } } #endif // !BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/feedback/show_feedback_page_browsertest.cc b/chrome/browser/feedback/show_feedback_page_browsertest.cc new file mode 100644 index 0000000..93497c5d --- /dev/null +++ b/chrome/browser/feedback/show_feedback_page_browsertest.cc
@@ -0,0 +1,91 @@ +// Copyright 2022 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 "ash/constants/ash_features.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" +#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" +#include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/prefs/testing_pref_service.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/test_navigation_observer.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace ash { + +class ShowFeedbackPageBrowserTest : public InProcessBrowserTest { + public: + ShowFeedbackPageBrowserTest() { + scope_feature_list_.InitAndEnableFeature(ash::features::kOsFeedback); + } + ~ShowFeedbackPageBrowserTest() override = default; + + protected: + base::test::ScopedFeatureList scope_feature_list_; +}; + +// Test that when the policy of UserFeedbackAllowed is false, feedback app is +// not opened. +IN_PROC_BROWSER_TEST_F(ShowFeedbackPageBrowserTest, UserFeedbackDisallowed) { + base::HistogramTester histogram_tester; + std::string unused; + chrome::ShowFeedbackPage(browser(), chrome::kFeedbackSourceBrowserCommand, + /*description_template=*/unused, + /*description_placeholder_text=*/unused, + /*category_tag=*/unused, + /*extra_diagnostics=*/unused); + histogram_tester.ExpectTotalCount("Feedback.RequestSource", 1); + browser()->profile()->GetPrefs()->SetBoolean(prefs::kUserFeedbackAllowed, + false); + chrome::ShowFeedbackPage(browser(), chrome::kFeedbackSourceBrowserCommand, + /*description_template=*/unused, + /*description_placeholder_text=*/unused, + /*category_tag=*/unused, + /*extra_diagnostics=*/unused); + histogram_tester.ExpectTotalCount("Feedback.RequestSource", 1); +} + +// Test that when the policy of UserFeedbackAllowed is true, feedback app is +// opened and the os_feedback is used when the feature kOsFeedback is enabled. +IN_PROC_BROWSER_TEST_F(ShowFeedbackPageBrowserTest, + OsFeedbackIsOpenedWhenFeatureEnabled) { + web_app::WebAppProvider::GetForTest(browser()->profile()) + ->system_web_app_manager() + .InstallSystemAppsForTesting(); + + base::HistogramTester histogram_tester; + EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); + + const GURL expected_url("chrome://os-feedback"); + content::TestNavigationObserver navigation_observer(expected_url); + navigation_observer.StartWatchingNewWebContents(); + + std::string unused; + browser()->profile()->GetPrefs()->SetBoolean(prefs::kUserFeedbackAllowed, + true); + chrome::ShowFeedbackPage(browser(), chrome::kFeedbackSourceBrowserCommand, + /*description_template=*/unused, + /*description_placeholder_text=*/unused, + /*category_tag=*/unused, + /*extra_diagnostics=*/unused); + navigation_observer.Wait(); + + histogram_tester.ExpectTotalCount("Feedback.RequestSource", 1); + EXPECT_EQ(2u, chrome::GetTotalBrowserCount()); + EXPECT_EQ(expected_url, chrome::FindLastActive() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetVisibleURL()); +} + +} // namespace ash
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 9b5808557..28c5fbe 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -109,6 +109,11 @@ "expiry_milestone": 110 }, { + "name": "allow-poly-device-pairing", + "owners": [ "cros-connectivity@google.com"], + "expiry_milestone": 110 + }, + { "name": "allow-repeated-updates", "owners": [ "vyshu", "chromeos-core-services@google.com" ], "expiry_milestone": 92
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 022aaa0..76bbd592 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -4066,6 +4066,11 @@ const char kAllowDisableTouchpadHapticFeedbackDescription[] = "Shows settings to adjust and disable touchpad haptic feedback."; +const char kAllowPolyDevicePairingName[] = + "Allow pairing of Bluetooth devices by Poly"; +const char kAllowPolyDevicePairingDescription[] = + "Shows Poly devices in the Bluetooth pairing UI."; + const char kAllowRepeatedUpdatesName[] = "Continue checking for updates before reboot and after initial update."; const char kAllowRepeatedUpdatesDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 9076c32..4dc5426 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2326,6 +2326,9 @@ extern const char kAllowDisableTouchpadHapticFeedbackName[]; extern const char kAllowDisableTouchpadHapticFeedbackDescription[]; +extern const char kAllowPolyDevicePairingName[]; +extern const char kAllowPolyDevicePairingDescription[]; + extern const char kAllowRepeatedUpdatesName[]; extern const char kAllowRepeatedUpdatesDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 45e96c3..af64cb2b 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -58,7 +58,7 @@ #include "components/signin/public/base/signin_switches.h" #include "components/subresource_filter/core/browser/subresource_filter_features.h" #include "components/sync/base/features.h" -#include "components/webapps/browser/android/features.h" +#include "components/webapps/browser/features.h" #include "content/public/common/content_features.h" #include "device/fido/features.h" #include "media/base/media_switches.h"
diff --git a/chrome/browser/installable/installable_manager_browsertest.cc b/chrome/browser/installable/installable_manager_browsertest.cc index e627e79..e42c1529 100644 --- a/chrome/browser/installable/installable_manager_browsertest.cc +++ b/chrome/browser/installable/installable_manager_browsertest.cc
@@ -158,7 +158,7 @@ splash_icon_ = std::make_unique<SkBitmap>(*data.splash_icon); has_maskable_splash_icon_ = data.has_maskable_splash_icon; valid_manifest_ = data.valid_manifest; - has_worker_ = data.has_worker; + worker_check_passed_ = data.worker_check_passed; base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure_); } @@ -175,7 +175,7 @@ bool has_maskable_splash_icon() const { return has_maskable_splash_icon_; } const SkBitmap* splash_icon() const { return splash_icon_.get(); } bool valid_manifest() const { return valid_manifest_; } - bool has_worker() const { return has_worker_; } + bool worker_check_passed() const { return worker_check_passed_; } private: base::RepeatingClosure quit_closure_; @@ -189,7 +189,7 @@ std::unique_ptr<SkBitmap> splash_icon_; bool has_maskable_splash_icon_; bool valid_manifest_; - bool has_worker_; + bool worker_check_passed_; }; class NestedCallbackTester { @@ -215,7 +215,7 @@ if (data.primary_icon) primary_icon_ = std::make_unique<SkBitmap>(*data.primary_icon); valid_manifest_ = data.valid_manifest; - has_worker_ = data.has_worker; + worker_check_passed_ = data.worker_check_passed; manager_->GetData( params_, base::BindOnce(&NestedCallbackTester::OnDidFinishSecondCheck, @@ -228,7 +228,7 @@ EXPECT_EQ(primary_icon_url_, data.primary_icon_url); EXPECT_EQ(primary_icon_.get(), data.primary_icon); EXPECT_EQ(valid_manifest_, data.valid_manifest); - EXPECT_EQ(has_worker_, data.has_worker); + EXPECT_EQ(worker_check_passed_, data.worker_check_passed); EXPECT_EQ(blink::IsEmptyManifest(*manifest_), blink::IsEmptyManifest(data.manifest)); EXPECT_EQ(manifest_->start_url, data.manifest.start_url); @@ -250,7 +250,7 @@ GURL primary_icon_url_; std::unique_ptr<SkBitmap> primary_icon_; bool valid_manifest_; - bool has_worker_; + bool worker_check_passed_; }; class InstallableManagerBrowserTest : public InProcessBrowserTest { @@ -388,15 +388,15 @@ void CheckServiceWorkerForTester(CallbackTester* tester) { if (is_service_worker_offline_supported_ || offline_capability_type_ == CheckOfflineCapabilityMode::NONE) { - EXPECT_TRUE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); } else if (offline_capability_type_ == CheckOfflineCapabilityMode::WARN_ONLY) { - EXPECT_TRUE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{WARN_NOT_OFFLINE_CAPABLE}, tester->errors()); } else { - EXPECT_FALSE(tester->has_worker()); + EXPECT_FALSE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{NOT_OFFLINE_CAPABLE}, tester->errors()); } @@ -509,7 +509,7 @@ EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->has_maskable_primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_FALSE(tester->has_maskable_splash_icon()); @@ -535,7 +535,7 @@ EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->has_maskable_primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_FALSE(tester->has_maskable_splash_icon()); @@ -560,7 +560,7 @@ EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->has_maskable_primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_FALSE(tester->has_maskable_splash_icon()); @@ -587,7 +587,7 @@ EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->has_maskable_primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_FALSE(tester->has_maskable_splash_icon()); @@ -615,7 +615,7 @@ EXPECT_TRUE(tester->primary_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{NO_ACCEPTABLE_ICON}, @@ -639,7 +639,7 @@ EXPECT_TRUE(tester->primary_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_FALSE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{NO_ACCEPTABLE_ICON}, @@ -666,7 +666,7 @@ EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); } } @@ -693,7 +693,7 @@ EXPECT_TRUE(tester->primary_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); @@ -716,7 +716,7 @@ EXPECT_TRUE(tester->primary_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{NO_ACCEPTABLE_ICON}, @@ -742,7 +742,7 @@ EXPECT_TRUE(tester->primary_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_FALSE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{NO_ACCEPTABLE_ICON}, @@ -770,7 +770,7 @@ EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_FALSE(tester->worker_check_passed()); EXPECT_EQ( std::vector<InstallableStatusCode>( {START_URL_NOT_VALID, MANIFEST_MISSING_NAME_OR_SHORT_NAME, @@ -797,7 +797,7 @@ EXPECT_FALSE(tester->primary_icon_url().is_empty()); EXPECT_NE(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); @@ -820,7 +820,7 @@ EXPECT_NE(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->has_maskable_primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_FALSE(tester->splash_icon_url().is_empty()); EXPECT_NE(nullptr, tester->splash_icon()); EXPECT_FALSE(tester->has_maskable_splash_icon()); @@ -848,7 +848,7 @@ EXPECT_TRUE(tester->has_maskable_splash_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); } } @@ -979,7 +979,7 @@ EXPECT_TRUE(tester->has_maskable_splash_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); } @@ -1009,7 +1009,7 @@ EXPECT_FALSE(tester->has_maskable_splash_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); } @@ -1038,7 +1038,7 @@ EXPECT_FALSE(tester->has_maskable_splash_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); } @@ -1068,7 +1068,7 @@ EXPECT_FALSE(tester->has_maskable_splash_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); } } @@ -1141,7 +1141,7 @@ EXPECT_TRUE(tester->primary_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_FALSE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{NO_MANIFEST}, tester->errors()); @@ -1166,7 +1166,7 @@ EXPECT_TRUE(tester->primary_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); @@ -1189,7 +1189,7 @@ EXPECT_FALSE(tester->primary_icon_url().is_empty()); EXPECT_NE(nullptr, tester->primary_icon()); EXPECT_TRUE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_FALSE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{NO_MATCHING_SERVICE_WORKER}, @@ -1256,7 +1256,7 @@ EXPECT_FALSE(nested_tester->primary_icon_url().is_empty()); EXPECT_NE(nullptr, nested_tester->primary_icon()); EXPECT_TRUE(nested_tester->valid_manifest()); - EXPECT_FALSE(nested_tester->has_worker()); + EXPECT_TRUE(nested_tester->worker_check_passed()); EXPECT_TRUE(nested_tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, nested_tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, nested_tester->errors()); @@ -1340,7 +1340,7 @@ EXPECT_FALSE(tester->primary_icon_url().is_empty()); EXPECT_NE(nullptr, tester->primary_icon()); EXPECT_TRUE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_FALSE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{NOT_OFFLINE_CAPABLE}, @@ -1375,7 +1375,7 @@ // We should have returned with an error. EXPECT_FALSE(blink::IsEmptyManifest(tester->manifest())); EXPECT_TRUE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_FALSE(tester->worker_check_passed()); EXPECT_EQ(std::vector<InstallableStatusCode>{NO_MATCHING_SERVICE_WORKER}, tester->errors()); } @@ -1429,7 +1429,7 @@ EXPECT_FALSE(tester->primary_icon_url().is_empty()); EXPECT_NE(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_FALSE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{NOT_OFFLINE_CAPABLE}, @@ -1480,7 +1480,7 @@ EXPECT_NE(nullptr, tester->primary_icon()); EXPECT_EQ(144, tester->primary_icon()->width()); EXPECT_TRUE(tester->valid_manifest()); - EXPECT_TRUE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); @@ -1505,7 +1505,7 @@ EXPECT_TRUE(tester->primary_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{NO_ICON_AVAILABLE}, @@ -1783,7 +1783,7 @@ EXPECT_FALSE(tester->has_maskable_primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_FALSE(tester->has_maskable_splash_icon()); @@ -1884,7 +1884,7 @@ EXPECT_FALSE(tester->primary_icon_url().is_empty()); EXPECT_NE(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_FALSE(tester->splash_icon_url().is_empty()); EXPECT_NE(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors()); @@ -1913,7 +1913,7 @@ EXPECT_NE(nullptr, tester->primary_icon()); EXPECT_TRUE(tester->has_maskable_primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_FALSE(tester->splash_icon_url().is_empty()); EXPECT_NE(nullptr, tester->splash_icon()); EXPECT_TRUE(tester->has_maskable_splash_icon()); @@ -1966,7 +1966,7 @@ EXPECT_EQ(nullptr, tester->primary_icon()); EXPECT_FALSE(tester->has_maskable_primary_icon()); EXPECT_FALSE(tester->valid_manifest()); - EXPECT_FALSE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_FALSE(tester->has_maskable_splash_icon()); @@ -2022,7 +2022,7 @@ EXPECT_NE(nullptr, tester->primary_icon()); EXPECT_EQ(144, tester->primary_icon()->width()); EXPECT_TRUE(tester->valid_manifest()); - EXPECT_TRUE(tester->has_worker()); + EXPECT_TRUE(tester->worker_check_passed()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); EXPECT_EQ(std::vector<InstallableStatusCode>{}, tester->errors());
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelper.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelper.java index a4d188c..f71c0e53 100644 --- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelper.java +++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupClientHelper.java
@@ -8,12 +8,25 @@ import com.google.common.base.Optional; import org.chromium.base.Callback; +import org.chromium.chrome.browser.password_manager.CredentialManagerLauncher.CredentialManagerError; /** * Interface for the helper responsible for Password Checkup operations. */ public interface PasswordCheckupClientHelper { /** + * Serves as a general exception for failed requests to the password checkup backend. + */ + class PasswordCheckBackendException extends Exception { + public @CredentialManagerError int errorCode; + + public PasswordCheckBackendException(String message, @CredentialManagerError int error) { + super(message); + errorCode = error; + } + } + + /** * Retrieves a pending intent that can be used to launch the Password Checkup UI in the * credential manager. The intent is to either be used immediately or discarded. * @@ -24,9 +37,10 @@ * @param failureCallback callback called if the retrieving failed with the encountered error. * The error should be a value from {@link CredentialManagerError}. */ - void getPasswordCheckupPendingIntent(@PasswordCheckReferrer int referrer, + @Deprecated + default void getPasswordCheckupPendingIntent(@PasswordCheckReferrer int referrer, Optional<String> accountName, Callback<PendingIntent> successCallback, - Callback<Integer> failureCallback); + Callback<Integer> failureCallback) {} /** * Asynchronously runs Password Checkup and stores the result in PasswordSpecifics then saves it @@ -39,8 +53,10 @@ * @param failureCallback callback called if encountered an error. * The error should be a value from {@link CredentialManagerError}. */ - void runPasswordCheckup(@PasswordCheckReferrer int referrer, Optional<String> accountName, - Callback<Void> successCallback, Callback<Integer> failureCallback); + @Deprecated + default void runPasswordCheckup(@PasswordCheckReferrer int referrer, + Optional<String> accountName, Callback<Void> successCallback, + Callback<Integer> failureCallback) {} /** * Asynchronously returns the number of breached credentials for the provided account. @@ -52,7 +68,49 @@ * @param failureCallback callback called if encountered an error. * The error should be a value from {@link CredentialManagerError}. */ - void getNumberOfBreachedCredentials(@PasswordCheckReferrer int referrer, + @Deprecated + default void getNumberOfBreachedCredentials(@PasswordCheckReferrer int referrer, Optional<String> accountName, Callback<Integer> successCallback, - Callback<Integer> failureCallback); + Callback<Integer> failureCallback) {} + + /** + * Retrieves a pending intent that can be used to launch the Password Checkup UI in the + * credential manager. The intent is to either be used immediately or discarded. + * + * @param referrer the place that will launch the password checkup UI + * @param accountName the account name that is syncing passwords. If no value was provided local + * account will be used. + * @param successCallback callback called with the intent if the retrieving was successful + * @param failureCallback callback called if the retrieving failed with the encountered error. + */ + default void getPasswordCheckupIntent(@PasswordCheckReferrer int referrer, + Optional<String> accountName, Callback<PendingIntent> successCallback, + Callback<Exception> failureCallback) {} + + /** + * Asynchronously runs Password Checkup and stores the result in PasswordSpecifics then saves it + * to the ChromeSync module. + * + * @param referrer the place that requested to start a check. + * @param accountName the account name that is syncing passwords. If no value was provided local + * account will be used. + * @param successCallback callback called with Password Check started successful + * @param failureCallback callback called if encountered an error. + */ + default void runPasswordCheckupInBackground(@PasswordCheckReferrer int referrer, + Optional<String> accountName, Callback<Void> successCallback, + Callback<Exception> failureCallback) {} + + /** + * Asynchronously returns the number of breached credentials for the provided account. + * + * @param referrer the place that requested number of breached credentials. + * @param accountName the account name that is syncing passwords. If no value was provided local + * account will be used. + * @param successCallback callback called with the number of breached passwords. + * @param failureCallback callback called if encountered an error. + */ + default void getBreachedCredentialsCount(@PasswordCheckReferrer int referrer, + Optional<String> accountName, Callback<Integer> successCallback, + Callback<Exception> failureCallback) {} }
diff --git a/chrome/browser/policy/client_data_delegate_desktop.cc b/chrome/browser/policy/client_data_delegate_desktop.cc index 4b34736..c8f06c0 100644 --- a/chrome/browser/policy/client_data_delegate_desktop.cc +++ b/chrome/browser/policy/client_data_delegate_desktop.cc
@@ -7,9 +7,7 @@ #include <utility> #include "base/callback.h" -#include "base/feature_list.h" #include "components/policy/core/common/cloud/cloud_policy_util.h" -#include "components/policy/core/common/features.h" #include "components/policy/proto/device_management_backend.pb.h" namespace policy { @@ -21,10 +19,8 @@ request->set_os_version(GetOSVersion()); request->set_machine_name(GetMachineName()); - if (base::FeatureList::IsEnabled(features::kUploadBrowserDeviceIdentifier)) { - request->set_allocated_browser_device_identifier( - GetBrowserDeviceIdentifier().release()); - } + request->set_allocated_browser_device_identifier( + GetBrowserDeviceIdentifier().release()); std::move(callback).Run(); }
diff --git a/chrome/browser/policy/client_data_delegate_desktop_unittest.cc b/chrome/browser/policy/client_data_delegate_desktop_unittest.cc index 5ae033a..a3fea26 100644 --- a/chrome/browser/policy/client_data_delegate_desktop_unittest.cc +++ b/chrome/browser/policy/client_data_delegate_desktop_unittest.cc
@@ -7,11 +7,9 @@ #include <memory> #include "base/callback_helpers.h" -#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "build/build_config.h" #include "components/policy/core/common/cloud/cloud_policy_util.h" -#include "components/policy/core/common/features.h" #include "components/policy/proto/device_management_backend.pb.h" #include "testing/gtest/include/gtest/gtest.h" @@ -28,8 +26,6 @@ #endif // BUILDFLAG(IS_WIN) base::test::TaskEnvironment task_environment; - base::test::ScopedFeatureList scoped_feature_list( - features::kUploadBrowserDeviceIdentifier); ClientDataDelegateDesktop client_data_delegate; enterprise_management::RegisterBrowserRequest request; @@ -45,25 +41,4 @@ expected_browser_device_identifier->serial_number()); } -TEST(ClientDataDelegateDesktopTest, - FillRegisterBrowserRequest_NoBrowserDeviceIdentifier) { -#if BUILDFLAG(IS_WIN) - base::win::ScopedCOMInitializer com_initializer; -#endif // BUILDFLAG(IS_WIN) - - base::test::TaskEnvironment task_environment; - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature( - features::kUploadBrowserDeviceIdentifier); - - ClientDataDelegateDesktop client_data_delegate; - enterprise_management::RegisterBrowserRequest request; - client_data_delegate.FillRegisterBrowserRequest(&request, base::DoNothing()); - task_environment.RunUntilIdle(); - - EXPECT_EQ(request.machine_name(), GetMachineName()); - EXPECT_TRUE(request.browser_device_identifier().computer_name().empty()); - EXPECT_TRUE(request.browser_device_identifier().serial_number().empty()); -} - } // namespace policy
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc index 0514ab3..800970f 100644 --- a/chrome/browser/printing/print_browsertest.cc +++ b/chrome/browser/printing/print_browsertest.cc
@@ -123,8 +123,8 @@ using OnDidShowErrorDialog = base::RepeatingCallback<void()>; using OnStopCallback = base::RepeatingCallback<void()>; -// Overriding callbacks for `TestPrintJobWorker` is broken into the following -// steps: +// Overriding callbacks for `TestPrintJobWorkerOop` is broken into the +// following steps: // 1. Error case processing. Call `error_check_callback` to reset any // triggers that were primed to cause errors in the testing context. // 2. Run the base class callback for normal handling. If there was an @@ -134,7 +134,7 @@ // `did_start_printing_callback` when in `OnDidStartPrinting()`) to note // the callback was observed and completed. This ensures all base class // processing was done before possibly quitting the test run loop. -struct TestPrintCallbacks { +struct TestPrintOopCallbacks { ErrorCheckCallback error_check_callback; OnDidUseDefaultSettingsCallback did_use_default_settings_callback; #if BUILDFLAG(IS_WIN) @@ -256,9 +256,7 @@ : PrintPreviewObserver(wait_for_loaded, /*pages_per_sheet=*/1) {} PrintPreviewObserver(bool wait_for_loaded, int pages_per_sheet) - : pages_per_sheet_(pages_per_sheet) { - if (wait_for_loaded) - queue_.emplace(); // DOMMessageQueue doesn't allow assignment + : pages_per_sheet_(pages_per_sheet), wait_for_loaded_(wait_for_loaded) { PrintPreviewUI::SetDelegateForTesting(this); } @@ -307,9 +305,11 @@ run_loop_->Quit(); preview_dialog_ = preview_dialog; - if (queue_.has_value()) { + if (wait_for_loaded_) { + // Instantiate |queue| to listen for messages in |preview_dialog_|. + queue_.emplace(preview_dialog_); content::ExecuteScriptAsync( - preview_dialog, + preview_dialog_.get(), "window.addEventListener('message', event => {" " if (event.data.type === 'documentLoaded') {" " domAutomationController.send(event.data.load_state);" @@ -328,6 +328,7 @@ uint32_t expected_rendered_page_count_ = 1; uint32_t rendered_page_count_ = 0; + const bool wait_for_loaded_ = false; raw_ptr<content::WebContents> preview_dialog_ = nullptr; base::RunLoop* run_loop_ = nullptr; }; @@ -1946,7 +1947,7 @@ ASSERT_TRUE(success); // Simulate a <shift-tab> press and wait for a focus message. - content::DOMMessageQueue msg_queue; + content::DOMMessageQueue msg_queue(preview_dialog); SimulateKeyPress(preview_dialog, ui::DomKey::TAB, ui::DomCode::TAB, ui::VKEY_TAB, false, true, false, false); std::string reply; @@ -2299,16 +2300,16 @@ #if !BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(ENABLE_OOP_PRINTING) -class TestPrintJobWorker : public PrintJobWorkerOop { +class TestPrintJobWorkerOop : public PrintJobWorkerOop { public: - TestPrintJobWorker(content::GlobalRenderFrameHostId rfh_id, - bool simulate_spooling_memory_errors, - TestPrintCallbacks* callbacks) + TestPrintJobWorkerOop(content::GlobalRenderFrameHostId rfh_id, + bool simulate_spooling_memory_errors, + TestPrintOopCallbacks* callbacks) : PrintJobWorkerOop(rfh_id, simulate_spooling_memory_errors), callbacks_(callbacks) {} - TestPrintJobWorker(const TestPrintJobWorker&) = delete; - TestPrintJobWorker& operator=(const TestPrintJobWorker&) = delete; - ~TestPrintJobWorker() override = default; + TestPrintJobWorkerOop(const TestPrintJobWorkerOop&) = delete; + TestPrintJobWorkerOop& operator=(const TestPrintJobWorkerOop&) = delete; + ~TestPrintJobWorkerOop() override = default; private: void OnDidUseDefaultSettings( @@ -2382,7 +2383,7 @@ callbacks_->did_stop_callback.Run(); } - raw_ptr<TestPrintCallbacks> callbacks_; + raw_ptr<TestPrintOopCallbacks> callbacks_; }; #endif // BUILDFLAG(ENABLE_OOP_PRINTING) @@ -2407,40 +2408,42 @@ // Safe to use `base::Unretained(this)` since this testing class // necessarily must outlive all interactions from the tests which will - // run through `TestPrintJobWorker`, the user of these callbacks. - test_print_callbacks_.error_check_callback = + // run through `TestPrintJobWorkerOop`, the user of these callbacks. + test_print_oop_callbacks_.error_check_callback = base::BindRepeating(&PrintBackendPrintBrowserTestBase::ErrorCheck, base::Unretained(this)); - test_print_callbacks_.did_use_default_settings_callback = + test_print_oop_callbacks_.did_use_default_settings_callback = base::BindRepeating( &PrintBackendPrintBrowserTestBase::OnDidUseDefaultSettings, base::Unretained(this)); #if BUILDFLAG(IS_WIN) - test_print_callbacks_.did_ask_user_for_settings_callback = + test_print_oop_callbacks_.did_ask_user_for_settings_callback = base::BindRepeating( &PrintBackendPrintBrowserTestBase::OnDidAskUserForSettings, base::Unretained(this)); #endif - test_print_callbacks_.did_start_printing_callback = base::BindRepeating( - &PrintBackendPrintBrowserTestBase::OnDidStartPrinting, - base::Unretained(this)); + test_print_oop_callbacks_.did_start_printing_callback = + base::BindRepeating( + &PrintBackendPrintBrowserTestBase::OnDidStartPrinting, + base::Unretained(this)); #if BUILDFLAG(IS_WIN) - test_print_callbacks_.did_render_printed_page_callback = + test_print_oop_callbacks_.did_render_printed_page_callback = base::BindRepeating( &PrintBackendPrintBrowserTestBase::OnDidRenderPrintedPage, base::Unretained(this)); #endif - test_print_callbacks_.did_render_printed_document_callback = + test_print_oop_callbacks_.did_render_printed_document_callback = base::BindRepeating( &PrintBackendPrintBrowserTestBase::OnDidRenderPrintedDocument, base::Unretained(this)); - test_print_callbacks_.did_document_done_callback = base::BindRepeating( - &PrintBackendPrintBrowserTestBase::OnDidDocumentDone, - base::Unretained(this)); - test_print_callbacks_.did_show_error_dialog = base::BindRepeating( + test_print_oop_callbacks_.did_document_done_callback = + base::BindRepeating( + &PrintBackendPrintBrowserTestBase::OnDidDocumentDone, + base::Unretained(this)); + test_print_oop_callbacks_.did_show_error_dialog = base::BindRepeating( &PrintBackendPrintBrowserTestBase::OnDidShowErrorDialog, base::Unretained(this)); - test_print_callbacks_.did_stop_callback = base::BindRepeating( + test_print_oop_callbacks_.did_stop_callback = base::BindRepeating( &PrintBackendPrintBrowserTestBase::OnDidStop, base::Unretained(this)); test_create_print_job_worker_callback_ = base::BindRepeating( &PrintBackendPrintBrowserTestBase::CreatePrintJobWorker, @@ -2706,8 +2709,8 @@ #if BUILDFLAG(ENABLE_OOP_PRINTING) std::unique_ptr<PrintJobWorker> CreatePrintJobWorker( content::GlobalRenderFrameHostId rfh_id) { - return std::make_unique<TestPrintJobWorker>( - rfh_id, simulate_spooling_memory_errors_, &test_print_callbacks_); + return std::make_unique<TestPrintJobWorkerOop>( + rfh_id, simulate_spooling_memory_errors_, &test_print_oop_callbacks_); } #endif // BUILDFLAG(ENABLE_OOP_PRINTING) @@ -2787,7 +2790,7 @@ TestPrintingContextDelegate test_printing_context_delegate_; PrintBackendPrintingContextFactoryForTest test_printing_context_factory_; #if BUILDFLAG(ENABLE_OOP_PRINTING) - TestPrintCallbacks test_print_callbacks_; + TestPrintOopCallbacks test_print_oop_callbacks_; CreatePrintJobWorkerCallback test_create_print_job_worker_callback_; bool simulate_spooling_memory_errors_ = false; mojo::Remote<mojom::PrintBackendService> test_remote_;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_captions_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_captions_background.js index b1cdd42..f08e22f2 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_captions_background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_captions_background.js
@@ -9,7 +9,167 @@ */ import {ChromeVoxPrefs} from '/chromevox/background/prefs.js'; -export const BrailleCaptionsBackground = {}; +export class BrailleCaptionsBackground { + /** + * @param {function()} stateCallback Called when the state of the captions + * feature changes. + */ + constructor(stateCallback) { + /** @private {function()} */ + this.stateCallback_ = stateCallback; + } + + /** + * Called once to initialize the class. + * @param {function()} stateCallback Called when the state of the captions + * feature changes. + */ + static init(stateCallback) { + BrailleCaptionsBackground.instance = + new BrailleCaptionsBackground(stateCallback); + } + + /** + * Returns whether the braille captions feature is enabled. + * @return {boolean} + */ + static isEnabled() { + return localStorage[BrailleCaptionsBackground.PREF_KEY] === String(true); + } + + /** + * @param {string} text Text of the shown braille. + * @param {ArrayBuffer} cells Braille cells shown on the display. + * @param {Array<number>} brailleToText Map of Braille letters to the first + * index of corresponding text letter. + * @param {{brailleOffset: number, textOffset: number}} offsetsForSlices + * Offsets to use for calculating indices. The element is the braille + * offset, the second is the text offset. + * @param {number} rows Number of rows to display. + * @param {number} columns Number of columns to display. + */ + static setContent( + text, cells, brailleToText, offsetsForSlices, rows, columns) { + // Convert the cells to Unicode braille pattern characters. + const byteBuf = new Uint8Array(cells); + let brailleChars = ''; + + for (let i = 0; i < byteBuf.length; ++i) { + brailleChars += String.fromCharCode( + BrailleCaptionsBackground.BRAILLE_UNICODE_BLOCK_START | byteBuf[i]); + } + const groups = BrailleCaptionsBackground.groupBrailleAndText( + brailleChars, text, brailleToText, offsetsForSlices); + const data = {groups, rows, cols: columns}; + (new PanelCommand(PanelCommandType.UPDATE_BRAILLE, data)).send(); + } + + /** + * @param {ArrayBuffer} cells Braille cells shown on the display. + * @param {number} rows Number of rows to display. + * @param {number} columns Number of columns to display. + */ + static setImageContent(cells, rows, columns) { + // Convert the cells to Unicode braille pattern characters. + const byteBuf = new Uint8Array(cells); + let brailleChars = ''; + + for (let i = 0; i < byteBuf.length; ++i) { + brailleChars += String.fromCharCode( + BrailleCaptionsBackground.BRAILLE_UNICODE_BLOCK_START | byteBuf[i]); + } + + const groups = [['Image', brailleChars]]; + const data = {groups, rows, cols: columns}; + (new PanelCommand(PanelCommandType.UPDATE_BRAILLE, data)).send(); + } + + /** + * @param {string} brailleChars Braille characters shown on the display. + * @param {string} text Text of the shown braille. + * @param {Array<number>} brailleToText Map of Braille cells to the first + * index of corresponding text letter. + * @param {{brailleOffset: number, textOffset: number}} offsets + * Offsets to use for calculating indices. The element is the braille + * offset, the second is the text offset. + * @return {Array} The groups of braille and texts to be displayed. + */ + static groupBrailleAndText(brailleChars, text, brailleToText, offsets) { + let brailleBuf = ''; + const groups = []; + let textIndex = 0; + const brailleOffset = offsets.brailleOffset; + const textOffset = offsets.textOffset; + const calculateTextIndex = index => + brailleToText[index + brailleOffset] - textOffset; + + for (let i = 0; i < brailleChars.length; ++i) { + const textSliceIndex = calculateTextIndex(i); + if (i !== 0 && textSliceIndex !== textIndex) { + groups.push( + [text.substr(textIndex, textSliceIndex - textIndex), brailleBuf]); + brailleBuf = ''; + textIndex = textSliceIndex; + } + brailleBuf += brailleChars.charAt(i); + } + + // Puts the rest of the text into the last group. + if (brailleBuf.length > 0 && text.charAt(textIndex) !== ' ') { + groups.push([text.substr(textIndex), brailleBuf]); + } + return groups; + } + + /** + * Sets whether the overlay should be active. + * @param {boolean} newValue The new value of the active flag. + */ + static setActive(newValue) { + const oldValue = BrailleCaptionsBackground.isEnabled(); + ChromeVoxPrefs.instance.setPref( + BrailleCaptionsBackground.PREF_KEY, String(newValue)); + if (oldValue !== newValue) { + BrailleCaptionsBackground.instance.callStateCallback_(); + const msg = newValue ? Msgs.getMsg('braille_captions_enabled') : + Msgs.getMsg('braille_captions_disabled'); + ChromeVox.tts.speak(msg, QueueMode.QUEUE); + ChromeVox.braille.write(NavBraille.fromText(msg)); + } + } + + /** + * Asynchronously returns a display state representing the state of the + * captions feature. This is used when no actual hardware display is + * connected. + * @return {!Promise<!BrailleDisplayState>} + */ + static async getVirtualDisplayState() { + return new Promise(async resolve => { + if (BrailleCaptionsBackground.isEnabled()) { + let items = await new Promise( + resolve => + chrome.storage.local.get({'virtualBrailleRows': 1}, resolve)); + const rows = items['virtualBrailleRows']; + items = await new Promise( + resolve => chrome.storage.local.get( + {'virtualBrailleColumns': 40}, resolve)); + const columns = items['virtualBrailleColumns']; + resolve( + {available: true, textRowCount: rows, textColumnCount: columns}); + } else { + resolve({available: false, textRowCount: 0, textColumnCount: 0}); + } + }); + } + + /** @private */ + callStateCallback_() { + if (this.stateCallback_) { + this.stateCallback_(); + } + } +} /** * Key set in local storage when this feature is enabled. @@ -17,7 +177,6 @@ */ BrailleCaptionsBackground.PREF_KEY = 'brailleCaptions'; - /** * Unicode block of braille pattern characters. A braille pattern is formed * from this value with the low order 8 bits set to the bits representing @@ -25,157 +184,3 @@ * @const */ BrailleCaptionsBackground.BRAILLE_UNICODE_BLOCK_START = 0x2800; - - -/** - * Called once to initialize the class. - * @param {function()} stateCallback Called when the state of the captions - * feature changes. - */ -BrailleCaptionsBackground.init = function(stateCallback) { - const self = BrailleCaptionsBackground; - /** - * @type {function()} - * @private - */ - self.stateCallback_ = stateCallback; -}; - - -/** - * Returns whether the braille captions feature is enabled. - * @return {boolean} - */ -BrailleCaptionsBackground.isEnabled = function() { - const self = BrailleCaptionsBackground; - return localStorage[self.PREF_KEY] === String(true); -}; - -/** - * @param {string} text Text of the shown braille. - * @param {ArrayBuffer} cells Braille cells shown on the display. - * @param {Array<number>} brailleToText Map of Braille letters to the first - * index of corresponding text letter. - * @param {{brailleOffset: number, textOffset: number}} offsetsForSlices - * Offsets to use for caculating indices. The element is the braille offset, - * the second is the text offset. - * @param {number} rows Number of rows to display. - * @param {number} columns Number of columns to display. - */ -BrailleCaptionsBackground.setContent = function( - text, cells, brailleToText, offsetsForSlices, rows, columns) { - const self = BrailleCaptionsBackground; - // Convert the cells to Unicode braille pattern characters. - const byteBuf = new Uint8Array(cells); - let brailleChars = ''; - - for (let i = 0; i < byteBuf.length; ++i) { - brailleChars += - String.fromCharCode(self.BRAILLE_UNICODE_BLOCK_START | byteBuf[i]); - } - const groups = BrailleCaptionsBackground.groupBrailleAndText( - brailleChars, text, brailleToText, offsetsForSlices); - const data = {groups, rows, cols: columns}; - (new PanelCommand(PanelCommandType.UPDATE_BRAILLE, data)).send(); -}; - -/** - * @param {ArrayBuffer} cells Braille cells shown on the display. - * @param {number} rows Number of rows to display. - * @param {number} columns Number of columns to display. - */ -BrailleCaptionsBackground.setImageContent = function(cells, rows, columns) { - const self = BrailleCaptionsBackground; - // Convert the cells to Unicode braille pattern characters. - const byteBuf = new Uint8Array(cells); - let brailleChars = ''; - - for (let i = 0; i < byteBuf.length; ++i) { - brailleChars += - String.fromCharCode(self.BRAILLE_UNICODE_BLOCK_START | byteBuf[i]); - } - - const groups = [['Image', brailleChars]]; - const data = {groups, rows, cols: columns}; - (new PanelCommand(PanelCommandType.UPDATE_BRAILLE, data)).send(); -}; - -/** - * @param {string} brailleChars Braille characters shown on the display. - * @param {string} text Text of the shown braille. - * @param {Array<number>} brailleToText Map of Braille cells to the first - * index of corresponding text letter. - * @param {{brailleOffset: number, textOffset: number}} offsets - * Offsets to use for caculating indices. The element is the braille offset, - * the second is the text offset. - * @return {Array} The groups of braille and texts to be displayed. - */ -BrailleCaptionsBackground.groupBrailleAndText = function( - brailleChars, text, brailleToText, offsets) { - let brailleBuf = ''; - const groups = []; - let textIndex = 0; - const brailleOffset = offsets.brailleOffset; - const textOffset = offsets.textOffset; - const calculateTextIndex = function(index) { - return brailleToText[index + brailleOffset] - textOffset; - }; - - for (let i = 0; i < brailleChars.length; ++i) { - const textSliceIndex = calculateTextIndex(i); - if (i !== 0 && textSliceIndex !== textIndex) { - groups.push( - [text.substr(textIndex, textSliceIndex - textIndex), brailleBuf]); - brailleBuf = ''; - textIndex = textSliceIndex; - } - brailleBuf += brailleChars.charAt(i); - } - - // Puts the rest of the text into the last group. - if (brailleBuf.length > 0 && text.charAt(textIndex) !== ' ') { - groups.push([text.substr(textIndex), brailleBuf]); - } - return groups; -}; - -/** - * Sets whether the overlay should be active. - * @param {boolean} newValue The new value of the active flag. - */ -BrailleCaptionsBackground.setActive = function(newValue) { - const self = BrailleCaptionsBackground; - const oldValue = self.isEnabled(); - ChromeVoxPrefs.instance.setPref(self.PREF_KEY, String(newValue)); - if (oldValue !== newValue) { - if (self.stateCallback_) { - self.stateCallback_(); - } - const msg = newValue ? Msgs.getMsg('braille_captions_enabled') : - Msgs.getMsg('braille_captions_disabled'); - ChromeVox.tts.speak(msg, QueueMode.QUEUE); - ChromeVox.braille.write(NavBraille.fromText(msg)); - } -}; - -/** - * Calls a callback on a display state representing the state of the captions - * feature. This is used when no actual hardware display is connected. - * @param {function(!BrailleDisplayState)} callback The callback to pass - * the display state into. - */ -BrailleCaptionsBackground.getVirtualDisplayState = function(callback) { - const self = BrailleCaptionsBackground; - if (self.isEnabled()) { - chrome.storage.local.get({'virtualBrailleRows': 1}, function(items) { - const rows = items['virtualBrailleRows']; - chrome.storage.local.get({'virtualBrailleColumns': 40}, function(items) { - const columns = items['virtualBrailleColumns']; - callback( - {available: true, textRowCount: rows, textColumnCount: columns}); - }); - }); - } else { - callback({available: false, textRowCount: 0, textColumnCount: 0}); - } -};
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_display_manager.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_display_manager.js index aa8f077..80e9fed 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_display_manager.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_display_manager.js
@@ -239,7 +239,8 @@ processDisplayState(newState); localStorage['menuBrailleCommands'] = true; } else { - BrailleCaptionsBackground.getVirtualDisplayState(processDisplayState); + BrailleCaptionsBackground.getVirtualDisplayState().then( + processDisplayState); localStorage['menuBrailleCommands'] = false; } }
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_button.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_button.html index bf8e74b..b8451fc 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_button.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_button.html
@@ -71,19 +71,15 @@ --paper-tooltip-delay-out: var(--emoji-tooltip-delay-out); --paper-tooltip-duration-in: 0; --paper-tooltip-duration-out: 0; + } - /* CSS mixin goes against style guide, but this is the only way to style - * the paper tooltip without changing the source code (which is in - * third_party) - */ - --paper-tooltip: { - box-shadow: var(--cr-elevation-1); - font-family: 'Roboto', sans-serif; - font-size: 12px; - margin: 4px; - padding: 4px 8px 4px 8px; - white-space: nowrap; - }; + #tooltip::part(tooltip) { + box-shadow: var(--cr-elevation-1); + font-family: 'Roboto', sans-serif; + font-size: 12px; + margin: 4px; + padding: 4px 8px 4px 8px; + white-space: nowrap; } </style>
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.html b/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.html index 5a13aaa..f17dc0ba8 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.html
@@ -118,19 +118,15 @@ --paper-tooltip-duration-out: 0; --paper-tooltip-opacity: 1; --paper-tooltip-text-color: var(--cros-tooltip-label-color); + } - /* CSS mixin goes against style guide, but this is the only way to style - * the paper tooltip without changing the source code (which is in - * third_party) - */ - --paper-tooltip: { - box-shadow: var(--cr-elevation-1); - font-family: 'Roboto', sans-serif; - font-size: 12px; - margin: 4px; - padding: 4px 8px 4px 8px; - white-space: nowrap; - }; + .tooltip::part(tooltip) { + box-shadow: var(--cr-elevation-1); + font-family: 'Roboto', sans-serif; + font-size: 12px; + margin: 4px; + padding: 4px 8px 4px 8px; + white-space: nowrap; } </style> @@ -165,4 +161,4 @@ [[emoticon.base.name]] </paper-tooltip> </template> -</div> \ No newline at end of file +</div>
diff --git a/chrome/browser/resources/pdf/controller.ts b/chrome/browser/resources/pdf/controller.ts index 5f22141bb..8fa5c823 100644 --- a/chrome/browser/resources/pdf/controller.ts +++ b/chrome/browser/resources/pdf/controller.ts
@@ -339,10 +339,10 @@ }); } - setReadOnly(enableReadOnly: boolean) { + setPresentationMode(enablePresentationMode: boolean) { this.postMessage_({ - type: 'setReadOnly', - enableReadOnly: enableReadOnly, + type: 'setPresentationMode', + enablePresentationMode, }); }
diff --git a/chrome/browser/resources/pdf/pdf_internal_plugin_wrapper.ts b/chrome/browser/resources/pdf/pdf_internal_plugin_wrapper.ts index 532bb089..8783601 100644 --- a/chrome/browser/resources/pdf/pdf_internal_plugin_wrapper.ts +++ b/chrome/browser/resources/pdf/pdf_internal_plugin_wrapper.ts
@@ -73,10 +73,8 @@ plugin.setAttribute('has-edits', ''); return; - case 'setReadOnly': - // TODO(crbug.com/702993): Rename the incoming message to reflect that - // this is only used by Presentation mode. - isPresentationMode = e.data.enableReadOnly; + case 'setPresentationMode': + isPresentationMode = e.data.enablePresentationMode; gestureDetector.setPresentationMode(isPresentationMode); if (isPresentationMode) {
diff --git a/chrome/browser/resources/pdf/pdf_viewer.ts b/chrome/browser/resources/pdf/pdf_viewer.ts index 27b9715..36696af 100644 --- a/chrome/browser/resources/pdf/pdf_viewer.ts +++ b/chrome/browser/resources/pdf/pdf_viewer.ts
@@ -514,14 +514,15 @@ // Switch viewport's wheel behavior. this.viewport.setPresentationMode(true); - // Restrict the content to read only (e.g. disable forms and links). - this.pluginController_!.setReadOnly(true); + // Set presentation mode, which restricts the content to read only + // (e.g. disable forms and links). + this.pluginController_!.setPresentationMode(true); // Revert back to the normal state when exiting Presentation mode. eventToPromise('fullscreenchange', scroller).then(() => { assert(document.fullscreenElement === null); this.viewport.setPresentationMode(false); - this.pluginController_!.setReadOnly(false); + this.pluginController_!.setPresentationMode(false); // Ensure that directional keys still work after exiting. this.shadowRoot!.querySelector('embed')!.focus();
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_data_usage_dialog.html b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_data_usage_dialog.html index 97d31ba4..f1a3b0b 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_data_usage_dialog.html +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_data_usage_dialog.html
@@ -35,9 +35,10 @@ --paper-tooltip-background: var(--cros-tooltip-background-color); --paper-tooltip-opacity: 1; --paper-tooltip-text-color: var(--cros-tooltip-label-color); - --paper-tooltip: { - margin-inline-end: 6px; - }; + } + + #dataUsageDataTooltip::part(tooltip) { + margin-inline-end: 6px; } #dataUsageDataTooltipText {
diff --git a/chrome/browser/resources/settings/privacy_sandbox/app.html b/chrome/browser/resources/settings/privacy_sandbox/app.html index fcc9b8e..e788e54d 100644 --- a/chrome/browser/resources/settings/privacy_sandbox/app.html +++ b/chrome/browser/resources/settings/privacy_sandbox/app.html
@@ -162,6 +162,16 @@ --paper-tooltip-duration-in: 300; --paper-tooltip-opacity: 1; } + + paper-tooltip::part(tooltip) { + border-radius: 4px; + box-shadow: var(--cr-elevation-2); + font-family: Roboto, Arial, sans-serif; + font-size: inherit; + font-weight: 400; + line-height: 154%; /* 20px. */ + margin: 0 4px; + } </style> <settings-prefs id="prefs" prefs="{{prefs}}"></settings-prefs> @@ -220,7 +230,7 @@ <template is="dom-if" if="[[!showFragment_(privacySandboxSettingsViewEnum_.MAIN, privacySandboxSettingsView_)]]" restamp> - <cr-dialog id="dialogWrapper" show-on-attach on-close="onDialogClose_"> + <cr-dialog id="dialogWrapper" show-on-attach> <template id="learnMoreDialog" is="dom-if" if="[[showFragment_( privacySandboxSettingsViewEnum_.LEARN_MORE_DIALOG,
diff --git a/chrome/browser/resources/settings/privacy_sandbox/app.ts b/chrome/browser/resources/settings/privacy_sandbox/app.ts index d49758b..b4f692d 100644 --- a/chrome/browser/resources/settings/privacy_sandbox/app.ts +++ b/chrome/browser/resources/settings/privacy_sandbox/app.ts
@@ -204,9 +204,6 @@ } private onDialogClose_() { - // This function will only be called once, regardless of how the dialog is - // shut (either via ESC or via the button), as in the latter the dialog is - // not "closed", but rather removed from the DOM. const lastView = this.privacySandboxSettingsView_; this.privacySandboxSettingsView_ = PrivacySandboxSettingsView.MAIN; afterNextRender(this, async () => { @@ -390,30 +387,6 @@ target.id === 'topicsTooltipIcon' ? '#topicsTooltip' : '#fledgeTooltip')!; - // Directly inject the required style into the stylesheets of the paper - // tooltip element. This is a workaround for CSS mixin properties seemingly - // being removed in optimized WebUI builds, and the paper-tooltip not - // supporting other styling methods. - // TODO(crbug.com/1308262): Expose required style hooks on paper-tooltip - const sheet = new CSSStyleSheet(); - sheet.replaceSync(` - #tooltip { - border-radius: 4px; - box-shadow: var(--cr-elevation-2); - font-family: Roboto, Arial, sans-serif; - font-size: inherit; - font-weight: 400; - line-height: 154%; /* 20px. */ - margin: 0 4px; - }`); - const elemStyleSheets = tooltip.shadowRoot!.adoptedStyleSheets; - - if (elemStyleSheets.length === 0 || - JSON.stringify(elemStyleSheets.slice(-1)[0]) !== - JSON.stringify(sheet)) { - tooltip.shadowRoot!.adoptedStyleSheets = [...elemStyleSheets, sheet]; - } - const hide = () => { tooltip.hide(); target.removeEventListener('mouseleave', hide);
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts index a3a9954c..dfb5bfd 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.ts +++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -144,6 +144,10 @@ return; } + // Remove all children from container. Use `replaceChildren` rather than + // setting `innerHTML = ''` in order to remove all listeners, too. + container.replaceChildren(); + // Construct a dom node corresponding to each ContentNode and append it to // container. This does not use polymer's templating abstraction, which // would create a shadow node element representing each ContentNode, because
diff --git a/chrome/browser/resources/tab_search/BUILD.gn b/chrome/browser/resources/tab_search/BUILD.gn index 0f23070..2737dc6 100644 --- a/chrome/browser/resources/tab_search/BUILD.gn +++ b/chrome/browser/resources/tab_search/BUILD.gn
@@ -6,7 +6,7 @@ import("//chrome/common/features.gni") import("//tools/grit/grit_rule.gni") import("//tools/grit/preprocess_if_expr.gni") -import("//tools/polymer/html_to_js.gni") +import("//tools/polymer/css_to_wrapper.gni") import("//tools/polymer/html_to_wrapper.gni") import("//tools/typescript/ts_library.gni") import("//ui/webui/resources/tools/generate_grd.gni") @@ -147,8 +147,8 @@ output_dir = "$root_gen_dir/chrome" } -html_to_js("css_wrapper_files") { - js_files = css_wrapper_files +css_to_wrapper("css_wrapper_files") { + in_files = css_files } html_to_wrapper("html_wrapper_files") {
diff --git a/chrome/browser/resources/tab_search/tab_group_color_helper.ts b/chrome/browser/resources/tab_search/tab_group_color_helper.ts index ad2c529..73ad770 100644 --- a/chrome/browser/resources/tab_search/tab_group_color_helper.ts +++ b/chrome/browser/resources/tab_search/tab_group_color_helper.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './tab_group_shared_vars.js'; +import './tab_group_shared_vars.css.js'; import {Color} from './tab_group_types.mojom-webui.js';
diff --git a/chrome/browser/resources/tab_search/tab_group_shared_vars.css b/chrome/browser/resources/tab_search/tab_group_shared_vars.css new file mode 100644 index 0000000..901176d --- /dev/null +++ b/chrome/browser/resources/tab_search/tab_group_shared_vars.css
@@ -0,0 +1,71 @@ +/* Copyright 2022 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. */ + +/* #css_wrapper_metadata_start + * #type=vars + * #css_wrapper_metadata_end */ + +/* + * TODO(romanarora): Move to cr_elements folder when another component needs + * to reference the file. + */ + +/* Matches colors specified in ThemeHelper::GetTabGroupColors. */ +html { + /* TODO(romanarora): Consider moving colors to shared_vars_css.html. Only + * adds colors not already present in shared_vars_css.html. + */ + --google-blue-300-rgb: 123, 170, 247; + --google-blue-300: rgb(var(--google-blue-300-rgb)); + --google-cyan-300-rgb: 120, 217, 236; /* #78d9ec */ + --google-cyan-300: rgb(var(--google-cyan-300-rgb)); + --google-cyan-900-rgb: 0, 123, 131; /* #007b83 */ + --google-cyan-900: rgb(var(--google-cyan-900-rgb)); + --google-green-300-rgb: 87, 187, 138; /* #57bb8a */ + --google-green-300: rgb(var(--google-green-300-rgb)); + --google-green-600-rgb: 30, 142, 62; /* #1e8e3e */ + --google-green-600: rgb(var(--google-green-600-rgb)); + --google-pink-300-rgb: 255, 139, 203; /* #ff8bcb */ + --google-pink-300: rgb(var(--google-pink-300-rgb)); + --google-pink-700-rgb: 208, 24, 132; /* #d01884 */ + --google-pink-700: rgb(var(--google-pink-700-rgb)); + --google-purple-200-rgb: 215, 174, 251; /* #d7aefb */ + --google-purple-200: rgb(var(--google-purple-200-rgb)); + --google-purple-600-rgb: 147, 52, 230; /* #9334e6 */ + --google-purple-600: rgb(var(--google-purple-600-rgb)); + --google-red-300-rgb: 230, 124, 115; /* #e67c73 */ + --google-red-300: rgb(var(--google-red-300-rgb)); + --google-yellow-300-rgb: 247, 203, 77; /* #f7cb4d */ + --google-yellow-300: rgb(var(--google-yellow-300-rgb)); + --google-yellow-900-rgb: 227, 116, 0; /* #e37400 */ + --google-yellow-900: rgb(var(--google-yellow-900-rgb)); + --google-orange-300-rgb: 252, 173, 112; /* #fcad70 */ + --google-orange-300: rgb(var(--google-orange-300-rgb)); + --google-orange-400-rgb: 250, 144, 62; /* #fa903e */ + --google-orange-400: rgb(var(--google-orange-400-rgb)); + + --tab-group-color-grey: var(--google-grey-700); + --tab-group-color-blue: var(--google-blue-600); + --tab-group-color-red: var(--google-red-600); + --tab-group-color-yellow: var(--google-yellow-900); + --tab-group-color-green: var(--google-green-600); + --tab-group-color-pink: var(--google-pink-700); + --tab-group-color-purple: var(--google-purple-600); + --tab-group-color-cyan: var(--google-cyan-900); + --tab-group-color-orange: var(--google-orange-400); +} + +@media (prefers-color-scheme: dark) { + html { + --tab-group-color-grey: var(--google-grey-400); + --tab-group-color-blue: var(--google-blue-300); + --tab-group-color-red: var(--google-red-300); + --tab-group-color-yellow: var(--google-yellow-300); + --tab-group-color-green: var(--google-green-300); + --tab-group-color-pink: var(--google-pink-300); + --tab-group-color-purple: var(--google-purple-200); + --tab-group-color-cyan: var(--google-cyan-300); + --tab-group-color-orange: var(--google-orange-300); + } +}
diff --git a/chrome/browser/resources/tab_search/tab_group_shared_vars.html b/chrome/browser/resources/tab_search/tab_group_shared_vars.html deleted file mode 100644 index b1577120..0000000 --- a/chrome/browser/resources/tab_search/tab_group_shared_vars.html +++ /dev/null
@@ -1,67 +0,0 @@ -<custom-style> - <style> - /* - * TODO(romanarora): Move to cr_elements folder when another component needs - * to reference the file. - */ - - /* Matches colors specified in ThemeHelper::GetTabGroupColors. */ - html { - /* TODO(romanarora): Consider moving colors to shared_vars_css.html. Only - * adds colors not already present in shared_vars_css.html. - */ - --google-blue-300-rgb: 123, 170, 247; - --google-blue-300: rgb(var(--google-blue-300-rgb)); - --google-cyan-300-rgb: 120, 217, 236; /* #78d9ec */ - --google-cyan-300: rgb(var(--google-cyan-300-rgb)); - --google-cyan-900-rgb: 0, 123, 131; /* #007b83 */ - --google-cyan-900: rgb(var(--google-cyan-900-rgb)); - --google-green-300-rgb: 87, 187, 138; /* #57bb8a */ - --google-green-300: rgb(var(--google-green-300-rgb)); - --google-green-600-rgb: 30, 142, 62; /* #1e8e3e */ - --google-green-600: rgb(var(--google-green-600-rgb)); - --google-pink-300-rgb: 255, 139, 203; /* #ff8bcb */ - --google-pink-300: rgb(var(--google-pink-300-rgb)); - --google-pink-700-rgb: 208, 24, 132; /* #d01884 */ - --google-pink-700: rgb(var(--google-pink-700-rgb)); - --google-purple-200-rgb: 215, 174, 251; /* #d7aefb */ - --google-purple-200: rgb(var(--google-purple-200-rgb)); - --google-purple-600-rgb: 147, 52, 230; /* #9334e6 */ - --google-purple-600: rgb(var(--google-purple-600-rgb)); - --google-red-300-rgb: 230, 124, 115; /* #e67c73 */ - --google-red-300: rgb(var(--google-red-300-rgb)); - --google-yellow-300-rgb: 247, 203, 77; /* #f7cb4d */ - --google-yellow-300: rgb(var(--google-yellow-300-rgb)); - --google-yellow-900-rgb: 227, 116, 0; /* #e37400 */ - --google-yellow-900: rgb(var(--google-yellow-900-rgb)); - --google-orange-300-rgb: 252, 173, 112; /* #fcad70 */ - --google-orange-300: rgb(var(--google-orange-300-rgb)); - --google-orange-400-rgb: 250, 144, 62; /* #fa903e */ - --google-orange-400: rgb(var(--google-orange-400-rgb)); - - --tab-group-color-grey: var(--google-grey-700); - --tab-group-color-blue: var(--google-blue-600); - --tab-group-color-red: var(--google-red-600); - --tab-group-color-yellow: var(--google-yellow-900); - --tab-group-color-green: var(--google-green-600); - --tab-group-color-pink: var(--google-pink-700); - --tab-group-color-purple: var(--google-purple-600); - --tab-group-color-cyan: var(--google-cyan-900); - --tab-group-color-orange: var(--google-orange-400); - } - - @media (prefers-color-scheme: dark) { - html { - --tab-group-color-grey: var(--google-grey-400); - --tab-group-color-blue: var(--google-blue-300); - --tab-group-color-red: var(--google-red-300); - --tab-group-color-yellow: var(--google-yellow-300); - --tab-group-color-green: var(--google-green-300); - --tab-group-color-pink: var(--google-pink-300); - --tab-group-color-purple: var(--google-purple-200); - --tab-group-color-cyan: var(--google-cyan-300); - --tab-group-color-orange: var(--google-orange-300); - } - } - </style> -</custom-style>
diff --git a/chrome/browser/resources/tab_search/tab_group_shared_vars.ts b/chrome/browser/resources/tab_search/tab_group_shared_vars.ts deleted file mode 100644 index 2bd30f5..0000000 --- a/chrome/browser/resources/tab_search/tab_group_shared_vars.ts +++ /dev/null
@@ -1,7 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -const $_documentContainer = document.createElement('template'); -$_documentContainer.innerHTML = `{__html_template__}`; -document.head.appendChild($_documentContainer.content);
diff --git a/chrome/browser/resources/tab_search/tab_search.gni b/chrome/browser/resources/tab_search/tab_search.gni index 059b3d6..38ca6e86 100644 --- a/chrome/browser/resources/tab_search/tab_search.gni +++ b/chrome/browser/resources/tab_search/tab_search.gni
@@ -34,7 +34,14 @@ "title_item.ts", ] + web_component_files -css_wrapper_files = [ "tab_group_shared_vars.ts" ] +# Files that are passed as input to css_to_wrapper(). +css_files = [ "tab_group_shared_vars.css" ] + +# Files that are generated by css_to_wrapper(). +css_wrapper_files = [] +foreach(f, css_files) { + css_wrapper_files += [ f + ".ts" ] +} mojo_js_files = [ "tab_group_types.mojom-webui.js",
diff --git a/chrome/browser/selection/android/BUILD.gn b/chrome/browser/selection/android/BUILD.gn new file mode 100644 index 0000000..c58c0d3 --- /dev/null +++ b/chrome/browser/selection/android/BUILD.gn
@@ -0,0 +1,17 @@ +# Copyright 2022 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("java") { + sources = [ "java/src/org/chromium/chrome/browser/selection/SelectionPopupBackPressHandler.java" ] + + deps = [ + "//base:base_java", + "//chrome/browser/tab:java", + "//chrome/browser/tabmodel:java", + "//components/browser_ui/widget/android:java", + "//content/public/android:content_full_java", + ] +}
diff --git a/chrome/browser/selection/android/OWNERS b/chrome/browser/selection/android/OWNERS new file mode 100644 index 0000000..e2dd518f --- /dev/null +++ b/chrome/browser/selection/android/OWNERS
@@ -0,0 +1 @@ +file://content/public/android/OWNERS
diff --git a/chrome/browser/selection/android/java/src/org/chromium/chrome/browser/selection/SelectionPopupBackPressHandler.java b/chrome/browser/selection/android/java/src/org/chromium/chrome/browser/selection/SelectionPopupBackPressHandler.java new file mode 100644 index 0000000..f7a186e5 --- /dev/null +++ b/chrome/browser/selection/android/java/src/org/chromium/chrome/browser/selection/SelectionPopupBackPressHandler.java
@@ -0,0 +1,83 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.selection; + +import org.chromium.base.Callback; +import org.chromium.base.lifetime.Destroyable; +import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.chrome.browser.tab.EmptyTabObserver; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.components.browser_ui.widget.gesture.BackPressHandler; +import org.chromium.content_public.browser.SelectionPopupController; + +/** + * {@link BackPressHandler} of {@link SelectionPopupController}. This listens to the change of tab + * model and notifies whether the current selection popup controller is going to intercept the + * back press. + */ +public class SelectionPopupBackPressHandler + extends EmptyTabObserver implements BackPressHandler, TabModelObserver, Destroyable { + private final ObservableSupplierImpl<Boolean> mBackPressChangedSupplier = + new ObservableSupplierImpl<>(); + private final Callback<Boolean> mCallback = this::onActionBarShowingChanged; + + private SelectionPopupController mPopupController; + private Tab mTab; + + /** + * @param tabModelSelector A {@link TabModelSelector} which can provide + * {@link org.chromium.chrome.browser.tabmodel.TabModelFilterProvider}. + */ + public SelectionPopupBackPressHandler(TabModelSelector tabModelSelector) { + tabModelSelector.getTabModelFilterProvider().addTabModelFilterObserver(this); + } + + @Override + public void handleBackPress() { + assert mPopupController != null; + mPopupController.clearSelection(); + } + + @Override + public ObservableSupplier<Boolean> getHandleBackPressChangedSupplier() { + return mBackPressChangedSupplier; + } + + @Override + public void didSelectTab(Tab tab, int type, int lastId) { + mBackPressChangedSupplier.set(false); + if (mPopupController != null) { + mPopupController.isSelectActionBarShowingSupplier().removeObserver(mCallback); + } + if (tab.getWebContents() == null) return; + if (mTab != null) tab.removeObserver(this); + tab.addObserver(this); + mTab = tab; + mPopupController = SelectionPopupController.fromWebContents(tab.getWebContents()); + mPopupController.isSelectActionBarShowingSupplier().addObserver(mCallback); + } + + @Override + public void onWebContentsSwapped(Tab tab, boolean didStartLoad, boolean didFinishLoad) { + mPopupController.isSelectActionBarShowingSupplier().removeObserver(mCallback); + mPopupController = SelectionPopupController.fromWebContents(tab.getWebContents()); + mPopupController.isSelectActionBarShowingSupplier().addObserver(mCallback); + } + + @Override + public void destroy() { + if (mTab != null) mTab.removeObserver(this); + mTab = null; + mPopupController.isSelectActionBarShowingSupplier().removeObserver(mCallback); + mPopupController = null; + } + + private void onActionBarShowingChanged(boolean isShowing) { + mBackPressChangedSupplier.set(isShowing); + } +}
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowIphController.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowIphController.java index 99e41185..cdcfda4f 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowIphController.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/crow/CrowIphController.java
@@ -10,6 +10,7 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.R; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.CurrentTabObserver; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -23,10 +24,12 @@ * Controls when the the Share Experiment IPH is shown. */ public class CrowIphController { - // TODO(crbug/1314455): Adjust these numbers. - private static final int MIN_DAYS = 1; - private static final int MIN_VISITS = 1; - private static final int NUM_HISTORY_DAYS = 7; + private static final int DEFAULT_MIN_DAYS_VISITED = 3; + private static final int DEFAULT_MIN_TOTAL_VISITS = 3; + private static final int DEFAULT_NUM_HISTORY_LOOKBACK_DAYS = 5; + private static final String MIN_DAYS_VISITED_PARAM = "min-days-visited"; + private static final String MIN_TOTAL_VISITS_PARAM = "min-total-visits"; + private static final String NUM_HISTORY_LOOKBACK_DAYS_PARAM = "num-history-lookback-days"; private final Activity mActivity; private final AppMenuHandler mAppMenuHandler; @@ -35,6 +38,10 @@ private final UserEducationHelper mUserEducationHelper; private final View mMenuButtonAnchorView; + private final int mMinDaysVisited; + private final int mMinTotalVisits; + private final int mNumHistoryLookbackDays; + /** * Constructs a {@link CrowIphController}. * @@ -53,6 +60,16 @@ mMenuButtonAnchorView = menuButtonAnchorView; mUserEducationHelper = new UserEducationHelper(activity, new Handler()); + mMinDaysVisited = ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.SHARE_CROW_BUTTON, MIN_DAYS_VISITED_PARAM, + DEFAULT_MIN_DAYS_VISITED); + mMinTotalVisits = ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.SHARE_CROW_BUTTON, MIN_TOTAL_VISITS_PARAM, + DEFAULT_MIN_TOTAL_VISITS); + mNumHistoryLookbackDays = ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.SHARE_CROW_BUTTON, NUM_HISTORY_LOOKBACK_DAYS_PARAM, + DEFAULT_NUM_HISTORY_LOOKBACK_DAYS); + mPageLoadObserver = new CurrentTabObserver(tabSupplier, new EmptyTabObserver() { @Override public void onPageLoadFinished(Tab tab, GURL url) { @@ -69,8 +86,8 @@ } private void maybeShowCrowIph(GURL url) { - CrowBridge.getVisitCountsToHost(url, NUM_HISTORY_DAYS, result -> { - if (result.dailyVisits >= MIN_DAYS && result.visits >= MIN_VISITS) { + CrowBridge.getVisitCountsToHost(url, mNumHistoryLookbackDays, result -> { + if (result.dailyVisits >= mMinDaysVisited && result.visits >= mMinTotalVisits) { requestShowCrowIph(); } });
diff --git a/chrome/browser/touch_to_fill/android/internal/java/res/layout/touch_to_fill_header_item_modern.xml b/chrome/browser/touch_to_fill/android/internal/java/res/layout/touch_to_fill_header_item_modern.xml index 23ef1e8..591361e 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/res/layout/touch_to_fill_header_item_modern.xml +++ b/chrome/browser/touch_to_fill/android/internal/java/res/layout/touch_to_fill_header_item_modern.xml
@@ -22,14 +22,14 @@ android:layout_marginBottom="8dp" android:importantForAccessibility="no" /> - <org.chromium.ui.widget.TextViewWithLeading + <androidx.appcompat.widget.DialogTitle android:id="@+id/touch_to_fill_sheet_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:paddingTop="10dp" android:paddingBottom="10dp" - android:textAppearance="@style/TextAppearance.Headline.Primary" /> + android:textAppearance="@style/TextAppearance.AlertDialogTitleStyle" /> <org.chromium.ui.widget.TextViewWithLeading android:id="@+id/touch_to_fill_sheet_subtitle"
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 25d4bb8..87a0e51 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -140,6 +140,8 @@ "passwords/password_generation_popup_controller_impl.h", "passwords/password_generation_popup_observer.h", "passwords/password_generation_popup_view.h", + "passwords/password_manager_navigation_throttle.cc", + "passwords/password_manager_navigation_throttle.h", "passwords/settings/password_manager_porter.cc", "passwords/settings/password_manager_porter.h", "passwords/settings/password_manager_presenter.cc", @@ -1323,8 +1325,6 @@ "tabs/saved_tab_groups/saved_tab_group.h", "tabs/saved_tab_groups/saved_tab_group_keyed_service.cc", "tabs/saved_tab_groups/saved_tab_group_keyed_service.h", - "tabs/saved_tab_groups/saved_tab_group_menu.cc", - "tabs/saved_tab_groups/saved_tab_group_menu.h", "tabs/saved_tab_groups/saved_tab_group_model.cc", "tabs/saved_tab_groups/saved_tab_group_model.h", "tabs/saved_tab_groups/saved_tab_group_model_listener.cc",
diff --git a/chrome/browser/ui/android/autofill/save_card_message_confirm_controller.cc b/chrome/browser/ui/android/autofill/save_card_message_confirm_controller.cc index 98f0363c3..580c976e 100644 --- a/chrome/browser/ui/android/autofill/save_card_message_confirm_controller.cc +++ b/chrome/browser/ui/android/autofill/save_card_message_confirm_controller.cc
@@ -42,7 +42,8 @@ } void SaveCardMessageConfirmController::ConfirmSaveCard( - const std::u16string& card_label) { + const std::u16string& card_label, + const std::u16string& cardholder_account) { if (!GetOrCreateJavaObject()) return; JNIEnv* env = base::android::AttachCurrentThread(); @@ -51,6 +52,7 @@ base::android::ConvertUTF16ToJavaString( env, l10n_util::GetStringUTF16(GetSaveCardDialogTitleId())), base::android::ConvertUTF16ToJavaString(env, card_label), + base::android::ConvertUTF16ToJavaString(env, cardholder_account), base::android::ConvertUTF16ToJavaString( env, l10n_util::GetStringUTF16( IDS_AUTOFILL_FIX_FLOW_PROMPT_SAVE_CARD_LABEL))); @@ -58,7 +60,8 @@ void SaveCardMessageConfirmController::FixName( const std::u16string& inferred_cardholder_name, - const std::u16string& card_label) { + const std::u16string& card_label, + const std::u16string& cardholder_account) { if (!GetOrCreateJavaObject()) return; JNIEnv* env = base::android::AttachCurrentThread(); @@ -69,13 +72,15 @@ env, l10n_util::GetStringUTF16(GetSaveCardDialogTitleId())), base::android::ConvertUTF16ToJavaString(env, inferred_cardholder_name), base::android::ConvertUTF16ToJavaString(env, card_label), + base::android::ConvertUTF16ToJavaString(env, cardholder_account), base::android::ConvertUTF16ToJavaString( env, l10n_util::GetStringUTF16( IDS_AUTOFILL_FIX_FLOW_PROMPT_SAVE_CARD_LABEL))); } void SaveCardMessageConfirmController::FixDate( - const std::u16string& card_label) { + const std::u16string& card_label, + const std::u16string& cardholder_account) { if (!GetOrCreateJavaObject()) return; JNIEnv* env = base::android::AttachCurrentThread(); @@ -84,6 +89,7 @@ base::android::ConvertUTF16ToJavaString( env, l10n_util::GetStringUTF16(GetSaveCardDialogTitleId())), base::android::ConvertUTF16ToJavaString(env, card_label), + base::android::ConvertUTF16ToJavaString(env, cardholder_account), base::android::ConvertUTF16ToJavaString( env, l10n_util::GetStringUTF16( IDS_AUTOFILL_FIX_FLOW_PROMPT_SAVE_CARD_LABEL)));
diff --git a/chrome/browser/ui/android/autofill/save_card_message_confirm_controller.h b/chrome/browser/ui/android/autofill/save_card_message_confirm_controller.h index 114f486..7bc64ec 100644 --- a/chrome/browser/ui/android/autofill/save_card_message_confirm_controller.h +++ b/chrome/browser/ui/android/autofill/save_card_message_confirm_controller.h
@@ -31,10 +31,13 @@ SaveCardMessageConfirmController& operator=( const SaveCardMessageConfirmController&) = delete; - void ConfirmSaveCard(const std::u16string& card_label); + void ConfirmSaveCard(const std::u16string& card_label, + const std::u16string& cardholder_account); void FixName(const std::u16string& inferred_cardholder_name, - const std::u16string& card_label); - void FixDate(const std::u16string& card_label); + const std::u16string& card_label, + const std::u16string& cardholder_account); + void FixDate(const std::u16string& card_label, + const std::u16string& cardholder_account); // Legal Message should be added before `ConfirmSaveCard`, `FixName` // and `FixDate` is called.
diff --git a/chrome/browser/ui/android/autofill/save_card_message_confirm_delegate.h b/chrome/browser/ui/android/autofill/save_card_message_confirm_delegate.h index 955e187..b6a584a 100644 --- a/chrome/browser/ui/android/autofill/save_card_message_confirm_delegate.h +++ b/chrome/browser/ui/android/autofill/save_card_message_confirm_delegate.h
@@ -29,7 +29,7 @@ virtual void DialogDismissed(JNIEnv* env) = 0; - virtual void OnLegalMessageLinkClicked( + virtual void OnLinkClicked( JNIEnv* env, const base::android::JavaParamRef<jstring>& url) = 0; };
diff --git a/chrome/browser/ui/android/autofill/save_card_message_controller_android.cc b/chrome/browser/ui/android/autofill/save_card_message_controller_android.cc index 1fc0020..560f079f 100644 --- a/chrome/browser/ui/android/autofill/save_card_message_controller_android.cc +++ b/chrome/browser/ui/android/autofill/save_card_message_controller_android.cc
@@ -44,6 +44,7 @@ const CreditCard& card, const LegalMessageLines& legal_message_lines, std::u16string inferred_name, + std::u16string cardholder_account, AutofillClient::UploadSaveCardPromptCallback upload_save_card_prompt_callback, AutofillClient::LocalSaveCardPromptCallback @@ -56,6 +57,7 @@ web_contents_ = web_contents; options_ = options; inferred_name_ = inferred_name; + cardholder_account_ = cardholder_account; upload_save_card_prompt_callback_ = std::move(upload_save_card_prompt_callback); @@ -198,18 +200,20 @@ void SaveCardMessageControllerAndroid::FixName( const std::u16string& inferred_cardholder_name) { - save_card_message_confirm_controller_->FixName(inferred_cardholder_name, - card_label_); + save_card_message_confirm_controller_->FixName( + inferred_cardholder_name, card_label_, cardholder_account_); is_name_confirmed_for_testing_ = true; } void SaveCardMessageControllerAndroid::FixDate() { - save_card_message_confirm_controller_->FixDate(card_label_); + save_card_message_confirm_controller_->FixDate(card_label_, + cardholder_account_); is_date_confirmed_for_testing_ = true; } void SaveCardMessageControllerAndroid::ConfirmSaveCard() { - save_card_message_confirm_controller_->ConfirmSaveCard(card_label_); + save_card_message_confirm_controller_->ConfirmSaveCard(card_label_, + cardholder_account_); is_save_card_confirmed_for_testing_ = true; } @@ -250,7 +254,7 @@ ResetInternal(); } -void SaveCardMessageControllerAndroid::OnLegalMessageLinkClicked( +void SaveCardMessageControllerAndroid::OnLinkClicked( JNIEnv* env, const base::android::JavaParamRef<jstring>& url) { reprompt_required_ = true;
diff --git a/chrome/browser/ui/android/autofill/save_card_message_controller_android.h b/chrome/browser/ui/android/autofill/save_card_message_controller_android.h index 932c28d..fd376f2 100644 --- a/chrome/browser/ui/android/autofill/save_card_message_controller_android.h +++ b/chrome/browser/ui/android/autofill/save_card_message_controller_android.h
@@ -42,6 +42,7 @@ const CreditCard& card, const LegalMessageLines& legal_message_lines, std::u16string inferred_name, + std::u16string cardholder_account, AutofillClient::UploadSaveCardPromptCallback upload_save_card_prompt_callback, AutofillClient::LocalSaveCardPromptCallback @@ -73,9 +74,8 @@ const base::android::JavaParamRef<jstring>& year) override; void OnSaveCardConfirmed(JNIEnv* env) override; void DialogDismissed(JNIEnv* env) override; - void OnLegalMessageLinkClicked( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& url) override; + void OnLinkClicked(JNIEnv* env, + const base::android::JavaParamRef<jstring>& url) override; bool IsGooglePayBrandingEnabled() const; @@ -122,6 +122,7 @@ save_card_message_confirm_controller_; std::u16string inferred_name_; + std::u16string cardholder_account_; std::u16string card_label_; // Whether we need to request users to fill in more info.
diff --git a/chrome/browser/ui/android/autofill/save_card_message_controller_android_unittest.cc b/chrome/browser/ui/android/autofill/save_card_message_controller_android_unittest.cc index 2fab8a6..fa652c2 100644 --- a/chrome/browser/ui/android/autofill/save_card_message_controller_android_unittest.cc +++ b/chrome/browser/ui/android/autofill/save_card_message_controller_android_unittest.cc
@@ -97,9 +97,9 @@ controller_.DialogDismissed(env); } - void OnLegalMessageLinkClicked() { + void OnLinkClicked() { JNIEnv* env = base::android::AttachCurrentThread(); - controller_.OnLegalMessageLinkClicked( + controller_.OnLinkClicked( env, base::android::JavaParamRef<jstring>( env, base::android::ConvertUTF16ToJavaString(env, u"").obj())); } @@ -147,7 +147,7 @@ AutofillClient::SaveCreditCardOptions options) { EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage); EXPECT_EQ(nullptr, GetMessageWrapper()); - controller_.Show(web_contents(), options, CreditCard(), {}, u"", + controller_.Show(web_contents(), options, CreditCard(), {}, u"", u"", std::move(upload_save_card_prompt_callback), std::move(local_save_card_prompt_callback)); } @@ -160,7 +160,7 @@ EXPECT_NE(nullptr, GetMessageWrapper()); EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage); controller_.Show(web_contents(), AutofillClient::SaveCreditCardOptions(), - CreditCard(), {}, u"", + CreditCard(), {}, u"", u"", std::move(upload_save_card_prompt_callback), std::move(local_save_card_prompt_callback)); } @@ -548,7 +548,7 @@ // Triggering dialog will dismiss the message. DismissMessage(messages::DismissReason::PRIMARY_ACTION); - OnLegalMessageLinkClicked(); + OnLinkClicked(); EXPECT_TRUE(IsRestoreRequired()); OnWebContentsFocused(); OnDateConfirmed();
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate.cc b/chrome/browser/ui/app_list/app_list_controller_delegate.cc index fced15c..98d761c 100644 --- a/chrome/browser/ui/app_list/app_list_controller_delegate.cc +++ b/chrome/browser/ui/app_list/app_list_controller_delegate.cc
@@ -11,6 +11,7 @@ #include "build/build_config.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/apps/app_service/extension_apps_utils.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/install_tracker_factory.h" #include "chrome/browser/extensions/launch_util.h" @@ -67,7 +68,7 @@ ash::settings::AppManagementEntryPoint:: kAppListContextMenuAppInfoWebApp); } else { - chrome::ShowAppManagementPage(profile, app_id, + chrome::ShowAppManagementPage(profile, GetEscapedAppId(app_id, app_type), ash::settings::AppManagementEntryPoint:: kAppListContextMenuAppInfoChromeApp); }
diff --git a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc index 3baf4f6..2d0d87b 100644 --- a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc +++ b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc
@@ -414,7 +414,7 @@ chrome::ShowFeedbackPage( /*browser=*/nullptr, chrome::kFeedbackSourceDesksTemplates, /*description_template=*/ - "#DesksTemplates\n\nProblem Template(s): \nProblem App(s): ", + "#SavedDesks", /*description_placeholder_text=*/std::string(), /*category_tag=*/std::string(), extra_diagnostics); }
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc index 2b9fc8a..072095bb 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
@@ -28,7 +28,6 @@ #include "base/debug/dump_without_crashing.h" #include "base/feature_list.h" #include "base/metrics/histogram_macros.h" -#include "base/strings/escape.h" #include "base/strings/pattern.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -38,6 +37,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/apps/app_service/extension_apps_utils.h" #include "chrome/browser/apps/icon_standardizer.h" #include "chrome/browser/ash/arc/arc_util.h" #include "chrome/browser/ash/crosapi/browser_util.h" @@ -851,13 +851,8 @@ profile, app_id, ash::settings::AppManagementEntryPoint::kShelfContextMenuAppInfoWebApp); } else { - // Normally app ids would only contain alphanumerics, but standalone - // browser extension app uses '#' as a delimiter. - std::string escaped_id = - app_type == apps::AppType::kStandaloneBrowserChromeApp - ? base::EscapeAllExceptUnreserved(app_id) - : app_id; - chrome::ShowAppManagementPage(profile, escaped_id, + chrome::ShowAppManagementPage(profile, + apps::GetEscapedAppId(app_id, app_type), ash::settings::AppManagementEntryPoint:: kShelfContextMenuAppInfoChromeApp); }
diff --git a/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_context_menu.cc b/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_context_menu.cc index dd9fcf7..3fd16df 100644 --- a/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_context_menu.cc +++ b/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_context_menu.cc
@@ -10,11 +10,11 @@ #include "ash/public/cpp/app_menu_constants.h" #include "ash/public/cpp/shelf_model.h" #include "ash/public/cpp/shelf_types.h" -#include "base/strings/escape.h" #include "base/task/sequenced_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/apps/app_service/extension_apps_utils.h" #include "chrome/browser/ash/accessibility/accessibility_manager.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" @@ -25,6 +25,7 @@ #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/webui/settings/ash/app_management/app_management_uma.h" #include "chrome/grit/generated_resources.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "ui/base/models/image_model.h" #include "ui/gfx/vector_icon_types.h" #include "ui/views/vector_icons.h" @@ -109,12 +110,11 @@ kShelfContextMenuAppInfoChromeApp : ash::settings::AppManagementEntryPoint:: kAppListContextMenuAppInfoChromeApp; - - // Normally app ids would only contain alphanumerics, but Lacros uses '#' - // as a delimiter. - std::string escaped_id = base::EscapeAllExceptUnreserved(app_id_); - chrome::ShowAppManagementPage(ProfileManager::GetPrimaryUserProfile(), - escaped_id, entry); + chrome::ShowAppManagementPage( + ProfileManager::GetPrimaryUserProfile(), + apps::GetEscapedAppId(app_id_, + apps::AppType::kStandaloneBrowserChromeApp), + entry); return; } default:
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index e147a40..91207603 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -542,7 +542,7 @@ if (messages::IsSaveCardMessagesUiEnabled()) { save_card_message_controller_android_.Show( web_contents(), options, card, /*legal_message_lines=*/{}, - GetAccountHolderName(), + GetAccountHolderName(), GetAccountHolderEmail(), /*upload_save_card_callback=*/{}, /*local_save_card_callback=*/std::move(callback)); return; @@ -571,12 +571,12 @@ #if BUILDFLAG(IS_ANDROID) DCHECK(options.show_prompt); if (messages::IsSaveCardMessagesUiEnabled()) { - save_card_message_controller_android_.Show(web_contents(), options, card, - legal_message_lines, - GetAccountHolderName(), - /*upload_save_card_callback=*/ - std::move(callback), - /*local_save_card_callback=*/{}); + save_card_message_controller_android_.Show( + web_contents(), options, card, legal_message_lines, + GetAccountHolderName(), GetAccountHolderEmail(), + /*upload_save_card_callback=*/ + std::move(callback), + /*local_save_card_callback=*/{}); return; } @@ -1055,6 +1055,19 @@ return base::UTF8ToUTF16(primary_account_info.full_name); } +std::u16string ChromeAutofillClient::GetAccountHolderEmail() { + Profile* profile = GetProfile(); + if (!profile) + return std::u16string(); + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile); + if (!identity_manager) + return std::u16string(); + AccountInfo primary_account_info = identity_manager->FindExtendedAccountInfo( + identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSync)); + return base::UTF8ToUTF16(primary_account_info.email); +} + WEB_CONTENTS_USER_DATA_KEY_IMPL(ChromeAutofillClient); } // namespace autofill
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index e5a8ee8..757ed60 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -233,6 +233,7 @@ Profile* GetProfile() const; bool IsMultipleAccountUser(); std::u16string GetAccountHolderName(); + std::u16string GetAccountHolderEmail(); std::unique_ptr<payments::PaymentsClient> payments_client_; std::unique_ptr<FormDataImporter> form_data_importer_;
diff --git a/chrome/browser/ui/passwords/password_manager_navigation_throttle.cc b/chrome/browser/ui/passwords/password_manager_navigation_throttle.cc new file mode 100644 index 0000000..1e51bd2 --- /dev/null +++ b/chrome/browser/ui/passwords/password_manager_navigation_throttle.cc
@@ -0,0 +1,113 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/passwords/password_manager_navigation_throttle.h" + +#include "base/logging.h" +#include "chrome/browser/password_manager/affiliation_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/url_constants.h" +#include "chrome/common/webui_url_constants.h" +#include "components/password_manager/core/common/password_manager_features.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/page_navigator.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_user_data.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "ui/base/page_transition_types.h" +#include "url/gurl.h" +#include "url/origin.h" + +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/password_manager/android/password_manager_launcher_android.h" +#endif + +namespace { + +using content::NavigationHandle; +using content::NavigationThrottle; +using content::WebContents; + +constexpr char kManageMyPasswordsURL[] = "https://passwords.google.com/native"; +constexpr char kReferrerURL[] = "https://passwords.google/"; +#if !BUILDFLAG(IS_ANDROID) +constexpr char kChromeUIPasswordsURL[] = "chrome:/settings/passwords"; +#endif + +bool IsTriggeredOnGoogleOwnedUI(NavigationHandle* handle) { + // Only cover cases when the user clicked on a link. + if (!ui::PageTransitionCoreTypeIs(handle->GetPageTransition(), + ui::PAGE_TRANSITION_LINK)) + return false; + + // Referrer origin and target URL must match. + url::Origin origin = handle->GetInitiatorOrigin().value_or(url::Origin()); + if (origin != url::Origin::Create(GURL(kReferrerURL)) || + handle->GetURL() != GURL(kManageMyPasswordsURL)) + return false; + +#if BUILDFLAG(IS_ANDROID) + return password_manager::features::UsesUnifiedPasswordManagerUi(); +#else + return base::FeatureList::IsEnabled( + password_manager::features::kUnifiedPasswordManagerDesktop); +#endif +} + +} // namespace + +PasswordManagerNavigationThrottle::PasswordManagerNavigationThrottle( + NavigationHandle* handle) + : NavigationThrottle(handle) {} + +PasswordManagerNavigationThrottle::~PasswordManagerNavigationThrottle() = + default; + +// static +std::unique_ptr<PasswordManagerNavigationThrottle> +PasswordManagerNavigationThrottle::MaybeCreateThrottleFor( + NavigationHandle* handle) { + // Don't handle navigations in subframes or main frames that are in a nested + // frame tree (e.g. portals, fenced frames) + if (!handle->GetParentFrameOrOuterDocument() && + IsTriggeredOnGoogleOwnedUI(handle)) { + return std::make_unique<PasswordManagerNavigationThrottle>(handle); + } + + return nullptr; +} + +NavigationThrottle::ThrottleCheckResult +PasswordManagerNavigationThrottle::WillStartRequest() { + WebContents* web_contents = navigation_handle()->GetWebContents(); + if (!web_contents) + return NavigationThrottle::PROCEED; + +#if BUILDFLAG(IS_ANDROID) + password_manager_launcher::ShowPasswordSettings( + web_contents, password_manager::ManagePasswordsReferrer::kChromeSettings); +#else + content::OpenURLParams params = + content::OpenURLParams::FromNavigationHandle(navigation_handle()); + params.url = GURL(kChromeUIPasswordsURL); + params.transition = ui::PAGE_TRANSITION_CLIENT_REDIRECT; + + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce( + [](base::WeakPtr<content::WebContents> web_contents, + const content::OpenURLParams& params) { + if (!web_contents) + return; + web_contents->OpenURL(params); + }, + web_contents->GetWeakPtr(), std::move(params))); +#endif + return NavigationThrottle::CANCEL_AND_IGNORE; +} + +const char* PasswordManagerNavigationThrottle::GetNameForLogging() { + return "PasswordManagerNavigationThrottle"; +}
diff --git a/chrome/browser/ui/passwords/password_manager_navigation_throttle.h b/chrome/browser/ui/passwords/password_manager_navigation_throttle.h new file mode 100644 index 0000000..ae2e3e3 --- /dev/null +++ b/chrome/browser/ui/passwords/password_manager_navigation_throttle.h
@@ -0,0 +1,26 @@ +// Copyright 2022 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_PASSWORDS_PASSWORD_MANAGER_NAVIGATION_THROTTLE_H_ +#define CHROME_BROWSER_UI_PASSWORDS_PASSWORD_MANAGER_NAVIGATION_THROTTLE_H_ + +#include "content/public/browser/navigation_throttle.h" + +// This NavigationThrottle redirects to Passwords in Settings when a target +// and referrer matches defined requirements. +class PasswordManagerNavigationThrottle : public content::NavigationThrottle { + public: + explicit PasswordManagerNavigationThrottle(content::NavigationHandle* handle); + + ~PasswordManagerNavigationThrottle() override; + + static std::unique_ptr<PasswordManagerNavigationThrottle> + MaybeCreateThrottleFor(content::NavigationHandle* handle); + + private: + ThrottleCheckResult WillStartRequest() override; + const char* GetNameForLogging() override; +}; + +#endif // CHROME_BROWSER_UI_PASSWORDS_PASSWORD_MANAGER_NAVIGATION_THROTTLE_H_
diff --git a/chrome/browser/ui/passwords/password_manager_navigation_throttle_unittest.cc b/chrome/browser/ui/passwords/password_manager_navigation_throttle_unittest.cc new file mode 100644 index 0000000..a4cb16e --- /dev/null +++ b/chrome/browser/ui/passwords/password_manager_navigation_throttle_unittest.cc
@@ -0,0 +1,108 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#include "chrome/browser/ui/passwords/password_manager_navigation_throttle.h" + +#include "base/memory/raw_ptr.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "components/password_manager/core/common/password_manager_features.h" +#include "components/variations/scoped_variations_ids_provider.h" +#include "content/public/browser/navigation_throttle.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/test/mock_navigation_handle.h" +#include "content/public/test/navigation_simulator.h" +#include "content/public/test/test_renderer_host.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/features.h" +#include "ui/base/page_transition_types.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace { + +constexpr char kManageMyPasswordsURL[] = "https://passwords.google.com/native"; +constexpr char kReferrerURL[] = "https://passwords.google/"; + +// An option struct to simplify setting up a specific navigation throttle. +struct NavigationThrottleOptions { + GURL url; + raw_ptr<content::RenderFrameHost> rfh = nullptr; + ui::PageTransition page_transition = ui::PAGE_TRANSITION_FROM_API; + absl::optional<url::Origin> initiator_origin; +}; + +} // namespace + +class PasswordManagerNavigationThrottleTest + : public ChromeRenderViewHostTestHarness { + public: + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); + content::RenderFrameHostTester::For(main_rfh()) + ->InitializeRenderFrameIfNeeded(); + subframe_ = content::RenderFrameHostTester::For(main_rfh()) + ->AppendChild("subframe"); +#if BUILDFLAG(IS_ANDROID) + feature_list_.InitAndEnableFeature( + password_manager::features::kUnifiedPasswordManagerAndroid); +#else + feature_list_.InitAndEnableFeature( + password_manager::features::kUnifiedPasswordManagerDesktop); +#endif + } + + content::RenderFrameHost* subframe() const { return subframe_; } + + std::unique_ptr<PasswordManagerNavigationThrottle> CreateNavigationThrottle( + NavigationThrottleOptions opts) { + content::MockNavigationHandle handle( + opts.url, opts.rfh ? opts.rfh.get() : main_rfh()); + handle.set_page_transition(opts.page_transition); + if (opts.initiator_origin) + handle.set_initiator_origin(*opts.initiator_origin); + return PasswordManagerNavigationThrottle::MaybeCreateThrottleFor(&handle); + } + + private: + base::test::ScopedFeatureList feature_list_; + variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{ + variations::VariationsIdsProvider::Mode::kUseSignedInState}; + raw_ptr<content::RenderFrameHost> subframe_ = nullptr; +}; + +TEST_F(PasswordManagerNavigationThrottleTest, CreatesNavigationThrottle) { + EXPECT_TRUE(CreateNavigationThrottle({ + .url = GURL(kManageMyPasswordsURL), + .page_transition = ui::PAGE_TRANSITION_LINK, + .initiator_origin = url::Origin::Create(GURL(kReferrerURL)), + })); +} + +TEST_F(PasswordManagerNavigationThrottleTest, + DoesntCreateNavigationThrottleWhenOriginDoesntMatch) { + EXPECT_FALSE(CreateNavigationThrottle({ + .url = GURL(kManageMyPasswordsURL), + .page_transition = ui::PAGE_TRANSITION_LINK, + .initiator_origin = url::Origin::Create(GURL("https://example.com/")), + })); +} + +TEST_F(PasswordManagerNavigationThrottleTest, + DoesntCreateNavigationThrottleWhenURLDoesntMatch) { + EXPECT_FALSE(CreateNavigationThrottle({ + .url = GURL("https://passwords.google.com/help"), + .page_transition = ui::PAGE_TRANSITION_LINK, + .initiator_origin = url::Origin::Create(GURL(kReferrerURL)), + })); +} + +TEST_F(PasswordManagerNavigationThrottleTest, + DoesntCreateNavigationThrottleWhenNotLinkTransition) { + EXPECT_FALSE(CreateNavigationThrottle({ + .url = GURL(kManageMyPasswordsURL), + .page_transition = ui::PAGE_TRANSITION_AUTO_BOOKMARK, + .initiator_origin = url::Origin::Create(GURL(kReferrerURL)), + })); +}
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu.cc deleted file mode 100644 index ba1c2b2..0000000 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu.cc +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu.h" - -#include <algorithm> -#include <vector> - -#include "base/bind.h" -#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group.h" -#include "content/public/browser/web_contents.h" -#include "ui/base/models/image_model.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/views/controls/button/menu_button.h" -#include "ui/views/controls/menu/menu_runner.h" -#include "ui/views/controls/menu/menu_types.h" -#include "ui/views/view.h" -#include "url/gurl.h" - -SavedTabGroupMenu::~SavedTabGroupMenu() = default; - -SavedTabGroupMenu::SavedTabGroupMenu(const SavedTabGroup* saved_group) - : ui::SimpleMenuModel(this), saved_group_(saved_group) {} - -void SavedTabGroupMenu::BuildMenu() { - int i = 0; - auto add_item_with_icon = [&](const SavedTabGroupTab& saved_tab) { - AddItemWithIcon(i++, saved_tab.tab_title, - ui::ImageModel::FromImage(saved_tab.favicon)); - }; - - std::for_each(saved_group_->saved_tabs.begin(), - saved_group_->saved_tabs.end(), add_item_with_icon); -} - -void SavedTabGroupMenu::RunMenu(views::Widget* parent, - views::MenuButtonController* button_controller, - const gfx::Rect& bounds, - OpenUrlCallback open_url) { - DCHECK(parent); - DCHECK(button_controller); - - open_url_ = std::move(open_url); - - // Instead of building the menu on construction, we can build each saved tab - // groups context menu when we need it. - BuildMenu(); - - context_menu_runner_ = std::make_unique<views::MenuRunner>( - this, views::MenuRunner::HAS_MNEMONICS); - context_menu_runner_->RunMenuAt(parent, button_controller, bounds, - views::MenuAnchorPosition::kTopLeft, - ui::MENU_SOURCE_NONE); -} - -bool SavedTabGroupMenu::IsCommandIdEnabled(int command_id) const { - int num_items = static_cast<int>(saved_group_->saved_tabs.size()); - DCHECK(command_id >= 0 && command_id < num_items); - return true; -} - -void SavedTabGroupMenu::ExecuteCommand(int command_id, int event_flags) { - DCHECK(IsCommandIdEnabled(command_id)); - - const GURL& url_to_open = saved_group_->saved_tabs[command_id].url; - content::OpenURLParams params(url_to_open, content::Referrer(), - WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui::PAGE_TRANSITION_AUTO_BOOKMARK, - false /* is_renderer_intiated */, - true /* started_from_context_menu */); - std::move(open_url_).Run(params); -}
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu.h deleted file mode 100644 index 7821015..0000000 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2022 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_TABS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_MENU_H_ -#define CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_MENU_H_ - -#include <memory> - -#include "base/callback_forward.h" -#include "content/public/browser/web_contents.h" -#include "ui/base/models/simple_menu_model.h" -#include "ui/views/controls/menu/menu_runner.h" -#include "ui/views/controls/menu/menu_types.h" - -class MenuButtonController; -class Widget; -struct SavedTabGroup; - -// Builds the context menu for a saved tab group. The context menu consists of -// the favicon and tab title for each tab found in a saved tab group. -class SavedTabGroupMenu : public ui::SimpleMenuModel, - public ui::SimpleMenuModel::Delegate { - public: - using OpenUrlCallback = - base::OnceCallback<void(const content::OpenURLParams&)>; - - // This SavedTabGroup is owned by the button which holds this context menu. - explicit SavedTabGroupMenu(const SavedTabGroup* saved_group); - SavedTabGroupMenu(const SavedTabGroupMenu&) = delete; - SavedTabGroupMenu& operator=(const SavedTabGroupMenu&) = delete; - ~SavedTabGroupMenu() override; - - // Displays the context menu for a saved tab group. - void RunMenu(views::Widget* parent, - views::MenuButtonController* button_controller, - const gfx::Rect& bounds, - OpenUrlCallback open_url); - - // ui::SimpleMenuModel::Delegate: - bool IsCommandIdEnabled(int command_id) const override; - void ExecuteCommand(int command_id, int event_flags) override; - - private: - // Builds the context menu for 'saved_group'. - void BuildMenu(); - - std::unique_ptr<views::MenuRunner> context_menu_runner_; - const SavedTabGroup* saved_group_; - OpenUrlCallback open_url_; -}; - -#endif // CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_MENU_H_
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu_unittest.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu_unittest.cc deleted file mode 100644 index 1c63360..0000000 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu_unittest.cc +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_menu.h" - -#include <memory> -#include <string> -#include <vector> - -#include "base/bind.h" -#include "chrome/browser/favicon/favicon_utils.h" -#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group.h" -#include "chrome/test/views/chrome_views_test_base.h" -#include "components/tab_groups/tab_group_color.h" -#include "components/tab_groups/tab_group_id.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/models/button_menu_item_model.h" -#include "ui/gfx/image/image.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/controls/button/menu_button.h" -#include "url/gurl.h" - -namespace { -void test_callback(const content::OpenURLParams& params) {} -} // anonymous namespace - -class TestMenuButton : public views::MenuButton { - public: - TestMenuButton() = default; - TestMenuButton(const TestMenuButton&) = delete; - TestMenuButton& operator=(const TestMenuButton&) = delete; - - private: - void ButtonPressed(const ui::Event& event) { return; } -}; - -// Serves to test the functions in SavedTabGroupMenu. -class SavedTabGroupMenuTest : public ChromeViewsTestBase { - protected: - SavedTabGroupMenuTest() = default; - - void SetUp() override { - ChromeViewsTestBase::SetUp(); - test_menu_button_ = std::make_unique<TestMenuButton>(); - test_saved_tab_group_ = std::make_unique<SavedTabGroup>( - SavedTabGroup(tab_groups::TabGroupId::GenerateNew(), u"Group Title", - tab_groups::TabGroupColorId::kGreen, - {CreateSavedTabGroupTab("Test_Link", u"Test Tab", - favicon::GetDefaultFavicon())})); - saved_tab_group_menu_ = - std::make_unique<SavedTabGroupMenu>(test_saved_tab_group_.get()); - saved_tab_group_menu_->RunMenu(CreateTestWidget().get(), - button_controller(), gfx::Rect(), - base::BindOnce(test_callback)); - - ASSERT_EQ(test_saved_tab_group_->saved_tabs.size(), - static_cast<size_t>(saved_tab_group_menu_->GetItemCount())); - } - - void TearDown() override { - ChromeViewsTestBase::TearDown(); - test_saved_tab_group_.reset(); - saved_tab_group_menu_.reset(); - } - - SavedTabGroupTab CreateSavedTabGroupTab(const std::string& url, - const std::u16string& tab_title, - const gfx::Image& favicon) { - return SavedTabGroupTab(GURL(url), tab_title, favicon); - } - - void TestWithMultipleTabs() { - test_saved_tab_group_.reset(); - saved_tab_group_menu_.reset(); - test_saved_tab_group_ = std::make_unique<SavedTabGroup>( - SavedTabGroup(tab_groups::TabGroupId::GenerateNew(), u"Group Title", - tab_groups::TabGroupColorId::kGreen, - {CreateSavedTabGroupTab("1_link", u"First Tab", - favicon::GetDefaultFavicon()), - CreateSavedTabGroupTab("2_link", u"Second Tab", - favicon::GetDefaultFavicon()), - CreateSavedTabGroupTab("3_link", u"Third Tab", - favicon::GetDefaultFavicon())})); - saved_tab_group_menu_ = - std::make_unique<SavedTabGroupMenu>(test_saved_tab_group_.get()); - saved_tab_group_menu_->RunMenu(CreateTestWidget().get(), - button_controller(), gfx::Rect(), - base::BindOnce(test_callback)); - } - - views::MenuButtonController* button_controller() { - return test_menu_button_->button_controller(); - } - - std::unique_ptr<SavedTabGroupMenu> saved_tab_group_menu_; - std::unique_ptr<SavedTabGroup> test_saved_tab_group_; - std::unique_ptr<TestMenuButton> test_menu_button_; -}; - -// Verifies that each item in our menu holds the correct information. -TEST_F(SavedTabGroupMenuTest, MenuItemHoldsCorrectInformation) { - EXPECT_EQ(test_saved_tab_group_->saved_tabs[0].tab_title, - saved_tab_group_menu_->GetLabelAt(0)); - EXPECT_EQ( - ui::ImageModel::FromImage(test_saved_tab_group_->saved_tabs[0].favicon), - saved_tab_group_menu_->GetIconAt(0)); - - TestWithMultipleTabs(); - for (size_t i = 0; i < test_saved_tab_group_->saved_tabs.size(); i++) { - EXPECT_EQ(test_saved_tab_group_->saved_tabs[i].tab_title, - saved_tab_group_menu_->GetLabelAt(i)); - EXPECT_EQ( - ui::ImageModel::FromImage(test_saved_tab_group_->saved_tabs[i].favicon), - saved_tab_group_menu_->GetIconAt(i)); - } -} - -// Verifies that the items in our menu corresponds to the correct command_id. -TEST_F(SavedTabGroupMenuTest, MenuItemsHoldCorrectCommandIds) { - int command_id = saved_tab_group_menu_->GetCommandIdAt(0); - EXPECT_EQ(0, command_id); - EXPECT_TRUE(saved_tab_group_menu_->IsCommandIdEnabled(command_id)); - - TestWithMultipleTabs(); - for (size_t i = 0; i < test_saved_tab_group_->saved_tabs.size(); i++) { - int command_id = saved_tab_group_menu_->GetCommandIdAt(i); - EXPECT_EQ(static_cast<int>(i), command_id); - EXPECT_TRUE(saved_tab_group_menu_->IsCommandIdEnabled(command_id)); - } -} - -// Verifies that calling ExecuteCommand calls our callback and can only be -// called once. -TEST_F(SavedTabGroupMenuTest, ExecuteCommandCanOnlyBeCalledOnce) { - static bool opened; - struct OpenUrl { - static void callback(const content::OpenURLParams& params) { - opened = true; - } - }; - - saved_tab_group_menu_->RunMenu(CreateTestWidget().get(), button_controller(), - gfx::Rect(), - base::BindOnce(OpenUrl::callback)); - saved_tab_group_menu_->ExecuteCommand(0, 0); - EXPECT_TRUE(opened); -}
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc index e62e1646..e66fb4a 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc
@@ -417,8 +417,11 @@ } void LocalCardMigrationDialogView::CloseDialog() { - controller_ = nullptr; GetWidget()->Close(); + if (controller_) { + controller_->OnDialogClosed(); + controller_ = nullptr; + } } void LocalCardMigrationDialogView::OnDialogAccepted() {
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc index d4f2cd4..17e35e3a 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc
@@ -54,8 +54,12 @@ set_margins(gfx::Insets()); } -LocalCardMigrationErrorDialogView::~LocalCardMigrationErrorDialogView() = - default; +LocalCardMigrationErrorDialogView::~LocalCardMigrationErrorDialogView() { + if (controller_) { + controller_->OnDialogClosed(); + controller_ = nullptr; + } +} void LocalCardMigrationErrorDialogView::ShowDialog( content::WebContents& web_contents) { @@ -66,11 +70,7 @@ } void LocalCardMigrationErrorDialogView::CloseDialog() { - controller_ = nullptr; GetWidget()->Close(); -} - -void LocalCardMigrationErrorDialogView::WindowClosing() { if (controller_) { controller_->OnDialogClosed(); controller_ = nullptr;
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.h b/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.h index ab657970..d067023 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.h +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.h
@@ -40,7 +40,6 @@ // views::BubbleDialogDelegateView: void Init() override; - void WindowClosing() override; private: raw_ptr<LocalCardMigrationDialogController> controller_;
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc index 3b453a2..384fb42 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
@@ -102,10 +102,10 @@ // for the button. AddChildViewAt( std::make_unique<SavedTabGroupButton>( + group, page_navigator(), base::BindRepeating(&SavedTabGroupBar::OnTabGroupButtonPressed, base::Unretained(this), group.group_id), - group.title, /*is_group_in_tabstrip*/ false, group.color, - animations_enabled_), + /*is_group_in_tabstrip*/ false, animations_enabled_), index); }
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc index 60eaffc7..7efe588 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc
@@ -4,27 +4,30 @@ #include "chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.h" +#include <memory> #include <string> +#include <vector> -#include "chrome/app/vector_icons/vector_icons.h" +#include "base/bind.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group.h" #include "chrome/browser/ui/tabs/tab_group_theme.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/bookmarks/bookmark_button_util.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" #include "chrome/grit/generated_resources.h" +#include "content/public/browser/page_navigator.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/dialog_model.h" #include "ui/base/models/dialog_model_menu_model_adapter.h" +#include "ui/base/models/image_model.h" #include "ui/base/theme_provider.h" #include "ui/gfx/animation/slide_animation.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point_f.h" -#include "ui/gfx/geometry/size.h" #include "ui/views/controls/button/label_button_border.h" #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/highlight_path_generator.h" @@ -41,16 +44,17 @@ constexpr float kCircleRadius = 14.0f; } // namespace -SavedTabGroupButton::SavedTabGroupButton(PressedCallback callback, - const std::u16string& title, +SavedTabGroupButton::SavedTabGroupButton(const SavedTabGroup& group, + content::PageNavigator* page_navigator, + PressedCallback callback, bool is_group_in_tabstrip, - tab_groups::TabGroupColorId color, bool animations_enabled) - : MenuButton(std::move(callback), title), - tab_group_color_id_(color), - is_group_in_tabstrip_(is_group_in_tabstrip) { - SetText(title); - SetAccessibleName(title); + : MenuButton(std::move(callback), group.title), + tab_group_color_id_(group.color), + is_group_in_tabstrip_(is_group_in_tabstrip), + context_menu_controller_(group.saved_tabs, page_navigator) { + SetText(group.title); + SetAccessibleName(group.title); SetID(VIEW_ID_BOOKMARK_BAR_ELEMENT); // Since the theme provider is not currently available when instantiated the @@ -85,9 +89,8 @@ // comfortably fit in the bookmarks bar. SetPreferredSize(gfx::Size(button_height, button_height)); } - // TODO(crbug.com/1324360): Add this back when the ContextMenuController does - // something reasonable. - // set_context_menu_controller(&context_menu_controller_); + + set_context_menu_controller(&context_menu_controller_); } SavedTabGroupButton::~SavedTabGroupButton() = default; @@ -186,26 +189,37 @@ return is_group_in_tabstrip_; } -SavedTabGroupButton::ContextMenuController::ContextMenuController() = default; +SavedTabGroupButton::ContextMenuController::ContextMenuController( + const std::vector<SavedTabGroupTab>& tabs, + content::PageNavigator* page_navigator) + : tabs_(tabs), page_navigator_(page_navigator) {} SavedTabGroupButton::ContextMenuController::~ContextMenuController() = default; void SavedTabGroupButton::ContextMenuController::ShowContextMenuForViewImpl( View* source, const gfx::Point& point, ui::MenuSourceType source_type) { - // TODO(pbos): Populate with real data, this is a placeholder to show dljames@ - // how the API is intended to be used. DoNothing()s need to be replaced with - // base::BindRepeating calls to open tabs. - auto dialog_model = - ui::DialogModel::Builder() - .AddMenuItem(ui::ImageModel::FromVectorIcon(kSaveGroupIcon), u"HELLO", - base::DoNothing()) - .AddMenuItem( - ui::ImageModel::FromVectorIcon(kMoveGroupToNewWindowIcon), - u"HELLO AGAIN", base::DoNothing()) - .Build(); - menu_model_ = std::make_unique<ui::DialogModelMenuModelAdapter>( - std::move(dialog_model)); + ui::DialogModel::Builder dialog_model = ui::DialogModel::Builder(); + + for (const SavedTabGroupTab& tab : tabs_) { + dialog_model.AddMenuItem( + ui::ImageModel::FromImage(tab.favicon), tab.tab_title, + base::BindRepeating( + [](GURL url, content::PageNavigator* page_navigator, + int event_flags) { + content::OpenURLParams params( + url, content::Referrer(), + WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_AUTO_BOOKMARK, + /*is_renderer_initiated=*/false, + /*started_from_context_menu=*/true); + page_navigator->OpenURL(params); + }, + tab.url, page_navigator_)); + } + + menu_model_ = + std::make_unique<ui::DialogModelMenuModelAdapter>(dialog_model.Build()); // TODO(pbos): See if there's a better way than IS_NESTED to force this to // show icons (we need favicons, I haven't figured out why this doesn't show
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.h b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.h index bca07fca..e0ba3cc3 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.h +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.h
@@ -5,9 +5,14 @@ #ifndef CHROME_BROWSER_UI_VIEWS_BOOKMARKS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_BUTTON_H_ #define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_BUTTON_H_ +#include <memory> #include <string> +#include <vector> +#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group.h" #include "components/tab_groups/tab_group_color.h" +#include "content/public/browser/page.h" +#include "content/public/browser/page_navigator.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/views/context_menu_controller.h" @@ -18,15 +23,17 @@ } // The display button for the Saved Tab Group in the bookmarks bar. +// Note: we currently recreate this button if any content (title, tabs, color, +// etc.) changes +// TODO(dljames): Find a way to not recreate the button for each update. class SavedTabGroupButton : public views::MenuButton { public: METADATA_HEADER(SavedTabGroupButton); - SavedTabGroupButton( - PressedCallback callback, - const std::u16string& title, - bool is_group_in_tabstrip, - tab_groups::TabGroupColorId color = tab_groups::TabGroupColorId::kGrey, - bool animations_enabled = true); + SavedTabGroupButton(const SavedTabGroup& group, + content::PageNavigator* page_navigator, + PressedCallback callback, + bool is_group_in_tabstrip, + bool animations_enabled = true); SavedTabGroupButton(const SavedTabGroupButton&) = delete; SavedTabGroupButton& operator=(const SavedTabGroupButton&) = delete; @@ -48,9 +55,12 @@ } private: + // TODO(dljames): Add a way to update the tabs in the context menu controller + // when a tab group is updated. class ContextMenuController : public views::ContextMenuController { public: - ContextMenuController(); + ContextMenuController(const std::vector<SavedTabGroupTab>& tabs, + content::PageNavigator* page_navigator); ~ContextMenuController() override; private: @@ -58,9 +68,18 @@ const gfx::Point& point, ui::MenuSourceType source_type) override; - // TODO(pbos): Comment + // The menu model for the saved tab group buttons context menu. std::unique_ptr<ui::MenuModel> menu_model_; + + // The menu runner for the saved tab group buttons context menu. std::unique_ptr<views::MenuRunner> menu_runner_; + + // The tabs to be displayed in the context menu. Currently supports tab + // title, url, and favicon. + const std::vector<SavedTabGroupTab> tabs_; + + // The page navigator used to open the context menu items into a new tab. + content::PageNavigator* page_navigator_; }; // The animations for button movement. @@ -72,6 +91,7 @@ // Denotes if the tabgroup is currently open in the tabstrip. bool is_group_in_tabstrip_; + // The context menu controller for the saved tab group button. ContextMenuController context_menu_controller_; };
diff --git a/chrome/browser/ui/views/extensions/extension_popup_interactive_uitest.cc b/chrome/browser/ui/views/extensions/extension_popup_interactive_uitest.cc index a6dec5e5..8e190b9 100644 --- a/chrome/browser/ui/views/extensions/extension_popup_interactive_uitest.cc +++ b/chrome/browser/ui/views/extensions/extension_popup_interactive_uitest.cc
@@ -146,5 +146,11 @@ // bubble. const bool is_stacked_above = views::test::WidgetTest::IsWindowStackedAbove( extension_popup->GetWidget(), permissions_api.GetPromptWindow()); +#if BUILDFLAG(IS_MAC) + // This doesn't yet work on mac. + // TODO(https://crbug.com/1300006): Investigate and fix. + EXPECT_TRUE(is_stacked_above); +#else EXPECT_FALSE(is_stacked_above); +#endif }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h index 66823c06..68e83dd 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h
@@ -24,7 +24,7 @@ // class ReadAnythingContainerView : public views::View { public: - explicit ReadAnythingContainerView( + ReadAnythingContainerView( std::unique_ptr<ReadAnythingToolbarView> toolbar, std::unique_ptr<SidePanelWebUIViewT<ReadAnythingUI>> content); ReadAnythingContainerView(const ReadAnythingContainerView&) = delete;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc index 2fdbafd8..b0f3973 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
@@ -28,7 +28,12 @@ controller_ = std::make_unique<ReadAnythingController>(model_.get(), browser); } -ReadAnythingCoordinator::~ReadAnythingCoordinator() = default; +ReadAnythingCoordinator::~ReadAnythingCoordinator() { + // Inform observers when |this| is destroyed so they can do their own cleanup. + for (Observer& obs : observers_) { + obs.OnCoordinatorDestroyed(); + } +} void ReadAnythingCoordinator::CreateAndRegisterEntry( SidePanelRegistry* global_registry) { @@ -40,24 +45,26 @@ base::Unretained(this)))); } -ReadAnythingPageHandler::Delegate* -ReadAnythingCoordinator::GetPageHandlerDelegate() { +ReadAnythingController* ReadAnythingCoordinator::GetController() { return controller_.get(); } -void ReadAnythingCoordinator::AddModelObserver( - ReadAnythingModel::Observer* observer) { - model_->AddObserver(observer); +ReadAnythingModel* ReadAnythingCoordinator::GetModel() { + return model_.get(); } -void ReadAnythingCoordinator::RemoveModelObserver( - ReadAnythingModel::Observer* observer) { - model_->RemoveObserver(observer); + +void ReadAnythingCoordinator::AddObserver( + ReadAnythingCoordinator::Observer* observer) { + observers_.AddObserver(observer); +} +void ReadAnythingCoordinator::RemoveObserver( + ReadAnythingCoordinator::Observer* observer) { + observers_.RemoveObserver(observer); } std::unique_ptr<views::View> ReadAnythingCoordinator::CreateContainerView() { // Create the views. - auto toolbar = std::make_unique<ReadAnythingToolbarView>( - controller_.get(), model_.get()->GetFontModel()); + auto toolbar = std::make_unique<ReadAnythingToolbarView>(this); Browser* browser = &GetBrowser(); auto content_web_view = std::make_unique<SidePanelWebUIViewT<ReadAnythingUI>>(
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h index 57c8b86..fab1dad 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h
@@ -8,10 +8,10 @@ #include <memory> #include "base/memory/raw_ptr.h" +#include "base/observer_list.h" #include "base/observer_list_types.h" #include "chrome/browser/ui/browser_user_data.h" #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h" -#include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h" class Browser; class ReadAnythingController; @@ -35,16 +35,22 @@ class ReadAnythingCoordinator : public BrowserUserData<ReadAnythingCoordinator> { public: + class Observer : public base::CheckedObserver { + public: + virtual void OnCoordinatorDestroyed() = 0; + }; + explicit ReadAnythingCoordinator(Browser* browser); ReadAnythingCoordinator(const ReadAnythingCoordinator&) = delete; ReadAnythingCoordinator& operator=(const ReadAnythingCoordinator&) = delete; ~ReadAnythingCoordinator() override; void CreateAndRegisterEntry(SidePanelRegistry* global_registry); - ReadAnythingPageHandler::Delegate* GetPageHandlerDelegate(); + ReadAnythingController* GetController(); + ReadAnythingModel* GetModel(); - void AddModelObserver(ReadAnythingModel::Observer* observer); - void RemoveModelObserver(ReadAnythingModel::Observer* observer); + void AddObserver(ReadAnythingCoordinator::Observer* observer); + void RemoveObserver(ReadAnythingCoordinator::Observer* observer); private: friend class BrowserUserData<ReadAnythingCoordinator>; @@ -57,6 +63,7 @@ std::unique_ptr<ReadAnythingModel> model_; std::unique_ptr<ReadAnythingController> controller_; + base::ObserverList<Observer> observers_; BROWSER_USER_DATA_KEY_DECL(); }; #endif // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_COORDINATOR_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc index f64403c..f551faf 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
@@ -13,8 +13,29 @@ #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry.h" #include "chrome/browser/ui/views/side_panel/side_panel_registry.h" +#include "testing/gmock/include/gmock/gmock.h" #include "ui/accessibility/accessibility_features.h" +using testing::_; + +class MockReadAnythingCoordinatorObserver + : public ReadAnythingCoordinator::Observer { + public: + MOCK_METHOD(void, OnCoordinatorDestroyed, (), (override)); +}; + +class MockReadAnythingModelObserver : public ReadAnythingModel::Observer { + public: + MOCK_METHOD(void, + OnFontNameUpdated, + (const std::string& new_font_name), + (override)); + MOCK_METHOD(void, + OnContentUpdated, + (const std::vector<ContentNodePtr>& content), + (override)); +}; + class ReadAnythingCoordinatorTest : public TestWithBrowserView { public: void SetUp() override { @@ -31,14 +52,21 @@ read_anything_coordinator_->CreateAndRegisterEntry(side_panel_registry_); } - ReadAnythingModel* GetModel() { - return read_anything_coordinator_->model_.get(); - } + // Wrapper methods around the ReadAnythingCoordinator. These do nothing more + // than keep the below tests less verbose (simple pass-throughs). ReadAnythingController* GetController() { - return read_anything_coordinator_->controller_.get(); + return read_anything_coordinator_->GetController(); } - + ReadAnythingModel* GetModel() { + return read_anything_coordinator_->GetModel(); + } + void AddObserver(ReadAnythingCoordinator::Observer* observer) { + read_anything_coordinator_->AddObserver(observer); + } + void RemoveObserver(ReadAnythingCoordinator::Observer* observer) { + read_anything_coordinator_->RemoveObserver(observer); + } std::unique_ptr<views::View> CreateContainerView() { return read_anything_coordinator_->CreateContainerView(); } @@ -47,6 +75,9 @@ raw_ptr<SidePanelCoordinator> side_panel_coordinator_; raw_ptr<SidePanelRegistry> side_panel_registry_; raw_ptr<ReadAnythingCoordinator> read_anything_coordinator_; + + MockReadAnythingCoordinatorObserver coordinator_observer_; + MockReadAnythingModelObserver model_observer_; }; TEST_F(ReadAnythingCoordinatorTest, ModelAndControllerPersist) { @@ -65,8 +96,25 @@ EXPECT_NE(nullptr, GetController()); } -TEST_F(ReadAnythingCoordinatorTest, CreateContainerViewReturnsNewView) { +TEST_F(ReadAnythingCoordinatorTest, ContainerViewsAreUnique) { auto view1 = CreateContainerView(); auto view2 = CreateContainerView(); EXPECT_NE(view1, view2); } + +TEST_F(ReadAnythingCoordinatorTest, OnCoordinatorDestroyedCalled) { + AddObserver(&coordinator_observer_); + EXPECT_CALL(coordinator_observer_, OnCoordinatorDestroyed()).Times(1); +} + +TEST_F(ReadAnythingCoordinatorTest, ModelObserversReceiveNotifications) { + GetModel()->AddObserver(&model_observer_); + + EXPECT_CALL(model_observer_, OnFontNameUpdated(_)).Times(1); + EXPECT_CALL(model_observer_, OnContentUpdated(_)).Times(1); + + GetModel()->SetSelectedFontIndex(3); + GetModel()->SetContent(std::vector<ContentNodePtr>()); + + GetModel()->RemoveObserver(&model_observer_); +}
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc index 04f2111bb..3ec8095 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc
@@ -8,6 +8,7 @@ #include <utility> #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_constants.h" +#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h" #include "components/vector_icons/vector_icons.h" #include "ui/color/color_provider.h" #include "ui/gfx/color_palette.h" @@ -20,9 +21,12 @@ #include "ui/views/layout/layout_types.h" ReadAnythingToolbarView::ReadAnythingToolbarView( - ReadAnythingToolbarView::Delegate* delegate, - ui::ComboboxModel* model) { - delegate_ = delegate; + ReadAnythingCoordinator* coordinator) + : coordinator_(std::move(coordinator)) { + coordinator_->AddObserver(this); + delegate_ = static_cast<ReadAnythingToolbarView::Delegate*>( + coordinator_->GetController()); + auto* font_model = coordinator_->GetModel()->GetFontModel(); // Create and set a BoxLayout LayoutManager for this view. auto layout = std::make_unique<views::BoxLayout>( @@ -42,14 +46,28 @@ combobox->SetSizeToLargestLabel(true); // TODO(1266555): This is placeholder text, remove for final UI. combobox->SetTooltipTextAndAccessibleName(u"Font Choice"); - combobox->SetModel(model); + combobox->SetModel(font_model); // Add all views as children. font_combobox_ = AddChildView(std::move(combobox)); } void ReadAnythingToolbarView::FontNameChangedCallback() { - delegate_->OnFontChoiceChanged(font_combobox_->GetSelectedIndex()); + if (delegate_) + delegate_->OnFontChoiceChanged(font_combobox_->GetSelectedIndex()); } -ReadAnythingToolbarView::~ReadAnythingToolbarView() = default; +void ReadAnythingToolbarView::OnCoordinatorDestroyed() { + // When the coordinator that created |this| is destroyed, clean up pointers. + coordinator_ = nullptr; + delegate_ = nullptr; + font_combobox_->SetModel(nullptr); +} + +ReadAnythingToolbarView::~ReadAnythingToolbarView() { + // If |this| is being destroyed before the associated coordinator, then + // remove |this| as an observer. + if (coordinator_) { + coordinator_->RemoveObserver(this); + } +}
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h index e5535acb..71c2f33 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_TOOLBAR_VIEW_H_ #include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h" #include "ui/base/models/combobox_model.h" #include "ui/views/controls/combobox/combobox.h" #include "ui/views/view.h" @@ -17,24 +18,28 @@ // This class is created by the ReadAnythingCoordinator and owned by the // ReadAnythingContainerView. It has the same lifetime as the Side Panel view. // -class ReadAnythingToolbarView : public views::View { +class ReadAnythingToolbarView : public views::View, + public ReadAnythingCoordinator::Observer { public: class Delegate { public: virtual void OnFontChoiceChanged(int new_choice) = 0; }; - explicit ReadAnythingToolbarView(ReadAnythingToolbarView::Delegate* delegate, - ui::ComboboxModel* model); + explicit ReadAnythingToolbarView(ReadAnythingCoordinator* coordinator); ReadAnythingToolbarView(const ReadAnythingToolbarView&) = delete; ReadAnythingToolbarView& operator=(const ReadAnythingToolbarView&) = delete; ~ReadAnythingToolbarView() override; + // ReadAnythingCoordinator::Observer: + void OnCoordinatorDestroyed() override; + private: void FontNameChangedCallback(); raw_ptr<views::Combobox> font_combobox_; raw_ptr<ReadAnythingToolbarView::Delegate> delegate_; + ReadAnythingCoordinator* coordinator_; base::WeakPtrFactory<ReadAnythingToolbarView> weak_pointer_factory_{this}; };
diff --git a/chrome/browser/ui/views/webid/account_selection_bubble_view.cc b/chrome/browser/ui/views/webid/account_selection_bubble_view.cc index 534cd14f..c6048821 100644 --- a/chrome/browser/ui/views/webid/account_selection_bubble_view.cc +++ b/chrome/browser/ui/views/webid/account_selection_bubble_view.cc
@@ -6,6 +6,7 @@ #include "base/i18n/case_conversion.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/accessibility/accessibility_state_utils.h" #include "chrome/browser/image_fetcher/image_decoder_impl.h" #include "chrome/browser/profiles/profile_avatar_icon_util.h" #include "chrome/browser/ui/monogram_utils.h" @@ -438,7 +439,9 @@ SizeToContents(); PreferredSizeChanged(); - continue_button_->RequestFocus(); + // Focus `continue_button` if screen reader is enabled. + if (accessibility_state_utils::IsScreenReaderEnabled()) + continue_button_->RequestFocus(); SendAccessibilityEvent(GetWidget()); }
diff --git a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc index 1b2b394..83ec804 100644 --- a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc +++ b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc
@@ -70,8 +70,8 @@ /*paired_phones=*/{phone}, /*contact_phone_callback=*/base::DoNothing(), "fido://qrcode"); } - transport_availability.has_recognized_platform_authenticator_credential = - false; + transport_availability.has_platform_authenticator_credential = device:: + FidoRequestHandlerBase::RecognizedCredential::kNoRecognizedCredential; transport_availability.request_type = device::FidoRequestType::kGetAssertion; model->StartFlow(std::move(transport_availability),
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc index 7be09a5..184558fb 100644 --- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
@@ -40,8 +40,6 @@ namespace { -constexpr size_t kMaxRelatedSearches = 5; - // Creates a `mojom::VisitPtr` from a `history_clusters::Visit`. mojom::URLVisitPtr VisitToMojom(Profile* profile, const history::ClusterVisit& visit) { @@ -104,6 +102,8 @@ visit_mojom->annotations.push_back(mojom::Annotation::kSearchResultsPage); } + visit_mojom->hidden = visit.hidden; + if (GetConfig().user_visible_debug) { visit_mojom->debug_info["visit_id"] = base::NumberToString(annotated_visit.visit_row.visit_id); @@ -166,47 +166,14 @@ } for (const auto& visit : cluster.visits) { - mojom::URLVisitPtr visit_mojom = VisitToMojom(profile, visit); + cluster_mojom->visits.push_back(VisitToMojom(profile, visit)); + } - // Even a 0.0 visit shouldn't be hidden if this is the first visit we - // encounter. The assumption is that the visits are always ranked by score - // in a descending order. - // TODO(crbug.com/1313631): Simplify this after removing "Show More" UI. - if ((visit.score == 0.0 && !cluster_mojom->visits.empty()) || - (visit.score < GetConfig().min_score_to_always_show_above_the_fold && - cluster_mojom->visits.size() >= - GetConfig().num_visits_to_always_show_above_the_fold)) { - // If the visit is dropped entirely, also skip coalescing its related - // searches by continuing the loop. - if (GetConfig().drop_hidden_visits) { - continue; - } - - visit_mojom->hidden = true; - } - - cluster_mojom->visits.push_back(std::move(visit_mojom)); - - // Coalesce the unique related searches of this visit into the cluster - // until the cap is reached. - for (const auto& search_query : - visit.annotated_visit.content_annotations.related_searches) { - if (cluster_mojom->related_searches.size() >= kMaxRelatedSearches) { - break; - } - - if (base::Contains(cluster_mojom->related_searches, search_query, - [](const mojom::SearchQueryPtr& search_query_mojom) { - return search_query_mojom->query; - })) { - continue; - } - - auto search_query_mojom = SearchQueryToMojom(profile, search_query); - if (search_query_mojom) { - cluster_mojom->related_searches.emplace_back( - std::move(*search_query_mojom)); - } + for (const auto& related_search : cluster.related_searches) { + auto search_query_mojom = SearchQueryToMojom(profile, related_search); + if (search_query_mojom) { + cluster_mojom->related_searches.emplace_back( + std::move(*search_query_mojom)); } }
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler_unittest.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler_unittest.cc index a1fef0c..87dad71c 100644 --- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler_unittest.cc +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler_unittest.cc
@@ -51,39 +51,21 @@ TestingProfile profile_; }; -TEST_F(HistoryClustersHandlerTest, QueryClustersResultToMojom_Hidden) { +// Just a basic test that we transform the data to mojom. A lot of the meat of +// the visit hiding logic is within QueryClustersState and HistoryClustersUtil. +TEST_F(HistoryClustersHandlerTest, QueryClustersResultToMojom_Integration) { std::vector<history::Cluster> clusters; - // High scoring visits should always be above the fold. - history::Cluster cluster1; - cluster1.cluster_id = 4; - cluster1.visits.push_back(CreateVisit("https://high-score-1", 1)); - cluster1.visits.push_back(CreateVisit("https://high-score-2", .8)); - cluster1.visits.push_back(CreateVisit("https://high-score-3", .5)); - cluster1.visits.push_back(CreateVisit("https://high-score-4", .5)); - cluster1.visits.push_back(CreateVisit("https://high-score-5", .5)); - cluster1.keywords.push_back(u"keyword"); - // Low scoring visits should be above the fold only if they're one of top 4. - history::Cluster cluster2; - cluster2.cluster_id = 6; - cluster2.visits.push_back(CreateVisit("https://low-score-1", .4)); - cluster2.visits.push_back(CreateVisit("https://low-score-2", .4)); - cluster2.visits.push_back(CreateVisit("https://low-score-3", .4)); - cluster2.visits.push_back(CreateVisit("https://low-score-4", .4)); - cluster2.visits.push_back(CreateVisit("https://low-score-5", .4)); - cluster2.keywords.push_back(u"keyword"); + history::Cluster cluster; + cluster.cluster_id = 4; + cluster.related_searches = {"one", "two", "three", "four", "five"}; + cluster.visits.push_back(CreateVisit("https://low-score-1", .4)); + cluster.visits[0].hidden = false; + cluster.visits.push_back(CreateVisit("https://low-score-1", .4)); + cluster.visits[1].hidden = true; - // 0 scoring visits should be above the fold only if they're 1st. - history::Cluster cluster3; - cluster3.cluster_id = 8; - cluster3.visits.push_back(CreateVisit("https://zero-score-1", 0)); - cluster3.visits.push_back(CreateVisit("https://zero-score-2", 0)); - cluster3.keywords.push_back(u"keyword"); - - clusters.push_back(cluster1); - clusters.push_back(cluster2); - clusters.push_back(cluster3); + clusters.push_back(cluster); mojom::QueryResultPtr mojom_result = QueryClustersResultToMojom(&profile_, "query", clusters, true, false); @@ -92,71 +74,23 @@ EXPECT_EQ(mojom_result->can_load_more, true); EXPECT_EQ(mojom_result->is_continuation, false); - ASSERT_EQ(mojom_result->clusters.size(), 3u); - - { - EXPECT_EQ(mojom_result->clusters[0]->id, 4); - const auto& visits = mojom_result->clusters[0]->visits; - ASSERT_EQ(visits.size(), 5u); - EXPECT_EQ(visits[0]->hidden, false); - EXPECT_EQ(visits[1]->hidden, false); - EXPECT_EQ(visits[2]->hidden, false); - EXPECT_EQ(visits[3]->hidden, false); - EXPECT_EQ(visits[4]->hidden, false); - } - - { - EXPECT_EQ(mojom_result->clusters[1]->id, 6); - const auto& visits = mojom_result->clusters[1]->visits; - ASSERT_EQ(visits.size(), 5u); - EXPECT_EQ(visits[0]->hidden, false); - EXPECT_EQ(visits[1]->hidden, false); - EXPECT_EQ(visits[2]->hidden, false); - EXPECT_EQ(visits[3]->hidden, false); - EXPECT_EQ(visits[4]->hidden, true); - } - - { - EXPECT_EQ(mojom_result->clusters[2]->id, 8); - ASSERT_EQ(mojom_result->clusters[2]->visits.size(), 2u); - EXPECT_EQ(mojom_result->clusters[2]->visits[0]->hidden, false); - EXPECT_EQ(mojom_result->clusters[2]->visits[1]->hidden, true); - } -} - -TEST_F(HistoryClustersHandlerTest, QueryClustersResultToMojom_RelatedSearches) { - std::vector<history::Cluster> clusters; - - history::Cluster cluster; - cluster.cluster_id = 4; - // Should include the top visit's related searches. - cluster.visits.push_back( - CreateVisit("https://high-score-1", 0, {"one", "two"})); - // Should exclude duplicates (i.e. "one"). - cluster.visits.push_back(CreateVisit( - "https://high-score-2", 0, {"one", "three", "four", "five", "six"})); - // Visits without related searches shouldn't interrupt the coalescing. - cluster.visits.push_back(CreateVisit("https://high-score-3", 0)); - // Should not include more related searches once the max related searches has - // been met (5). - cluster.visits.push_back( - CreateVisit("https://high-score-4", 0, {"seven", "eight", "nine"})); - cluster.visits.push_back(CreateVisit("https://high-score-5", 0, {"ten"})); - - clusters.push_back(cluster); - - mojom::QueryResultPtr mojom_result = - QueryClustersResultToMojom(&profile_, "query", clusters, false, false); - ASSERT_EQ(mojom_result->clusters.size(), 1u); - EXPECT_EQ(mojom_result->clusters[0]->id, 4); const auto& cluster_mojom = mojom_result->clusters[0]; - ASSERT_EQ(cluster_mojom->related_searches.size(), 5u); - EXPECT_EQ(cluster_mojom->related_searches[0]->query, "one"); - EXPECT_EQ(cluster_mojom->related_searches[1]->query, "two"); - EXPECT_EQ(cluster_mojom->related_searches[2]->query, "three"); - EXPECT_EQ(cluster_mojom->related_searches[3]->query, "four"); - EXPECT_EQ(cluster_mojom->related_searches[4]->query, "five"); + + { + EXPECT_EQ(cluster_mojom->id, 4); + const auto& visits = cluster_mojom->visits; + ASSERT_EQ(visits.size(), 2u); + // Test that the hidden attribute is passed through to mojom. + EXPECT_EQ(visits[0]->hidden, false); + EXPECT_EQ(visits[1]->hidden, true); + ASSERT_EQ(cluster_mojom->related_searches.size(), 5u); + EXPECT_EQ(cluster_mojom->related_searches[0]->query, "one"); + EXPECT_EQ(cluster_mojom->related_searches[1]->query, "two"); + EXPECT_EQ(cluster_mojom->related_searches[2]->query, "three"); + EXPECT_EQ(cluster_mojom->related_searches[3]->query, "four"); + EXPECT_EQ(cluster_mojom->related_searches[4]->query, "five"); + } } // TODO(manukh) Add a test case for `VisitToMojom`.
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.cc b/chrome/browser/ui/webui/policy/policy_ui_handler.cc index 4d5d84a..62f6971 100644 --- a/chrome/browser/ui/webui/policy/policy_ui_handler.cc +++ b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
@@ -1022,7 +1022,7 @@ return names; } -base::Value PolicyUIHandler::GetPolicyValues() { +base::Value::List PolicyUIHandler::GetPolicyValues() { auto client = std::make_unique<policy::ChromePolicyConversionsClient>( web_ui()->GetWebContents()->GetBrowserContext()); @@ -1034,7 +1034,7 @@ .WithUpdaterPolicies( std::make_unique<policy::PolicyMap>(updater_policies_->Clone())) .WithUpdaterPolicySchemas(GetGoogleUpdatePolicySchemas()) - .ToValue(); + .ToValueList(); } #endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) @@ -1044,7 +1044,7 @@ policy_conversions.WithAdditionalChromePolicies(device_policy_.Clone()); #endif // BUILDFLAG(IS_CHROMEOS_LACROS) - return policy_conversions.EnableConvertValues(true).ToValue(); + return policy_conversions.EnableConvertValues(true).ToValueList(); } void PolicyUIHandler::AddExtensionPolicyNames( @@ -1334,7 +1334,8 @@ void PolicyUIHandler::SendPolicies() { if (IsJavascriptAllowed()) - FireWebUIListener("policies-updated", GetPolicyNames(), GetPolicyValues()); + FireWebUIListener("policies-updated", GetPolicyNames(), + base::Value(GetPolicyValues())); } #if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.h b/chrome/browser/ui/webui/policy/policy_ui_handler.h index 1e5da8c..46ef2d6 100644 --- a/chrome/browser/ui/webui/policy/policy_ui_handler.h +++ b/chrome/browser/ui/webui/policy/policy_ui_handler.h
@@ -87,7 +87,7 @@ private: base::Value GetPolicyNames(); - base::Value GetPolicyValues(); + base::Value::List GetPolicyValues(); void AddExtensionPolicyNames(base::Value* names, policy::PolicyDomain policy_domain);
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc index bf72fe36..623afc76 100644 --- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc +++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
@@ -91,10 +91,7 @@ // calls. auto printing_context( PrintingContext::Create(&delegate, /*skip_system_calls=*/false)); - if (mojom::ResultCode::kSuccess != printing_context->UsePdfSettings() || - printing_context->settings().device_units_per_inch() <= 0) { - return gfx::Size(); - } + printing_context->UsePdfSettings(); gfx::Size pdf_media_size = printing_context->GetPdfPaperSizeDeviceUnits(); float device_microns_per_device_unit = static_cast<float>(kMicronsPerInch) /
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc index 196ee62..3e046820 100644 --- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc +++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.cc
@@ -10,7 +10,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h" +#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h" ReadAnythingPageHandler::ReadAnythingPageHandler( mojo::PendingRemote<Page> page, @@ -22,27 +22,35 @@ browser_ = chrome::FindLastActive(); if (!browser_) return; - ReadAnythingCoordinator::FromBrowser(browser_)->AddModelObserver(this); - delegate_ = - ReadAnythingCoordinator::FromBrowser(browser_)->GetPageHandlerDelegate(); + + coordinator_ = ReadAnythingCoordinator::FromBrowser(browser_); + coordinator_->AddObserver(this); + model_ = coordinator_->GetModel(); + model_->AddObserver(this); + delegate_ = static_cast<ReadAnythingPageHandler::Delegate*>( + coordinator_->GetController()); } ReadAnythingPageHandler::~ReadAnythingPageHandler() { - // Remove |this| from the observer list of |ReadAnythingModel|. - if (browser_) { - ReadAnythingCoordinator* coordinator = - ReadAnythingCoordinator::FromBrowser(browser_); + // If |this| is destroyed before the |ReadAnythingCoordinator|, then remove + // |this| from the observer lists. In the cases where the coordinator is + // destroyed first, these will have been destroyed before this call. + if (model_) + model_->RemoveObserver(this); - // `Browser` is guaranteed to live as long as the ReadAnythingCoordinator - // since it is BrowserUserData (due to how UserData works - Browser owns - // this UserData). - DCHECK(coordinator); - coordinator->RemoveModelObserver(this); - } + if (coordinator_) + coordinator_->RemoveObserver(this); } void ReadAnythingPageHandler::OnUIReady() { - delegate_->OnUIReady(); + if (delegate_) + delegate_->OnUIReady(); +} + +void ReadAnythingPageHandler::OnCoordinatorDestroyed() { + coordinator_ = nullptr; + model_ = nullptr; + delegate_ = nullptr; } void ReadAnythingPageHandler::OnContentUpdated(
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h index 9565f74..cdf07f6 100644 --- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h +++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_page_handler.h
@@ -10,6 +10,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h" #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h" #include "chrome/browser/ui/webui/side_panel/read_anything/read_anything.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -30,15 +31,16 @@ // as the Side Panel view. // class ReadAnythingPageHandler : public PageHandler, - public ReadAnythingModel::Observer { + public ReadAnythingModel::Observer, + public ReadAnythingCoordinator::Observer { public: class Delegate { public: virtual void OnUIReady() = 0; }; - explicit ReadAnythingPageHandler(mojo::PendingRemote<Page> page, - mojo::PendingReceiver<PageHandler> receiver); + ReadAnythingPageHandler(mojo::PendingRemote<Page> page, + mojo::PendingReceiver<PageHandler> receiver); ReadAnythingPageHandler(const ReadAnythingPageHandler&) = delete; ReadAnythingPageHandler& operator=(const ReadAnythingPageHandler&) = delete; ~ReadAnythingPageHandler() override; @@ -51,9 +53,12 @@ void OnContentUpdated( const std::vector<ContentNodePtr>& content_nodes) override; + // ReadAnythingCoordinator::Observer: + void OnCoordinatorDestroyed() override; + private: - // ReadAnythingPageHandler::Delegate is owned by ReadAnythingCoordinator which - // is a browser user data, so |delegate_| has the same lifetime as |browser_|. + raw_ptr<ReadAnythingCoordinator> coordinator_; + raw_ptr<ReadAnythingModel> model_; raw_ptr<ReadAnythingPageHandler::Delegate> delegate_; Browser* browser_;
diff --git a/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.cc b/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.cc index 5dcd8e2..fc7b84f 100644 --- a/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.cc +++ b/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.cc
@@ -55,12 +55,6 @@ web_ui()->RegisterMessageCallback(message, std::move(callback)); } -void ChromeTranslateInternalsHandler::RegisterDeprecatedMessageCallback( - const std::string& message, - const DeprecatedMessageCallback& callback) { - web_ui()->RegisterDeprecatedMessageCallback(message, callback); -} - void ChromeTranslateInternalsHandler::CallJavascriptFunction( const std::string& function_name, const std::vector<const base::Value*>& args) {
diff --git a/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.h b/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.h index 1a852ff..88fc56f4 100644 --- a/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.h +++ b/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.h
@@ -30,9 +30,6 @@ variations::VariationsService* GetVariationsService() override; void RegisterMessageCallback(const std::string& message, MessageCallback callback) override; - void RegisterDeprecatedMessageCallback( - const std::string& message, - const DeprecatedMessageCallback& callback) override; void CallJavascriptFunction( const std::string& function_name, const std::vector<const base::Value*>& args) override;
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index 74e9448a..ff5047e9 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -480,6 +480,7 @@ "commands/run_on_os_login_command_unittest.cc", "daily_metrics_helper_unittest.cc", "external_install_options_unittest.cc", + "externally_installed_web_app_prefs_unittest.cc", "externally_managed_app_manager_impl_unittest.cc", "externally_managed_app_manager_unittest.cc", "isolation_prefs_utils_unittest.cc",
diff --git a/chrome/browser/web_applications/extensions/BUILD.gn b/chrome/browser/web_applications/extensions/BUILD.gn index 13b757f..faff1a5 100644 --- a/chrome/browser/web_applications/extensions/BUILD.gn +++ b/chrome/browser/web_applications/extensions/BUILD.gn
@@ -46,7 +46,6 @@ sources = [ "bookmark_app_util_unittest.cc", - "externally_installed_web_app_prefs_unittest.cc", "externally_managed_app_install_task_unittest.cc", "web_app_policy_manager_unittest.cc", "web_app_provider_unittest.cc",
diff --git a/chrome/browser/web_applications/externally_installed_web_app_prefs.cc b/chrome/browser/web_applications/externally_installed_web_app_prefs.cc index f188531..4dc16fd 100644 --- a/chrome/browser/web_applications/externally_installed_web_app_prefs.cc +++ b/chrome/browser/web_applications/externally_installed_web_app_prefs.cc
@@ -8,7 +8,10 @@ #include <utility> #include <vector> +#include "base/containers/contains.h" +#include "chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.h" #include "chrome/browser/web_applications/web_app_install_utils.h" +#include "chrome/browser/web_applications/web_app_prefs_utils.h" #include "chrome/browser/web_applications/web_app_registry_update.h" #include "chrome/common/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -283,6 +286,10 @@ ExternallyInstalledWebAppPrefs::ParsedPrefs pref_to_app_data = ParseExternalPrefsToWebAppData(pref_service); + // First migrate data to UserUninstalledPreinstalledWebAppPrefs. + MigrateExternalPrefDataToPreinstalledPrefs( + pref_service, &sync_bridge->registrar(), pref_to_app_data); + ScopedRegistryUpdate update(sync_bridge); for (auto it : pref_to_app_data) { WebApp* web_app = update->UpdateApp(it.first); @@ -305,4 +312,50 @@ } } +// static +void ExternallyInstalledWebAppPrefs::MigrateExternalPrefDataToPreinstalledPrefs( + PrefService* pref_service, + const WebAppRegistrar* registrar, + const ExternallyInstalledWebAppPrefs::ParsedPrefs& parsed_data) { + UserUninstalledPreinstalledWebAppPrefs preinstalled_prefs(pref_service); + for (auto pair : parsed_data) { + const AppId& app_id = pair.first; + const auto& source_to_config_map = pair.second; + const auto& it = source_to_config_map.find(WebAppManagement::kDefault); + // Migration will happen in the following cases: + // 1. If app_id exists in the external prefs that had source as + // kDefault but the app is no longer installed in the registry or if it + // is no longer preinstalled, that means + // it was preinstalled and then uninstalled by user. + if (!registrar->IsInstalledByDefaultManagement(app_id) && + it != source_to_config_map.end()) { + preinstalled_prefs.Add(app_id, it->second.install_urls); + } + // 2. If the value corresponding to the app_id in + // web_app::kWasExternalAppUninstalledByUser is true, then it was previously + // a preinstalled app that was user uninstalled. In this case, we migrate + // ALL install URLs for that corresponding app_id, because a preinstalled + // app could have been installed as an app with a different source now. + if (GetBoolWebAppPref(pref_service, app_id, + kWasExternalAppUninstalledByUser)) { + preinstalled_prefs.Add(app_id, MergeAllUrls(source_to_config_map)); + } + } +} + +// static +base::flat_set<GURL> ExternallyInstalledWebAppPrefs::MergeAllUrls( + const base::flat_map<WebAppManagement::Type, + WebApp::ExternalManagementConfig>& source_config_map) { + std::vector<GURL> urls; + for (auto it : source_config_map) { + for (const GURL& url : it.second.install_urls) { + DCHECK(url.is_valid()); + urls.push_back(url); + } + } + + return urls; +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/externally_installed_web_app_prefs.h b/chrome/browser/web_applications/externally_installed_web_app_prefs.h index a135a1c1..06bf1b4 100644 --- a/chrome/browser/web_applications/externally_installed_web_app_prefs.h +++ b/chrome/browser/web_applications/externally_installed_web_app_prefs.h
@@ -13,6 +13,7 @@ #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_id.h" +#include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_sync_bridge.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -86,6 +87,16 @@ WebAppSyncBridge* sync_bridge); private: + // Used to migrate information regarding user uninstalled preinstalled apps + // to UserUninstalledPreinstalledWebAppPrefs. + static void MigrateExternalPrefDataToPreinstalledPrefs( + PrefService* pref_service, + const WebAppRegistrar* registrar, + const ParsedPrefs& parsed_data); + static base::flat_set<GURL> MergeAllUrls( + const base::flat_map<WebAppManagement::Type, + WebApp::ExternalManagementConfig>& + source_config_map); const raw_ptr<PrefService> pref_service_; };
diff --git a/chrome/browser/web_applications/extensions/externally_installed_web_app_prefs_unittest.cc b/chrome/browser/web_applications/externally_installed_web_app_prefs_unittest.cc similarity index 64% rename from chrome/browser/web_applications/extensions/externally_installed_web_app_prefs_unittest.cc rename to chrome/browser/web_applications/externally_installed_web_app_prefs_unittest.cc index c257dbd2..03bc483 100644 --- a/chrome/browser/web_applications/extensions/externally_installed_web_app_prefs_unittest.cc +++ b/chrome/browser/web_applications/externally_installed_web_app_prefs_unittest.cc
@@ -6,28 +6,23 @@ #include <algorithm> -#include "base/command_line.h" #include "base/json/json_reader.h" -#include "chrome/browser/extensions/test_extension_system.h" #include "chrome/browser/web_applications/test/fake_web_app_provider.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" +#include "chrome/browser/web_applications/test/web_app_test.h" #include "chrome/browser/web_applications/test/web_app_test_utils.h" +#include "chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.h" #include "chrome/browser/web_applications/web_app_constants.h" +#include "chrome/browser/web_applications/web_app_id.h" +#include "chrome/browser/web_applications/web_app_prefs_utils.h" #include "chrome/browser/web_applications/web_app_registry_update.h" #include "chrome/common/pref_names.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "chrome/test/base/testing_profile.h" -#include "components/crx_file/id_util.h" #include "components/prefs/scoped_user_pref_update.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/common/extension_builder.h" #include "testing/gtest/include/gtest/gtest.h" namespace web_app { -using ExternalInstallSource = ExternalInstallSource; - -class ExternallyInstalledWebAppPrefsTest - : public ChromeRenderViewHostTestHarness { +class ExternallyInstalledWebAppPrefsTest : public WebAppTest { public: ExternallyInstalledWebAppPrefsTest() = default; ExternallyInstalledWebAppPrefsTest( @@ -40,32 +35,14 @@ ChromeRenderViewHostTestHarness::SetUp(); web_app_provider_ = web_app::FakeWebAppProvider::Get(profile()); web_app_provider_->StartWithSubsystems(); - // TODO(https://crbug.com/891172): Use an extension agnostic test registry. - extensions::TestExtensionSystem* test_system = - static_cast<extensions::TestExtensionSystem*>( - extensions::ExtensionSystem::Get(profile())); - test_system->CreateExtensionService(base::CommandLine::ForCurrentProcess(), - profile()->GetPath(), - false); // autoupdate_enabled } - std::string GenerateFakeExtensionId(const GURL& url) { - return crx_file::id_util::GenerateId("fake_app_id_for:" + url.spec()); - } - - void SimulatePreviouslyInstalledApp(const GURL& url, - ExternalInstallSource install_source) { - std::string id = GenerateFakeExtensionId(url); - extensions::ExtensionRegistry::Get(profile())->AddEnabled( - extensions::ExtensionBuilder("Dummy Name").SetID(id).Build()); - + AppId SimulatePreviouslyInstalledApp(const GURL& url, + ExternalInstallSource install_source) { + AppId id = test::InstallDummyWebApp(profile(), "TestApp", url); ExternallyInstalledWebAppPrefs(profile()->GetPrefs()) .Insert(url, id, install_source); - } - - void SimulateUninstallApp(const GURL& url) { - std::string id = GenerateFakeExtensionId(url); - extensions::ExtensionRegistry::Get(profile())->RemoveEnabled(id); + return id; } std::vector<GURL> GetAppUrls(ExternalInstallSource install_source) { @@ -79,15 +56,14 @@ return urls; } - void InitProvider() { + FakeWebAppProvider* provider() { base::RunLoop run_loop; web_app_provider_->on_registry_ready().Post(FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); + return web_app_provider_; } - FakeWebAppProvider* provider() { return web_app_provider_; } - private: FakeWebAppProvider* web_app_provider_; }; @@ -98,10 +74,10 @@ GURL url_c("https://c.example.com/"); GURL url_d("https://d.example.com/"); - std::string id_a = GenerateFakeExtensionId(url_a); - std::string id_b = GenerateFakeExtensionId(url_b); - std::string id_c = GenerateFakeExtensionId(url_c); - std::string id_d = GenerateFakeExtensionId(url_d); + AppId id_a; + AppId id_b; + AppId id_c; + AppId id_d; auto* prefs = profile()->GetPrefs(); ExternallyInstalledWebAppPrefs map(prefs); @@ -126,13 +102,12 @@ GetAppUrls(ExternalInstallSource::kExternalPolicy)); // Add some entries. - - SimulatePreviouslyInstalledApp(url_a, - ExternalInstallSource::kExternalDefault); - SimulatePreviouslyInstalledApp(url_b, - ExternalInstallSource::kInternalDefault); - SimulatePreviouslyInstalledApp(url_c, - ExternalInstallSource::kExternalDefault); + id_a = SimulatePreviouslyInstalledApp( + url_a, ExternalInstallSource::kExternalDefault); + id_b = SimulatePreviouslyInstalledApp( + url_b, ExternalInstallSource::kInternalDefault); + id_c = SimulatePreviouslyInstalledApp( + url_c, ExternalInstallSource::kExternalDefault); EXPECT_EQ(id_a, map.LookupAppId(url_a).value_or("missing")); EXPECT_EQ(id_b, map.LookupAppId(url_b).value_or("missing")); @@ -175,8 +150,8 @@ // Uninstall an underlying extension. The ExternallyInstalledWebAppPrefs will // still return positive. - - SimulateUninstallApp(url_b); + ScopedRegistryUpdate update(&provider()->sync_bridge()); + update->DeleteApp(id_b); EXPECT_EQ(id_a, map.LookupAppId(url_a).value_or("missing")); EXPECT_EQ(id_b, map.LookupAppId(url_b).value_or("missing")); @@ -340,7 +315,6 @@ } TEST_F(ExternallyInstalledWebAppPrefsTest, MigrationTestForSingleSource) { - InitProvider(); std::unique_ptr<WebApp> web_app = test::CreateWebApp( GURL("https://app.com/"), WebAppManagement::Type::kDefault); AppId app_id = web_app->app_id(); @@ -375,4 +349,133 @@ .install_urls.begin()); } +TEST_F(ExternallyInstalledWebAppPrefsTest, + UserUninstalledPreInstalledWebAppMigrationSingleApp) { + ExternallyInstalledWebAppPrefs external_prefs(profile()->GetPrefs()); + UserUninstalledPreinstalledWebAppPrefs preinstalled_prefs( + profile()->GetPrefs()); + AppId app_id1 = "test_app1"; + AppId app_id2 = "test_app2"; + external_prefs.Insert(GURL("https://app1.com/install"), app_id1, + ExternalInstallSource::kExternalDefault); + external_prefs.SetIsPlaceholder(GURL("https://app1.com/install"), true); + + external_prefs.Insert(GURL("https://app2.com/install"), app_id2, + ExternalInstallSource::kArc); + external_prefs.SetIsPlaceholder(GURL("https://app2.com/install"), true); + + ExternallyInstalledWebAppPrefs::MigrateExternalPrefData( + profile()->GetPrefs(), &provider()->sync_bridge()); + + // On migration, only a app_id1 should be migrated. + EXPECT_TRUE(preinstalled_prefs.DoesAppIdExist(app_id1)); + EXPECT_FALSE(preinstalled_prefs.DoesAppIdExist(app_id2)); +} + +TEST_F(ExternallyInstalledWebAppPrefsTest, + UserUninstalledPreInstalledWebAppMigrationSingleAppNonDefault) { + ExternallyInstalledWebAppPrefs external_prefs(profile()->GetPrefs()); + UserUninstalledPreinstalledWebAppPrefs preinstalled_prefs( + profile()->GetPrefs()); + AppId app_id1 = "test_app1"; + external_prefs.Insert(GURL("https://app1.com/install"), app_id1, + ExternalInstallSource::kArc); + external_prefs.SetIsPlaceholder(GURL("https://app1.com/install"), true); + + external_prefs.Insert(GURL("https://app2.com/install"), app_id1, + ExternalInstallSource::kExternalPolicy); + external_prefs.SetIsPlaceholder(GURL("https://app2.com/install"), true); + + ExternallyInstalledWebAppPrefs::MigrateExternalPrefData( + profile()->GetPrefs(), &provider()->sync_bridge()); + + // On migration, nothing is migrated because default installs do not exist in + // the external prefs. + EXPECT_FALSE(preinstalled_prefs.DoesAppIdExist(app_id1)); +} + +TEST_F(ExternallyInstalledWebAppPrefsTest, + UserUninstalledPreInstalledWebAppMigrationSingleAppMultiURL) { + ExternallyInstalledWebAppPrefs external_prefs(profile()->GetPrefs()); + UserUninstalledPreinstalledWebAppPrefs preinstalled_prefs( + profile()->GetPrefs()); + AppId app_id1 = "test_app1"; + external_prefs.Insert(GURL("https://app1.com/install"), app_id1, + ExternalInstallSource::kInternalDefault); + external_prefs.SetIsPlaceholder(GURL("https://app1.com/install"), true); + + external_prefs.Insert(GURL("https://app2.com/install"), app_id1, + ExternalInstallSource::kExternalDefault); + external_prefs.SetIsPlaceholder(GURL("https://app2.com/install"), true); + + ExternallyInstalledWebAppPrefs::MigrateExternalPrefData( + profile()->GetPrefs(), &provider()->sync_bridge()); + + // On migration, everything (app_ids and both URLs should be migrated). + EXPECT_TRUE(preinstalled_prefs.DoesAppIdExist(app_id1)); + EXPECT_EQ(app_id1, preinstalled_prefs.LookUpAppIdByInstallUrl( + GURL("https://app1.com/install"))); + EXPECT_EQ(app_id1, preinstalled_prefs.LookUpAppIdByInstallUrl( + GURL("https://app2.com/install"))); +} + +TEST_F(ExternallyInstalledWebAppPrefsTest, + UserUninstalledPreInstalledWebAppMigrationOldPref) { + ExternallyInstalledWebAppPrefs external_prefs(profile()->GetPrefs()); + UserUninstalledPreinstalledWebAppPrefs preinstalled_prefs( + profile()->GetPrefs()); + AppId app_id1 = "test_app1"; + external_prefs.Insert(GURL("https://app1.com/install"), app_id1, + ExternalInstallSource::kExternalPolicy); + external_prefs.SetIsPlaceholder(GURL("https://app1.com/install"), true); + + external_prefs.Insert(GURL("https://app2.com/install"), app_id1, + ExternalInstallSource::kArc); + external_prefs.SetIsPlaceholder(GURL("https://app2.com/install"), true); + + UpdateBoolWebAppPref(profile()->GetPrefs(), app_id1, + kWasExternalAppUninstalledByUser, true); + + ExternallyInstalledWebAppPrefs::MigrateExternalPrefData( + profile()->GetPrefs(), &provider()->sync_bridge()); + + // On migration, everything (app_ids and both URLs should be migrated). + EXPECT_TRUE(preinstalled_prefs.DoesAppIdExist(app_id1)); + EXPECT_EQ(app_id1, preinstalled_prefs.LookUpAppIdByInstallUrl( + GURL("https://app1.com/install"))); + EXPECT_EQ(app_id1, preinstalled_prefs.LookUpAppIdByInstallUrl( + GURL("https://app2.com/install"))); +} + +TEST_F(ExternallyInstalledWebAppPrefsTest, + DuplicateMigrationDoesNotGrowPreinstalledPrefs) { + ExternallyInstalledWebAppPrefs external_prefs(profile()->GetPrefs()); + UserUninstalledPreinstalledWebAppPrefs preinstalled_prefs( + profile()->GetPrefs()); + AppId app_id1 = "test_app1"; + external_prefs.Insert(GURL("https://app1.com/install"), app_id1, + ExternalInstallSource::kExternalPolicy); + external_prefs.SetIsPlaceholder(GURL("https://app1.com/install"), true); + + UpdateBoolWebAppPref(profile()->GetPrefs(), app_id1, + kWasExternalAppUninstalledByUser, true); + + ExternallyInstalledWebAppPrefs::MigrateExternalPrefData( + profile()->GetPrefs(), &provider()->sync_bridge()); + + // On migration, everything (app_ids and both URLs should be migrated). + EXPECT_TRUE(preinstalled_prefs.DoesAppIdExist(app_id1)); + EXPECT_EQ(app_id1, preinstalled_prefs.LookUpAppIdByInstallUrl( + GURL("https://app1.com/install"))); + EXPECT_EQ(1, preinstalled_prefs.Size()); + + // Call migration 2 more times, pref size should not grow if same + // data is being migrated. + ExternallyInstalledWebAppPrefs::MigrateExternalPrefData( + profile()->GetPrefs(), &provider()->sync_bridge()); + ExternallyInstalledWebAppPrefs::MigrateExternalPrefData( + profile()->GetPrefs(), &provider()->sync_bridge()); + EXPECT_EQ(1, preinstalled_prefs.Size()); +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.cc b/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.cc index 36040f12..a98bf91 100644 --- a/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.cc +++ b/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.cc
@@ -105,4 +105,16 @@ } } +int UserUninstalledPreinstalledWebAppPrefs::Size() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + const base::Value* ids_to_urls = pref_service_->GetDictionary( + prefs::kUserUninstalledPreinstalledWebAppPref); + + if (!ids_to_urls) + return 0; + + const base::Value::Dict* pref_info = ids_to_urls->GetIfDict(); + return pref_info->size(); +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.h b/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.h index 5a92683..39cbb63 100644 --- a/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.h +++ b/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.h
@@ -56,6 +56,7 @@ bool DoesAppIdExist(const AppId& app_id); void AppendExistingInstallUrlsPerAppId(const AppId& app_id, base::flat_set<GURL>& urls); + int Size(); private: const raw_ptr<PrefService> pref_service_;
diff --git a/chrome/browser/web_applications/web_app_install_finalizer.cc b/chrome/browser/web_applications/web_app_install_finalizer.cc index 0d2d51a..162aaab 100644 --- a/chrome/browser/web_applications/web_app_install_finalizer.cc +++ b/chrome/browser/web_applications/web_app_install_finalizer.cc
@@ -28,6 +28,7 @@ #include "chrome/browser/web_applications/os_integration/web_app_shortcuts_menu.h" #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/user_display_mode.h" +#include "chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_icon_generator.h" @@ -275,6 +276,12 @@ if (app->IsPreinstalledApp()) { UpdateBoolWebAppPref(profile_->GetPrefs(), app_id, kWasExternalAppUninstalledByUser, true); + // Update the default uninstalled web_app prefs if it is a preinstalled app + // but being removed by user. + UserUninstalledPreinstalledWebAppPrefs(profile_->GetPrefs()) + .Add(app_id, app->management_to_external_config_map() + .at(WebAppManagement::kDefault) + .install_urls); } // UninstallWebApp can wipe out an app with multiple sources. This
diff --git a/chrome/browser/web_applications/web_app_install_manager_unittest.cc b/chrome/browser/web_applications/web_app_install_manager_unittest.cc index e6dc905..817733e1 100644 --- a/chrome/browser/web_applications/web_app_install_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
@@ -1038,6 +1038,8 @@ GURL("https://example.com/path"), WebAppManagement::kSync); default_and_user_app->AddSource(WebAppManagement::kDefault); default_and_user_app->SetUserDisplayMode(UserDisplayMode::kStandalone); + default_and_user_app->AddInstallURLToManagementExternalConfigMap( + WebAppManagement::kDefault, GURL("https://example.com/path")); const AppId app_id = default_and_user_app->app_id(); const GURL external_app_url("https://example.com/path/default"); @@ -1077,6 +1079,8 @@ GURL("https://example.com/path"), WebAppManagement::kSync); default_and_user_app->AddSource(WebAppManagement::kDefault); default_and_user_app->SetUserDisplayMode(UserDisplayMode::kStandalone); + default_and_user_app->AddInstallURLToManagementExternalConfigMap( + WebAppManagement::kDefault, GURL("https://example.com/path")); const AppId app_id = default_and_user_app->app_id(); const GURL external_app_url("https://example.com/path/default");
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc index b084b8f..cfa5224c 100644 --- a/chrome/browser/web_applications/web_app_registrar.cc +++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -479,6 +479,16 @@ return web_app ? web_app->IsStorageIsolated() : false; } +bool WebAppRegistrar::IsInstalledByDefaultManagement( + const AppId& app_id) const { + if (!IsInstalled(app_id)) + return false; + + const WebApp* web_app = GetAppById(app_id); + DCHECK(web_app); + return web_app->GetSources().test(WebAppManagement::kDefault); +} + bool WebAppRegistrar::WasInstalledByDefaultOnly(const AppId& app_id) const { const WebApp* web_app = GetAppById(app_id); return web_app && web_app->HasOnlySource(WebAppManagement::Type::kDefault);
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h index 8e8c2fed..28583ecb 100644 --- a/chrome/browser/web_applications/web_app_registrar.h +++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -103,6 +103,10 @@ blink::ParsedPermissionsPolicy GetPermissionsPolicy( const AppId& app_id) const; + // Returns true if there exists a currently installed app that has been + // installed by PreinstalledWebAppManager. + bool IsInstalledByDefaultManagement(const AppId& app_id) const; + // Returns true if the app was preinstalled and NOT installed via any other // mechanism. bool WasInstalledByDefaultOnly(const AppId& app_id) const;
diff --git a/chrome/browser/web_applications/web_app_registrar_unittest.cc b/chrome/browser/web_applications/web_app_registrar_unittest.cc index 85606fd..aea0f33 100644 --- a/chrome/browser/web_applications/web_app_registrar_unittest.cc +++ b/chrome/browser/web_applications/web_app_registrar_unittest.cc
@@ -1145,4 +1145,26 @@ EXPECT_FALSE(registrar().IsRegisteredLaunchProtocol(app_id, "mailto")); } +TEST_F(WebAppRegistrarTest, TestIsDefaultManagementInstalled) { + controller().Init(); + + auto web_app1 = + test::CreateWebApp(GURL("https://start.com"), WebAppManagement::kDefault); + auto web_app2 = test::CreateWebApp(GURL("https://starter.com"), + WebAppManagement::kPolicy); + const AppId app_id1 = web_app1->app_id(); + const AppId app_id2 = web_app2->app_id(); + RegisterApp(std::move(web_app1)); + RegisterApp(std::move(web_app2)); + + // Currently default installed. + EXPECT_TRUE(registrar().IsInstalledByDefaultManagement(app_id1)); + // Currently installed by source other than installed. + EXPECT_FALSE(registrar().IsInstalledByDefaultManagement(app_id2)); + + // Uninstalling the previously default installed app. + UnregisterApp(app_id1); + EXPECT_FALSE(registrar().IsInstalledByDefaultManagement(app_id1)); +} + } // namespace web_app
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc index 360931a..4eb1b9d 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -312,10 +312,11 @@ // fail. Proceed to a special error screen instead. if (transport_availability_.request_type == device::FidoRequestType::kGetAssertion) { - DCHECK(transport_availability_ - .has_recognized_platform_authenticator_credential); - if (!*transport_availability_ - .has_recognized_platform_authenticator_credential) { + DCHECK_NE(transport_availability_.has_platform_authenticator_credential, + device::FidoRequestHandlerBase::RecognizedCredential::kUnknown); + if (transport_availability_.has_platform_authenticator_credential == + device::FidoRequestHandlerBase::RecognizedCredential:: + kNoRecognizedCredential) { SetCurrentStep(Step::kErrorInternalUnrecognized); return; } @@ -955,8 +956,9 @@ if (base::Contains(transport_availability_.available_transports, AuthenticatorTransport::kInternal) && is_get_assertion && - *transport_availability_ - .has_recognized_platform_authenticator_credential) { + transport_availability_.has_platform_authenticator_credential == + device::FidoRequestHandlerBase::RecognizedCredential:: + kHasRecognizedCredential) { priority_transport = AuthenticatorTransport::kInternal; }
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc index d9371b3..c1fec9bb 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
@@ -23,6 +23,7 @@ #include "device/fido/discoverable_credential_metadata.h" #include "device/fido/features.h" #include "device/fido/fido_constants.h" +#include "device/fido/fido_request_handler_base.h" #include "device/fido/fido_transport_protocol.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -258,9 +259,13 @@ transports_info.request_type = test.request_type; transports_info.available_transports = test.transports; - transports_info.has_recognized_platform_authenticator_credential = + transports_info.has_platform_authenticator_credential = base::Contains(test.params, - TransportAvailabilityParam::kHasPlatformCredential); + TransportAvailabilityParam::kHasPlatformCredential) + ? device::FidoRequestHandlerBase::RecognizedCredential:: + kHasRecognizedCredential + : device::FidoRequestHandlerBase::RecognizedCredential:: + kNoRecognizedCredential; if (base::Contains( test.params, @@ -718,7 +723,8 @@ TransportAvailabilityInfo transports_info; transports_info.available_transports = kAllTransports; - transports_info.has_recognized_platform_authenticator_credential = true; + transports_info.has_platform_authenticator_credential = device:: + FidoRequestHandlerBase::RecognizedCredential::kHasRecognizedCredential; model.StartFlow(std::move(transports_info), /*use_location_bar_bubble=*/true, /*prefer_native_api=*/false); @@ -744,7 +750,8 @@ TransportAvailabilityInfo transports_info; transports_info.available_transports = kAllTransports; - transports_info.has_recognized_platform_authenticator_credential = true; + transports_info.has_platform_authenticator_credential = device:: + FidoRequestHandlerBase::RecognizedCredential::kHasRecognizedCredential; device::DiscoverableCredentialMetadata cred_1( {0}, device::PublicKeyCredentialUserEntity({1, 2, 3, 4})); device::DiscoverableCredentialMetadata cred_2(
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc index d041dc2..ef805112 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -792,8 +792,13 @@ callback) { if (disable_ui_) { // Cryptotoken requests should never reach account selection. - NOTREACHED(); - std::move(cancel_callback_).Run(); + DCHECK(IsVirtualEnvironmentEnabled()); + + // The browser is being automated. Select the first credential to support + // automation of discoverable credentials. + // TODO(crbug.com/991666): Provide a way to determine which account gets + // picked. + std::move(callback).Run(std::move(responses.at(0))); return; }
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 52cada42..377dc9a 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1652356777-22968c0343d3dab5af5e71c970198c515e19f0b5.profdata +chrome-win32-main-1652367504-e16559aa10862cd703ddaf15816ffe8bb011e211.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 789aa94..6b82dea 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1652356777-14199a2764984cebd34e978b7bee66a84e7ee3da.profdata +chrome-win64-main-1652367504-6023c828cb679dd05bfb942d2245691253a4b212.profdata
diff --git a/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc b/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc index 70720b70..ea6f4dca 100644 --- a/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc +++ b/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
@@ -29,7 +29,6 @@ const ChromeOSSystemExtensionInfos& getMap() { static const ChromeOSSystemExtensionInfos kExtensionIdToExtensionInfoMap{ - // TODO(b/200920331): replace google.com with OEM-specific origin. {/*extension_id=*/"gogonhoemckpdpadfnjnpgbjpbjnodgc", {/*manufacturer=*/"HP", /*pwa_origin=*/"*://www.google.com/*"}}, {/*extension_id=*/"alnedpmllcfpgldkagbfbjkloonjlfjb",
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index d046b4d0..bd6fe04 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc
@@ -122,10 +122,6 @@ const char kWallpaperManagerId[] = "obklkkbkpaoaejdabbfldmcfplpdgolj"; const char kHelpAppExtensionId[] = "honijodknafkokifofgiaalefdiedpko"; #endif // BUILDFLAG(IS_CHROMEOS_ASH) -#if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION) -// The extension id of the Hangout Service extnsion. -const char kHangoutServiceExtensionId[] = "nkeimhogjdpnpccoofpliimaahmaaome"; -#endif const char kAppStateNotInstalled[] = "not_installed"; const char kAppStateInstalled[] = "installed";
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index a8a664fb..82bdab25 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h
@@ -233,10 +233,6 @@ // The extension id of official HelpApp extension. extern const char kHelpAppExtensionId[]; #endif -#if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION) -// The extension id of the Hangout Service extnsion. -extern const char kHangoutServiceExtensionId[]; -#endif // What causes an extension to be installed? Used in histograms, so don't // change existing values.
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 0160090..06315cc 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1726,10 +1726,10 @@ if (!extension) return; - // Append a default CSP to ensure the extension can't relax the default + // Append a minimum CSP to ensure the extension can't relax the default // applied CSP through means like Service Worker. const std::string* default_csp = - extensions::CSPInfo::GetDefaultCSPToAppend(*extension, gurl.path()); + extensions::CSPInfo::GetMinimumCSPToAppend(*extension, gurl.path()); if (!default_csp) return;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ed1ddc5..a26247703 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3765,6 +3765,7 @@ "../browser/chromeos/tablet_mode/tablet_mode_page_behavior_browsertest.cc", "../browser/device_api/device_attribute_api_browsertest.cc", "../browser/drive/drive_notification_manager_factory_browsertest.cc", + "../browser/feedback/show_feedback_page_browsertest.cc", "../browser/metrics/chromeos_family_link_user_metrics_provider_browsertest.cc", "../browser/metrics/chromeos_metrics_provider_browsertest.cc", "../browser/metrics/family_user_metrics_provider_browsertest.cc", @@ -6525,6 +6526,7 @@ "../browser/ui/passwords/credential_leak_dialog_controller_impl_unittest.cc", "../browser/ui/passwords/credential_manager_dialog_controller_impl_unittest.cc", "../browser/ui/passwords/manage_passwords_ui_controller_unittest.cc", + "../browser/ui/passwords/password_manager_navigation_throttle_unittest.cc", "../browser/ui/passwords/well_known_change_password_navigation_throttle_unittest.cc", "../browser/ui/qrcode_generator/qrcode_generator_bubble_controller_unittest.cc", "../browser/ui/read_later/read_later_test_utils.cc", @@ -6544,7 +6546,6 @@ "../browser/ui/tabs/existing_window_sub_menu_model_unittest.cc", "../browser/ui/tabs/pinned_tab_codec_unittest.cc", "../browser/ui/tabs/pinned_tab_service_unittest.cc", - "../browser/ui/tabs/saved_tab_groups/saved_tab_group_menu_unittest.cc", "../browser/ui/tabs/saved_tab_groups/saved_tab_group_model_unittest.cc", "../browser/ui/tabs/tab_menu_model_unittest.cc", "../browser/ui/tabs/tab_strip_model_stats_recorder_unittest.cc",
diff --git a/chrome/test/data/banners/manifest_isolated.json b/chrome/test/data/banners/manifest_isolated.json index 5e3b0311..1c25284 100644 --- a/chrome/test/data/banners/manifest_isolated.json +++ b/chrome/test/data/banners/manifest_isolated.json
@@ -11,5 +11,8 @@ "start_url": "isolated/simple.html", "display": "standalone", "orientation": "landscape", - "isolated_storage": true + "isolated_storage": true, + "permissions_policy": { + "usb": [ "self" ] + } }
diff --git a/chrome/test/data/extensions/api_test/no_wasm_mv3/empty.wasm b/chrome/test/data/extensions/api_test/no_wasm_mv3/empty.wasm new file mode 100644 index 0000000..d8fc92d0 --- /dev/null +++ b/chrome/test/data/extensions/api_test/no_wasm_mv3/empty.wasm Binary files differ
diff --git a/chrome/test/data/extensions/api_test/no_wasm_mv3/manifest.json b/chrome/test/data/extensions/api_test/no_wasm_mv3/manifest.json new file mode 100644 index 0000000..be6cd62 --- /dev/null +++ b/chrome/test/data/extensions/api_test/no_wasm_mv3/manifest.json
@@ -0,0 +1,6 @@ +{ + "name": "Hello, WebAssembly!", + "description": "Verify wasm not allowed without explicit CSP", + "version": "0.1", + "manifest_version": 3 +}
diff --git a/chrome/test/data/extensions/api_test/no_wasm_mv3/page.html b/chrome/test/data/extensions/api_test/no_wasm_mv3/page.html new file mode 100644 index 0000000..95c1485e --- /dev/null +++ b/chrome/test/data/extensions/api_test/no_wasm_mv3/page.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<html> + <script type="module" src="page.js"></script> +</html>
diff --git a/chrome/test/data/extensions/api_test/no_wasm_mv3/page.js b/chrome/test/data/extensions/api_test/no_wasm_mv3/page.js new file mode 100644 index 0000000..9957ef3c --- /dev/null +++ b/chrome/test/data/extensions/api_test/no_wasm_mv3/page.js
@@ -0,0 +1,7 @@ +// Copyright 2022 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 {runTests} from './test_module.js'; + +runTests();
diff --git a/chrome/test/data/extensions/api_test/no_wasm_mv3/test_module.js b/chrome/test/data/extensions/api_test/no_wasm_mv3/test_module.js new file mode 100644 index 0000000..d47a43c0 --- /dev/null +++ b/chrome/test/data/extensions/api_test/no_wasm_mv3/test_module.js
@@ -0,0 +1,41 @@ +// Copyright 2022 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. + +export async function runTests() { + + chrome.test.runTests([ + // Attempts to fetch and instantiate a simple Wasm module. + async function instantiateFetch() { + const response = await fetch('empty.wasm'); + + let wasmAllowed; + try { + const instance = await WebAssembly.instantiateStreaming(response); + wasmAllowed = true; + } catch (e) { + wasmAllowed = false; + } + chrome.test.assertFalse(wasmAllowed); + chrome.test.succeed(); + }, + + // Attempts to instantiate a simple Wasm module. + async function instantiateArrayBuffer() { + // The smallest possible Wasm module. Just the header (0, "A", "S", "M"), + // and the version (0x1). + const bytes = new Uint8Array([0, 0x61, 0x73, 0x6d, 0x1, 0, 0, 0]); + + let wasmAllowed; + try { + const instance = await WebAssembly.instantiate(bytes); + wasmAllowed = true; + } catch (e) { + wasmAllowed = false; + } + + chrome.test.assertFalse(wasmAllowed); + chrome.test.succeed(); + } + ]); +}
diff --git a/chrome/test/data/extensions/api_test/wasm_mv3/manifest.json b/chrome/test/data/extensions/api_test/wasm_mv3/manifest.json index 898374a..dbc58aaf 100644 --- a/chrome/test/data/extensions/api_test/wasm_mv3/manifest.json +++ b/chrome/test/data/extensions/api_test/wasm_mv3/manifest.json
@@ -3,6 +3,9 @@ "description": "Verify usage of wasm in MV3", "version": "0.1", "manifest_version": 3, + "content_security_policy":{ + "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'" + }, "background": { "service_worker": "service_worker.js", "type": "module"
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts index cfd2de6..c833824 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts
@@ -341,7 +341,7 @@ }); test( - 'sends the first three local images that successfully load thumbnails', + 'sends the first four local images that successfully load thumbnails', async () => { // Set up store data. Local image list is loaded, but thumbnails are // still loading in. @@ -381,20 +381,22 @@ // loading. assertFalse(wallpaperCollectionsElement['didSendLocalImageData_']); - // Second thumbnail fails loading. Third succeeds. + // Second thumbnail fails loading. Third and fourth succeed. personalizationStore.data.wallpaper.loading.local.data = { ...personalizationStore.data.wallpaper.loading.local.data, 'LocalImage1.png': false, 'LocalImage2.png': false, + 'LocalImage3.png': false, }; personalizationStore.data.wallpaper.local.data = { ...personalizationStore.data.wallpaper.local.data, 'LocalImage1.png': '', 'LocalImage2.png': 'local_data_2', + 'LocalImage3.png': 'local_data_3', }; personalizationStore.notifyObservers(); - // 2 thumbnails have now loaded. 1 failed. But there are no more + // 3 thumbnails have now loaded. 1 failed. But there are no more // remaining to try loading, should send local image data anyway. const [_, sentData] = await testProxy.whenCalled('sendLocalImageData') as @@ -406,6 +408,7 @@ 'LocalImage0.png': 'local_data_0', 'LocalImage1.png': '', 'LocalImage2.png': 'local_data_2', + 'LocalImage3.png': 'local_data_3', }, sentData); });
diff --git a/chrome/test/data/webui/settings/privacy_sandbox_test.ts b/chrome/test/data/webui/settings/privacy_sandbox_test.ts index 667115d..8de80a5 100644 --- a/chrome/test/data/webui/settings/privacy_sandbox_test.ts +++ b/chrome/test/data/webui/settings/privacy_sandbox_test.ts
@@ -714,30 +714,4 @@ await flushTasks(); assertMainViewVisible(); }); - - test('directDialogClose', async function() { - // Confirm that closing the dialog directly (as done through the escape key) - // correctly navigates back. - assertMainViewVisible(); - - // Open a sub page. - page.shadowRoot!.querySelector<HTMLElement>( - '#adPersonalizationRow')!.click(); - await flushTasks(); - assertAdPersonalizationDialogVisible(); - - // Close the subpage by closing the modal dialog directly. - const dialogWrapper = - page.shadowRoot!.querySelector<CrDialogElement>('#dialogWrapper'); - assertTrue(!!dialogWrapper); - dialogWrapper.close(); - await flushTasks(); - assertMainViewVisible(); - - // Closing the dialog should have reset the view state, such that another - // dialog can be opened. - page.shadowRoot!.querySelector<HTMLElement>('#adMeasurementRow')!.click(); - await flushTasks(); - assertAdMeasurementDialogVisible(); - }); });
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts b/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts index 22e3ec0..26dfbf636 100644 --- a/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts +++ b/chrome/test/data/webui/side_panel/read_anything/read_anything_app_test.ts
@@ -331,4 +331,26 @@ const expected: ContentNode[] = []; assertContentNodes(expected); }); + + test('showContent clearContainer', async () => { + const contentNodes1: ContentNode[] = [ + new ContentNodeBuilder(ContentType.kStaticText) + .setText('First set of content.') + .build(), + ]; + + callbackRouter.showContent(contentNodes1); + await flushTasks(); + assertContentNodes(contentNodes1); + + const contentNodes2: ContentNode[] = [ + new ContentNodeBuilder(ContentType.kStaticText) + .setText('Second set of content.') + .build(), + ]; + + callbackRouter.showContent(contentNodes2); + await flushTasks(); + assertContentNodes(contentNodes2); + }); });
diff --git a/chrome/test/enterprise/e2e/infra/chrome_ent_test_case.py b/chrome/test/enterprise/e2e/infra/chrome_ent_test_case.py index 606408122..2e628ac 100644 --- a/chrome/test/enterprise/e2e/infra/chrome_ent_test_case.py +++ b/chrome/test/enterprise/e2e/infra/chrome_ent_test_case.py
@@ -115,6 +115,7 @@ self.clients[instance_name].RunPowershell(cmd) def InstallWebDriver(self, instance_name): + self.EnsurePythonInstalled(instance_name) self.InstallPipPackagesLatest(instance_name, ['selenium', 'absl-py', 'pywin32']) @@ -143,8 +144,6 @@ Returns: the output.""" - self.EnsurePythonInstalled(instance_name) - # upload the test file_name = self.UploadFile(instance_name, test_file, r'c:\temp') @@ -166,8 +165,6 @@ Returns: the output.""" - self.EnsurePythonInstalled(instance_name) - # upload the test file_name = self.UploadFile(instance_name, test_file, r'c:\temp')
diff --git a/chrome/test/enterprise/e2e/policy/fullscreen_allowed/is_fullscreen_allowed.py b/chrome/test/enterprise/e2e/policy/fullscreen_allowed/is_fullscreen_allowed.py index 084a34f..cf1855f 100644 --- a/chrome/test/enterprise/e2e/policy/fullscreen_allowed/is_fullscreen_allowed.py +++ b/chrome/test/enterprise/e2e/policy/fullscreen_allowed/is_fullscreen_allowed.py
@@ -2,9 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import test_util +import time from absl import app from pywinauto.application import Application +import test_util def main(argv): @@ -24,6 +25,7 @@ print("press F11 to enter full screen mode.") w.type_keys('{F11}') + time.sleep(5) window_rect = w.rectangle() window_width = window_rect.width() window_height = window_rect.height()
diff --git a/chromeos/hugepage_text/OWNERS b/chromeos/hugepage_text/OWNERS index 4ad6b380..ec84e62 100644 --- a/chromeos/hugepage_text/OWNERS +++ b/chromeos/hugepage_text/OWNERS
@@ -1,3 +1,2 @@ gbiv@chromium.org -llozano@chromium.org manojgupta@chromium.org
diff --git a/components/autofill/core/browser/metrics/shadow_prediction_metrics_unittest.cc b/components/autofill/core/browser/metrics/shadow_prediction_metrics_unittest.cc index 2d9e829..9da0358 100644 --- a/components/autofill/core/browser/metrics/shadow_prediction_metrics_unittest.cc +++ b/components/autofill/core/browser/metrics/shadow_prediction_metrics_unittest.cc
@@ -115,8 +115,11 @@ : public autofill::metrics::AutofillMetricsBaseTest { public: AutofillShadowPredictionMetricsTest() { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillParsingPatternProvider); + scoped_feature_list_.InitWithFeaturesAndParameters( + {base::test::ScopedFeatureList::FeatureAndParams( + features::kAutofillParsingPatternProvider, + {{"prediction_source", "default"}})}, + {}); } ~AutofillShadowPredictionMetricsTest() override = default; @@ -162,17 +165,8 @@ #if BUILDFLAG(USE_INTERNAL_AUTOFILL_HEADERS) // Test that Autofill.ShadowPredictions.* describes the differences between the // predictions and the submitted values. -#if BUILDFLAG(IS_ANDROID) -// https://crbug.com/1324261 -#define MAYBE_SubmissionWithAgreeingShadowPredictions \ - DISABLED_SubmissionWithAgreeingShadowPredictions -#else -#define MAYBE_SubmissionWithAgreeingShadowPredictions \ - SubmissionWithAgreeingShadowPredictions -#endif - TEST_F(AutofillShadowPredictionMetricsTest, - MAYBE_SubmissionWithAgreeingShadowPredictions) { + SubmissionWithAgreeingShadowPredictions) { FormData form = GetFormWith2Fields(autofill_client_->form_origin()); form.fields[0].value = u"Elvis Aaron Presley"; // A known `NAME_FULL`. form.fields[1].value = u"buddy@gmail.com"; // A known `EMAIL_ADDRESS`.
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp index f356edc..efe946b 100644 --- a/components/autofill_payments_strings.grdp +++ b/components/autofill_payments_strings.grdp
@@ -105,6 +105,9 @@ <message name="IDS_AUTOFILL_MOBILE_SAVE_CARD_TO_CLOUD_CONFIRMATION_DIALOG_EXPLANATION" desc="Explanation of the effect of the Autofill save card prompt when the card is to be saved by uploading it to Google Payments." formatter_data="android_java"> Save your card and billing info to your Google Account for secure and faster checkouts </message> + <message name="IDS_AUTOFILL_MOBILE_SAVE_CARD_TO_CLOUD_CONFIRMATION_DIALOG_EXPLANATION_WITH_ACCOUNT_NAME" desc="Explanation of the effect of the Autofill save card prompt when the card is to be saved by uploading it to Google Payments. Includes Google account reference." formatter_data="android_java"> + Save your card and billing info to your Google Account <ph name="USER_EMAIL">^1<ex>user@gmail.com</ex></ph> for secure and faster checkouts + </message> </if> <if expr="is_ios"> <then>
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_MOBILE_SAVE_CARD_TO_CLOUD_CONFIRMATION_DIALOG_EXPLANATION_WITH_ACCOUNT_NAME.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_MOBILE_SAVE_CARD_TO_CLOUD_CONFIRMATION_DIALOG_EXPLANATION_WITH_ACCOUNT_NAME.png.sha1 new file mode 100644 index 0000000..9e040b5 --- /dev/null +++ b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_MOBILE_SAVE_CARD_TO_CLOUD_CONFIRMATION_DIALOG_EXPLANATION_WITH_ACCOUNT_NAME.png.sha1
@@ -0,0 +1 @@ +44c6e8c0f0fee08842017c5b62b321c78de74b7d \ No newline at end of file
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java index 09cb5b23e..77b80ca 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java
@@ -21,16 +21,17 @@ public interface BackPressHandler { // The smaller the value is, the higher the priority is. @IntDef({Type.TEXT_BUBBLE, Type.VR_DELEGATE, Type.AR_DELEGATE, Type.LAYOUT_MANAGER, - Type.MANUAL_FILLING, Type.TAB_MODAL_HANDLER, Type.FULLSCREEN}) + Type.SELECTION_POPUP, Type.MANUAL_FILLING, Type.TAB_MODAL_HANDLER, Type.FULLSCREEN}) @Retention(RetentionPolicy.SOURCE) @interface Type { int TEXT_BUBBLE = 0; int VR_DELEGATE = 1; int AR_DELEGATE = 2; int LAYOUT_MANAGER = 3; - int MANUAL_FILLING = 4; - int FULLSCREEN = 5; - int TAB_MODAL_HANDLER = 6; + int SELECTION_POPUP = 4; + int MANUAL_FILLING = 5; + int FULLSCREEN = 6; + int TAB_MODAL_HANDLER = 7; int NUM_TYPES = TAB_MODAL_HANDLER + 1; } @@ -39,7 +40,9 @@ /** * A {@link ObservableSupplier<Boolean>} which notifies of whether the implementer wants to * intercept the back gesture. - * @return True if the implementer wants to intercept the back gesture. + * @return An {@link ObservableSupplier<Boolean>} which yields true if the implementer wants to + * intercept the back gesture; otherwise, it should yield false to prevent {@link + * #handleBackPress()} from being called. */ default ObservableSupplier<Boolean> getHandleBackPressChangedSupplier() { return new ObservableSupplierImpl<>();
diff --git a/components/cast_streaming/browser/playback_command_dispatcher.cc b/components/cast_streaming/browser/playback_command_dispatcher.cc index 7fc972c69..0e11e163 100644 --- a/components/cast_streaming/browser/playback_command_dispatcher.cc +++ b/components/cast_streaming/browser/playback_command_dispatcher.cc
@@ -37,8 +37,13 @@ mojo::Remote<media::mojom::Renderer> translators_renderer; RegisterCommandSource(translators_renderer.BindNewPipeAndPassReceiver()); - call_translator_ = std::make_unique<remoting::RendererRpcCallTranslator>( - std::move(translators_renderer)); + auto message_processor_callback = base::BindRepeating( + &PlaybackCommandDispatcher::SendRemotingRpcMessageToRemote, + weak_factory_.GetWeakPtr()); + renderer_call_translator_ = + std::make_unique<remoting::RendererRpcCallTranslator>( + std::move(message_processor_callback), + std::move(translators_renderer)); } PlaybackCommandDispatcher::~PlaybackCommandDispatcher() { @@ -55,32 +60,16 @@ DCHECK(messenger); messenger_ = messenger; - handle_ = messenger_->GetUniqueHandle(); + RegisterHandleForCallbacks( + openscreen::cast::RpcMessenger::kAcquireRendererHandle); + RegisterHandleForCallbacks( + openscreen::cast::RpcMessenger::kAcquireDemuxerHandle); - // Include the |handle_| in the callback so that it will persist even upon - // re-negotiation. - auto message_processor_callback = base::BindPostTask( - task_runner_, - base::BindRepeating( - &PlaybackCommandDispatcher::SendRemotingRpcMessageToRemote, - weak_factory_.GetWeakPtr(), handle_), - FROM_HERE); - call_translator_->SetMessageProcessor(std::move(message_processor_callback)); - - auto message_receiver_callback = base::BindPostTask( - task_runner_, - base::BindRepeating( - &PlaybackCommandDispatcher::ProcessRemotingRpcMessageFromRemote, - weak_factory_.GetWeakPtr()), - FROM_HERE); - messenger_->RegisterMessageReceiverCallback( - handle_, [cb = std::move(message_receiver_callback)]( - std::unique_ptr<openscreen::cast::RpcMessage> message) { - cb.Run(std::move(message)); - }); - + renderer_call_translator_->set_handle(AcquireHandle()); demuxer_stream_handler_ = std::make_unique<remoting::RpcDemuxerStreamHandler>( - this, messenger_, + this, + base::BindRepeating(&PlaybackCommandDispatcher::AcquireHandle, + base::Unretained(this)), base::BindRepeating( &PlaybackCommandDispatcher::SendRemotingRpcMessageToRemote, base::Unretained(this))); @@ -142,16 +131,14 @@ void PlaybackCommandDispatcher::OnRemotingSessionEnded() { demuxer_stream_handler_.reset(); - if (messenger_) { - messenger_->UnregisterMessageReceiverCallback(handle_); - messenger_ = nullptr; - } + messenger_ = nullptr; streaming_init_info_ = absl::nullopt; } void PlaybackCommandDispatcher::SendRemotingRpcMessageToRemote( openscreen::cast::RpcMessenger::Handle handle, std::unique_ptr<openscreen::cast::RpcMessage> message) { + DCHECK_NE(handle, openscreen::cast::RpcMessenger::kInvalidHandle); DCHECK(message); DCHECK(task_runner_->RunsTasksInCurrentSequence()); @@ -175,8 +162,9 @@ } const bool did_dispatch_as_renderer_call = - call_translator_ && - remoting::DispatchRendererRpcCall(message.get(), call_translator_.get()); + renderer_call_translator_ && + remoting::DispatchRendererRpcCall(message.get(), + renderer_call_translator_.get()); if (did_dispatch_as_renderer_call) { return; } @@ -192,6 +180,29 @@ LOG(ERROR) << "Unhandled RPC Message for command " << message->proc(); } +openscreen::cast::RpcMessenger::Handle +PlaybackCommandDispatcher::AcquireHandle() { + DCHECK(messenger_); + auto handle = messenger_->GetUniqueHandle(); + RegisterHandleForCallbacks(handle); + return handle; +} + +void PlaybackCommandDispatcher::RegisterHandleForCallbacks( + openscreen::cast::RpcMessenger::Handle handle) { + DCHECK(messenger_); + messenger_->RegisterMessageReceiverCallback( + handle, [ptr = weak_factory_.GetWeakPtr()]( + std::unique_ptr<openscreen::cast::RpcMessage> message) { + if (!ptr) { + DVLOG(1) + << "Message receiver has been invalidated. Dropping message."; + return; + } + ptr->ProcessRemotingRpcMessageFromRemote(std::move(message)); + }); +} + void PlaybackCommandDispatcher::OnSetPlaybackControllerDone() { has_set_playback_controller_call_returned_ = true; @@ -201,7 +212,11 @@ } void PlaybackCommandDispatcher::RpcAcquireRendererAsync(AcquireRendererCB cb) { - acquire_renderer_cb_ = base::BindOnce(std::move(cb), handle_); + DCHECK(renderer_call_translator_); + const auto handle = renderer_call_translator_->handle(); + + DCHECK_NE(handle, openscreen::cast::RpcMessenger::kInvalidHandle); + acquire_renderer_cb_ = base::BindOnce(std::move(cb), handle); if (has_set_playback_controller_call_returned_) { std::move(acquire_renderer_cb_).Run(); @@ -228,12 +243,7 @@ } streaming_init_info_->audio_stream_info->config = std::move(config); - if (!streaming_init_info_->video_stream_info || - !streaming_init_info_->video_stream_info->config.Matches( - media::VideoDecoderConfig())) { - // |streaming_init_info_| is intentionally copied here. - streaming_dispatcher_->StartStreamingSession(streaming_init_info_.value()); - } + MaybeStartStreamingSession(); } void PlaybackCommandDispatcher::OnNewVideoConfig( @@ -247,12 +257,34 @@ } streaming_init_info_->video_stream_info->config = std::move(config); - if (!streaming_init_info_->audio_stream_info || + MaybeStartStreamingSession(); +} + +void PlaybackCommandDispatcher::MaybeStartStreamingSession() { + DCHECK(streaming_init_info_); + const bool is_audio_config_ready = + !streaming_init_info_->audio_stream_info || !streaming_init_info_->audio_stream_info->config.Matches( - media::AudioDecoderConfig())) { - // |streaming_init_info_| is intentionally copied here. - streaming_dispatcher_->StartStreamingSession(streaming_init_info_.value()); + media::AudioDecoderConfig()); + const bool is_video_config_ready = + !streaming_init_info_->video_stream_info || + !streaming_init_info_->video_stream_info->config.Matches( + media::VideoDecoderConfig()); + if (!is_audio_config_ready || !is_video_config_ready) { + return; } + + DCHECK(demuxer_stream_handler_); + if (streaming_init_info_->audio_stream_info) { + demuxer_stream_handler_->RequestMoreAudioBuffers(); + } + if (streaming_init_info_->video_stream_info) { + demuxer_stream_handler_->RequestMoreVideoBuffers(); + } + + // |streaming_init_info_| is intentionally copied here. + DCHECK(streaming_dispatcher_); + streaming_dispatcher_->StartStreamingSession(streaming_init_info_.value()); } } // namespace cast_streaming
diff --git a/components/cast_streaming/browser/playback_command_dispatcher.h b/components/cast_streaming/browser/playback_command_dispatcher.h index bf6dae3f..9b26db2 100644 --- a/components/cast_streaming/browser/playback_command_dispatcher.h +++ b/components/cast_streaming/browser/playback_command_dispatcher.h
@@ -72,6 +72,17 @@ void ProcessRemotingRpcMessageFromRemote( std::unique_ptr<openscreen::cast::RpcMessage> message); + // Acquires a new handle from |messenger_|. + openscreen::cast::RpcMessenger::Handle AcquireHandle(); + + // Registers a |handle| with |messenger_| to receive callbacks to + // ProcessRemotingRpcMessageFromRemote(). + void RegisterHandleForCallbacks( + openscreen::cast::RpcMessenger::Handle handle); + + // Starts streaming if each expected audio or video config has been received. + void MaybeStartStreamingSession(); + // Callback for mojom::RendererController::SetPlaybackController() call. void OnSetPlaybackControllerDone(); @@ -90,14 +101,14 @@ base::OnceCallback<void()> acquire_renderer_cb_; openscreen::cast::RpcMessenger* messenger_; - openscreen::cast::RpcMessenger::Handle handle_; // Multiplexes Renderer commands from a number of senders. std::unique_ptr<RendererControlMultiplexer> muxer_; // Handles translating between Remoting commands (in proto form) and mojo // commands. - std::unique_ptr<remoting::RendererRpcCallTranslator> call_translator_; + std::unique_ptr<remoting::RendererRpcCallTranslator> + renderer_call_translator_; // Handles DemuxerStream interactions. std::unique_ptr<remoting::RpcDemuxerStreamHandler> demuxer_stream_handler_;
diff --git a/components/cast_streaming/browser/renderer_rpc_call_translator.cc b/components/cast_streaming/browser/renderer_rpc_call_translator.cc index 976ce4d..43189774 100644 --- a/components/cast_streaming/browser/renderer_rpc_call_translator.cc +++ b/components/cast_streaming/browser/renderer_rpc_call_translator.cc
@@ -10,31 +10,33 @@ namespace cast_streaming::remoting { RendererRpcCallTranslator::RendererRpcCallTranslator( + RpcMessageProcessor processor, mojo::Remote<media::mojom::Renderer> remote_renderer) - : renderer_client_receiver_(this), + : message_processor_(std::move(processor)), + renderer_client_receiver_(this), renderer_remote_(std::move(remote_renderer)), weak_factory_(this) {} RendererRpcCallTranslator::~RendererRpcCallTranslator() = default; -void RendererRpcCallTranslator::SetMessageProcessor( - RpcMessageProcessor processor) { - message_processor_ = std::move(processor); -} - void RendererRpcCallTranslator::OnRpcInitialize() { - renderer_remote_->Initialize( - renderer_client_receiver_.BindNewEndpointAndPassRemote(), - /* streams */ {}, /* media_url_params */ nullptr, - base::BindOnce(&RendererRpcCallTranslator::OnInitializeCompleted, - weak_factory_.GetWeakPtr(), message_processor_)); + if (!has_been_initialized_) { + has_been_initialized_ = true; + renderer_remote_->Initialize( + renderer_client_receiver_.BindNewEndpointAndPassRemote(), + /* streams */ {}, /* media_url_params */ nullptr, + base::BindOnce(&RendererRpcCallTranslator::OnInitializeCompleted, + weak_factory_.GetWeakPtr(), handle_)); + } else { + OnInitializeCompleted(handle_, true); + } } void RendererRpcCallTranslator::OnRpcFlush(uint32_t audio_count, uint32_t video_count) { renderer_remote_->Flush( base::BindOnce(&RendererRpcCallTranslator::OnFlushCompleted, - weak_factory_.GetWeakPtr(), message_processor_)); + weak_factory_.GetWeakPtr(), handle_)); } void RendererRpcCallTranslator::OnRpcStartPlayingFrom(base::TimeDelta time) { @@ -52,58 +54,60 @@ void RendererRpcCallTranslator::OnTimeUpdate(base::TimeDelta media_time, base::TimeDelta max_time, base::TimeTicks capture_time) { - message_processor_.Run(CreateMessageForMediaTimeUpdate(media_time)); + message_processor_.Run(handle_, CreateMessageForMediaTimeUpdate(media_time)); } void RendererRpcCallTranslator::OnBufferingStateChange( media::BufferingState state, media::BufferingStateChangeReason reason) { - message_processor_.Run(CreateMessageForBufferingStateChange(state)); + message_processor_.Run(handle_, CreateMessageForBufferingStateChange(state)); } void RendererRpcCallTranslator::OnError(const media::PipelineStatus& status) { - message_processor_.Run(CreateMessageForError()); + message_processor_.Run(handle_, CreateMessageForError()); } void RendererRpcCallTranslator::OnEnded() { - message_processor_.Run(CreateMessageForMediaEnded()); + message_processor_.Run(handle_, CreateMessageForMediaEnded()); } void RendererRpcCallTranslator::OnAudioConfigChange( const media::AudioDecoderConfig& config) { - message_processor_.Run(CreateMessageForAudioConfigChange(config)); + message_processor_.Run(handle_, CreateMessageForAudioConfigChange(config)); } void RendererRpcCallTranslator::OnVideoConfigChange( const media::VideoDecoderConfig& config) { - message_processor_.Run(CreateMessageForVideoConfigChange(config)); + message_processor_.Run(handle_, CreateMessageForVideoConfigChange(config)); } void RendererRpcCallTranslator::OnVideoNaturalSizeChange( const gfx::Size& size) { - message_processor_.Run(CreateMessageForVideoNaturalSizeChange(size)); + message_processor_.Run(handle_, CreateMessageForVideoNaturalSizeChange(size)); } void RendererRpcCallTranslator::OnVideoOpacityChange(bool opaque) { - message_processor_.Run(CreateMessageForVideoOpacityChange(opaque)); + message_processor_.Run(handle_, CreateMessageForVideoOpacityChange(opaque)); } void RendererRpcCallTranslator::OnStatisticsUpdate( const media::PipelineStatistics& stats) { - message_processor_.Run(CreateMessageForStatisticsUpdate(stats)); + message_processor_.Run(handle_, CreateMessageForStatisticsUpdate(stats)); } void RendererRpcCallTranslator::OnWaiting(media::WaitingReason reason) {} void RendererRpcCallTranslator::OnInitializeCompleted( - RpcMessageProcessor processor, + openscreen::cast::RpcMessenger::Handle handle_at_time_of_sending, bool success) { - message_processor_.Run(CreateMessageForInitializationComplete(success)); + message_processor_.Run(handle_at_time_of_sending, + CreateMessageForInitializationComplete(success)); } void RendererRpcCallTranslator::OnFlushCompleted( - RpcMessageProcessor processor) { - message_processor_.Run(CreateMessageForFlushComplete()); + openscreen::cast::RpcMessenger::Handle handle_at_time_of_sending) { + message_processor_.Run(handle_at_time_of_sending, + CreateMessageForFlushComplete()); } } // namespace cast_streaming::remoting
diff --git a/components/cast_streaming/browser/renderer_rpc_call_translator.h b/components/cast_streaming/browser/renderer_rpc_call_translator.h index fc26a80..6cb5a504 100644 --- a/components/cast_streaming/browser/renderer_rpc_call_translator.h +++ b/components/cast_streaming/browser/renderer_rpc_call_translator.h
@@ -28,18 +28,23 @@ public RpcRendererCallMessageHandler { public: using RpcMessageProcessor = base::RepeatingCallback<void( + openscreen::cast::RpcMessenger::Handle handle, std::unique_ptr<openscreen::cast::RpcMessage>)>; // |remote_renderer| is the remote media::mojom::Renderer to which commands // translated from proto messages should be sent. + // |processor| is responsible for handling any proto messages ready to be sent + // out. explicit RendererRpcCallTranslator( + RpcMessageProcessor processor, mojo::Remote<media::mojom::Renderer> remote_renderer); ~RendererRpcCallTranslator() override; - // |processor| is responsible for handling any proto messages ready to be sent - // out. This callback is expected to set the handle in each incoming message. - // This callback must be callable from any thread. - void SetMessageProcessor(RpcMessageProcessor processor); + // Sets the |handle| to be used for future outgoing RPC calls. + void set_handle(openscreen::cast::RpcMessenger::Handle handle) { + handle_ = handle; + } + openscreen::cast::RpcMessenger::Handle handle() const { return handle_; } private: // media::mojom::RendererClient overrides. @@ -65,11 +70,18 @@ void OnRpcSetPlaybackRate(double playback_rate) override; void OnRpcSetVolume(double volume) override; - // Callbacks for mojo calls. |processor| is included as an input so that if - // the callback changes before the response to this message is returned, it - // will send with the old |message_processor_| value. - void OnInitializeCompleted(RpcMessageProcessor processor, bool succeeded); - void OnFlushCompleted(RpcMessageProcessor processor); + // Callbacks for mojo calls. |handle_at_time_of_sending| is included as an + // input so that if |handle_| changes before the response to this message is + // returned, it will send with the old |handle_| value. + void OnInitializeCompleted( + openscreen::cast::RpcMessenger::Handle handle_at_time_of_sending, + bool succeeded); + void OnFlushCompleted( + openscreen::cast::RpcMessenger::Handle handle_at_time_of_sending); + + // Signifies whether the Initialize() command has been sent to the Renderer, + // which will only be done once over the duration of this instance's lifetime. + bool has_been_initialized_ = false; RpcMessageProcessor message_processor_; @@ -77,6 +89,9 @@ renderer_client_receiver_; mojo::Remote<media::mojom::Renderer> renderer_remote_; + openscreen::cast::RpcMessenger::Handle handle_ = + openscreen::cast::RpcMessenger::kInvalidHandle; + base::WeakPtrFactory<RendererRpcCallTranslator> weak_factory_; };
diff --git a/components/cast_streaming/browser/rpc_demuxer_stream_handler.cc b/components/cast_streaming/browser/rpc_demuxer_stream_handler.cc index 7b36dc2..70eb6ca 100644 --- a/components/cast_streaming/browser/rpc_demuxer_stream_handler.cc +++ b/components/cast_streaming/browser/rpc_demuxer_stream_handler.cc
@@ -19,13 +19,13 @@ RpcDemuxerStreamHandler::RpcDemuxerStreamHandler( Client* client, - openscreen::cast::RpcMessenger* rpc_messenger, + HandleFactory handle_factory, RpcProcessMessageCB message_processor) : client_(client), - rpc_messenger_(rpc_messenger), + handle_factory_(std::move(handle_factory)), message_processor_(std::move(message_processor)), weak_factory_(this) { - DCHECK(rpc_messenger_); + DCHECK(handle_factory_); DCHECK(message_processor_); } @@ -38,7 +38,7 @@ // initialize the DemuxerStreams. if (audio_stream_handle != openscreen::cast::RpcMessenger::kInvalidHandle) { audio_message_processor_ = std::make_unique<MessageProcessor>( - client_, rpc_messenger_->GetUniqueHandle(), audio_stream_handle, + client_, handle_factory_.Run(), audio_stream_handle, MessageProcessor::Type::kAudio); std::unique_ptr<openscreen::cast::RpcMessage> message = remoting::CreateMessageForDemuxerStreamInitialize( @@ -49,7 +49,7 @@ if (video_stream_handle != openscreen::cast::RpcMessenger::kInvalidHandle) { video_message_processor_ = std::make_unique<MessageProcessor>( - client_, rpc_messenger_->GetUniqueHandle(), video_stream_handle, + client_, handle_factory_.Run(), video_stream_handle, MessageProcessor::Type::kVideo); std::unique_ptr<openscreen::cast::RpcMessage> message = remoting::CreateMessageForDemuxerStreamInitialize(
diff --git a/components/cast_streaming/browser/rpc_demuxer_stream_handler.h b/components/cast_streaming/browser/rpc_demuxer_stream_handler.h index 4b81d31d..1a5b8a5 100644 --- a/components/cast_streaming/browser/rpc_demuxer_stream_handler.h +++ b/components/cast_streaming/browser/rpc_demuxer_stream_handler.h
@@ -35,13 +35,15 @@ virtual void OnNewVideoConfig(media::VideoDecoderConfig new_config) = 0; }; - // Creates a new instance of this class. |client| and |rpc_messenger| are both - // expected to outlive this class. + // Creates a new instance of this class. |client| is expected to outlive this + // class. + using HandleFactory = + base::RepeatingCallback<openscreen::cast::RpcMessenger::Handle()>; using RpcProcessMessageCB = base::RepeatingCallback<void( openscreen::cast::RpcMessenger::Handle, std::unique_ptr<openscreen::cast::RpcMessage>)>; RpcDemuxerStreamHandler(Client* client, - openscreen::cast::RpcMessenger* rpc_messenger, + HandleFactory handle_factory, RpcProcessMessageCB message_processor); ~RpcDemuxerStreamHandler() override; @@ -111,7 +113,7 @@ uint32_t total_frames_received_ = 0; - bool is_read_until_call_pending_ = true; + bool is_read_until_call_pending_ = false; }; // Helpers for the above methods of the same name. @@ -130,7 +132,7 @@ uint32_t total_frames_received) override; Client* const client_; - openscreen::cast::RpcMessenger* const rpc_messenger_; + HandleFactory handle_factory_; RpcProcessMessageCB message_processor_; std::unique_ptr<MessageProcessor> audio_message_processor_;
diff --git a/components/cast_streaming/browser/rpc_demuxer_stream_handler_unittests.cc b/components/cast_streaming/browser/rpc_demuxer_stream_handler_unittests.cc index a9d0bc5..8305553 100644 --- a/components/cast_streaming/browser/rpc_demuxer_stream_handler_unittests.cc +++ b/components/cast_streaming/browser/rpc_demuxer_stream_handler_unittests.cc
@@ -29,7 +29,7 @@ namespace cast_streaming::remoting { namespace { -ACTION_P(CheckInitializeDemuxerStream, remote_handle, local_handle_ptr) { +ACTION_P(CheckInitializeDemuxerStream, remote_handle, local_handle) { const openscreen::cast::RpcMessenger::Handle handle = arg0; const std::unique_ptr<openscreen::cast::RpcMessage>& rpc = arg1; @@ -37,8 +37,7 @@ EXPECT_EQ(rpc->proc(), openscreen::cast::RpcMessage::RPC_DS_INITIALIZE); EXPECT_EQ(handle, remote_handle); ASSERT_TRUE(rpc->has_integer_value()); - *local_handle_ptr = rpc->integer_value(); - EXPECT_NE(*local_handle_ptr, openscreen::cast::RpcMessenger::kInvalidHandle); + EXPECT_EQ(local_handle, rpc->integer_value()); } ACTION_P(CheckReadUntilCall, remote_handle, local_handle, last_total) { @@ -84,19 +83,21 @@ {1920, 1080}, media::EmptyExtraData(), media::EncryptionScheme::kUnencrypted), - rpc_messenger_( - [](auto data) { FAIL() << "Messages should not be sent here"; }), stream_handler_( &client_, - &rpc_messenger_, + base::BindRepeating(&RpcDemuxerStreamHandlerTest::GetHandle, + base::Unretained(this)), base::BindRepeating(&RpcDemuxerStreamHandlerTest::SendMessage, base::Unretained(this))) { + EXPECT_CALL(*this, GetHandle()) + .WillOnce(Return(audio_local_handle_)) + .WillOnce(Return(video_local_handle_)); EXPECT_CALL(*this, SendMessage(audio_remote_handle_, _)) .WillOnce(CheckInitializeDemuxerStream(audio_remote_handle_, - &audio_local_handle_)); + audio_local_handle_)); EXPECT_CALL(*this, SendMessage(video_remote_handle_, _)) .WillOnce(CheckInitializeDemuxerStream(video_remote_handle_, - &video_local_handle_)); + video_local_handle_)); stream_handler_.OnRpcAcquireDemuxer(audio_remote_handle_, video_remote_handle_); } @@ -116,6 +117,8 @@ void(openscreen::cast::RpcMessenger::Handle, std::unique_ptr<openscreen::cast::RpcMessage>)); + MOCK_METHOD0(GetHandle, openscreen::cast::RpcMessenger::Handle()); + void OnRpcInitializeCallback( openscreen::cast::RpcMessenger::Handle handle, absl::optional<media::AudioDecoderConfig> audio_config, @@ -139,13 +142,12 @@ openscreen::cast::RpcMessenger::Handle audio_remote_handle_ = 123; openscreen::cast::RpcMessenger::Handle video_remote_handle_ = 456; - openscreen::cast::RpcMessenger::Handle audio_local_handle_; - openscreen::cast::RpcMessenger::Handle video_local_handle_; + openscreen::cast::RpcMessenger::Handle audio_local_handle_ = 135; + openscreen::cast::RpcMessenger::Handle video_local_handle_ = 246; media::AudioDecoderConfig test_audio_config_; media::VideoDecoderConfig test_video_config_; - openscreen::cast::RpcMessenger rpc_messenger_; StrictMock<MockClient> client_; RpcDemuxerStreamHandler stream_handler_;
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index b7b6875a..ef3da3a 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@ { - "version": "9.8", - "log_list_timestamp": "2022-05-10T12:55:35Z", + "version": "9.10", + "log_list_timestamp": "2022-05-12T12:56:00Z", "operators": [ { "name": "Google",
diff --git a/components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/UrlConstants.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/UrlConstants.java index e056245..d1c2514 100644 --- a/components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/UrlConstants.java +++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/UrlConstants.java
@@ -75,6 +75,8 @@ public static final String GPU_URL = "chrome://gpu/"; public static final String VERSION_URL = "chrome://version/"; + public static final String GOOGLE_ACCOUNT_HOME_URL = "https://myaccount.google.com/"; + public static final String GOOGLE_ACCOUNT_ACTIVITY_CONTROLS_URL = "https://myaccount.google.com/activitycontrols/search";
diff --git a/components/enterprise/browser/reporting/policy_info.cc b/components/enterprise/browser/reporting/policy_info.cc index cc7ed94..d9156637 100644 --- a/components/enterprise/browser/reporting/policy_info.cc +++ b/components/enterprise/browser/reporting/policy_info.cc
@@ -108,24 +108,23 @@ } // namespace void AppendChromePolicyInfoIntoProfileReport( - const base::Value& policies, + const base::Value::Dict& policies, em::ChromeUserProfileInfo* profile_info) { - for (auto policy_iter : policies.FindKey("chromePolicies")->DictItems()) { + for (auto policy_iter : *policies.FindDict("chromePolicies")) { UpdatePolicyInfo(profile_info->add_chrome_policies(), policy_iter.first, policy_iter.second); } } void AppendExtensionPolicyInfoIntoProfileReport( - const base::Value& policies, + const base::Value::Dict& policies, em::ChromeUserProfileInfo* profile_info) { - if (!policies.FindKey("extensionPolicies")) { + if (!policies.Find("extensionPolicies")) { // Android and iOS don't support extensions and their policies. return; } - for (auto extension_iter : - policies.FindKey("extensionPolicies")->DictItems()) { + for (auto extension_iter : *policies.FindDict("extensionPolicies")) { const base::Value& policies_value = extension_iter.second; if (policies_value.DictSize() == 0) continue;
diff --git a/components/enterprise/browser/reporting/policy_info.h b/components/enterprise/browser/reporting/policy_info.h index 82a5fa9..820ef51 100644 --- a/components/enterprise/browser/reporting/policy_info.h +++ b/components/enterprise/browser/reporting/policy_info.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_ENTERPRISE_BROWSER_REPORTING_POLICY_INFO_H_ #define COMPONENTS_ENTERPRISE_BROWSER_REPORTING_POLICY_INFO_H_ +#include "base/values.h" #include "components/policy/proto/device_management_backend.pb.h" namespace base { @@ -20,11 +21,11 @@ namespace enterprise_reporting { void AppendChromePolicyInfoIntoProfileReport( - const base::Value& policies, + const base::Value::Dict& policies, enterprise_management::ChromeUserProfileInfo* profile_info); void AppendExtensionPolicyInfoIntoProfileReport( - const base::Value& policies, + const base::Value::Dict& policies, enterprise_management::ChromeUserProfileInfo* profile_info); void AppendMachineLevelUserCloudPolicyFetchTimestamp(
diff --git a/components/enterprise/browser/reporting/profile_report_generator.cc b/components/enterprise/browser/reporting/profile_report_generator.cc index 3a88bc352..b28fd89d 100644 --- a/components/enterprise/browser/reporting/profile_report_generator.cc +++ b/components/enterprise/browser/reporting/profile_report_generator.cc
@@ -72,7 +72,7 @@ policies_ = policy::DictionaryPolicyConversions(std::move(client)) .EnableConvertTypes(false) .EnablePrettyPrint(false) - .ToValue(); + .ToValueDict(); GetChromePolicyInfo(); GetExtensionPolicyInfo(); GetPolicyFetchTimestampInfo();
diff --git a/components/enterprise/browser/reporting/profile_report_generator.h b/components/enterprise/browser/reporting/profile_report_generator.h index d5faeaad..c96480c0 100644 --- a/components/enterprise/browser/reporting/profile_report_generator.h +++ b/components/enterprise/browser/reporting/profile_report_generator.h
@@ -83,7 +83,7 @@ private: std::unique_ptr<Delegate> delegate_; - base::Value policies_; + base::Value::Dict policies_; bool extensions_enabled_ = true; bool policies_enabled_ = true;
diff --git a/components/history/core/browser/history_types.h b/components/history/core/browser/history_types.h index bc6bfc72..75d66ce 100644 --- a/components/history/core/browser/history_types.h +++ b/components/history/core/browser/history_types.h
@@ -861,6 +861,11 @@ // Which positions matched the search query in various fields. query_parser::Snippet::MatchPositions title_match_positions; query_parser::Snippet::MatchPositions url_for_display_match_positions; + + // If true, the visit should be "below the fold" and not initially shown in + // any UI. It is still included in the cluster so that it can be queried over, + // as well as deleted when the whole cluster is deleted. + bool hidden = false; }; // A cluster of `ClusterVisit`s with associated metadata (i.e. `keywords` and @@ -893,6 +898,11 @@ // The positions within the label that match the search query, if it exists. query_parser::Snippet::MatchPositions label_match_positions; + // The vector of related searches for the whole cluster. This is derived from + // the related searches of the constituent visits, and computed in + // cross-platform code so we have a consistent set across platforms. + std::vector<std::string> related_searches; + // A floating point score that's positive if the cluster matches the user's // search query, and zero otherwise. This score changes depending on the // entered search query, so this should never be persisted. It's a
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h index 6f3e8b2..490a6d06 100644 --- a/components/history_clusters/core/config.h +++ b/components/history_clusters/core/config.h
@@ -13,6 +13,10 @@ // The default configuration. Always use |GetConfig()| to get the current // configuration. +// +// Config has the same thread-safety as base::FeatureList. The first call to +// GetConfig() (which performs initialization) must be done single threaded on +// the main thread. After that, Config can be read from any thread. struct Config { // True if journeys feature is enabled as per field trial check. Does not // check for any user-specific conditions (such as locales).
diff --git a/components/history_clusters/core/history_clusters_service_test_api.cc b/components/history_clusters/core/history_clusters_service_test_api.cc index 1fad8545..d62cc74 100644 --- a/components/history_clusters/core/history_clusters_service_test_api.cc +++ b/components/history_clusters/core/history_clusters_service_test_api.cc
@@ -100,7 +100,8 @@ return visits; } -history::ClusterVisit GetHardcodedClusterVisit(history::VisitID visit_id) { +history::ClusterVisit GetHardcodedClusterVisit(history::VisitID visit_id, + float score) { const auto& visits = GetHardcodedTestVisits(); for (const auto& visit : visits) { if (visit.visit_row.visit_id != visit_id) @@ -111,7 +112,7 @@ cluster_visit.normalized_url = visit.url_row.url(); cluster_visit.url_for_deduping = ComputeURLForDeduping(cluster_visit.normalized_url); - cluster_visit.score = 0.5; + cluster_visit.score = score; return cluster_visit; }
diff --git a/components/history_clusters/core/history_clusters_service_test_api.h b/components/history_clusters/core/history_clusters_service_test_api.h index 8a4f0c78..5edd691 100644 --- a/components/history_clusters/core/history_clusters_service_test_api.h +++ b/components/history_clusters/core/history_clusters_service_test_api.h
@@ -66,7 +66,8 @@ std::vector<history::AnnotatedVisit> GetHardcodedTestVisits(); // Fetches the hardcoded `ClusterVisit` with ID `visit_id`. -history::ClusterVisit GetHardcodedClusterVisit(history::VisitID visit_id); +history::ClusterVisit GetHardcodedClusterVisit(history::VisitID visit_id, + float score = 0.5); } // namespace history_clusters
diff --git a/components/history_clusters/core/history_clusters_util.cc b/components/history_clusters/core/history_clusters_util.cc index 2f5bdf6..d23640b 100644 --- a/components/history_clusters/core/history_clusters_util.cc +++ b/components/history_clusters/core/history_clusters_util.cc
@@ -6,6 +6,7 @@ #include <algorithm> +#include "base/containers/contains.h" #include "base/i18n/case_conversion.h" #include "base/ranges/algorithm.h" #include "base/strings/string_piece.h" @@ -101,9 +102,8 @@ // // Note, this should NOT be called for `cluster_visits` with NO matching visits. void PromoteMatchingVisitsAboveNonMatchingVisits( - std::vector<history::ClusterVisit>* cluster_visits) { - DCHECK(cluster_visits); - for (auto& visit : *cluster_visits) { + std::vector<history::ClusterVisit>& cluster_visits) { + for (auto& visit : cluster_visits) { if (visit.matches_search_query) { // Smash all matching scores into the range that's above the fold. visit.score = @@ -169,9 +169,8 @@ nullptr, nullptr, nullptr); } -void StableSortVisits(std::vector<history::ClusterVisit>* visits) { - DCHECK(visits); - base::ranges::stable_sort(*visits, [](auto& v1, auto& v2) { +void StableSortVisits(std::vector<history::ClusterVisit>& visits) { + base::ranges::stable_sort(visits, [](auto& v1, auto& v2) { if (v1.score != v2.score) { // Use v1 > v2 to get higher scored visits BEFORE lower scored visits. return v1.score > v2.score; @@ -184,8 +183,7 @@ } void ApplySearchQuery(const std::string& query, - std::vector<history::Cluster>* clusters) { - DCHECK(clusters); + std::vector<history::Cluster>& clusters) { if (query.empty()) return; @@ -198,7 +196,7 @@ // Move all the passed in `clusters` into `all_clusters`, and start rebuilding // `clusters` to only contain the matching ones. std::vector<history::Cluster> all_clusters; - std::swap(all_clusters, *clusters); + std::swap(all_clusters, clusters); for (auto& cluster : all_clusters) { const float total_matching_visit_score = @@ -206,7 +204,7 @@ DCHECK_GE(total_matching_visit_score, 0); if (total_matching_visit_score > 0 && GetConfig().rescore_visits_within_clusters_for_query) { - PromoteMatchingVisitsAboveNonMatchingVisits(&cluster.visits); + PromoteMatchingVisitsAboveNonMatchingVisits(cluster.visits); } cluster.search_match_score = total_matching_visit_score; @@ -219,12 +217,12 @@ if (cluster.search_match_score > 0) { // Move the matching clusters into the final list. - clusters->push_back(std::move(cluster)); + clusters.push_back(std::move(cluster)); } } if (GetConfig().sort_clusters_within_batch_for_query) { - base::ranges::stable_sort(*clusters, [](auto& c1, auto& c2) { + base::ranges::stable_sort(clusters, [](auto& c1, auto& c2) { // Use c1 > c2 to get higher scored clusters BEFORE lower scored clusters. return c1.search_match_score > c2.search_match_score; }); @@ -233,37 +231,81 @@ void CullNonProminentOrDuplicateClusters( std::string query, - std::vector<history::Cluster>* clusters, + std::vector<history::Cluster>& clusters, std::set<GURL>* seen_single_visit_cluster_urls) { - DCHECK(clusters); DCHECK(seen_single_visit_cluster_urls); if (query.empty()) { // For the empty-query state, only show clusters with // `should_show_on_prominent_ui_surfaces` set to true. This restriction is // NOT applied when the user is searching for a specific keyword. - clusters->erase(base::ranges::remove_if( - *clusters, - [](const history::Cluster& cluster) { - return !cluster.should_show_on_prominent_ui_surfaces; - }), - clusters->end()); + clusters.erase(base::ranges::remove_if( + clusters, + [](const history::Cluster& cluster) { + return !cluster.should_show_on_prominent_ui_surfaces; + }), + clusters.end()); } else { - clusters->erase(base::ranges::remove_if( - *clusters, - [&](const history::Cluster& cluster) { - // Erase all duplicate single-visit non-prominent - // clusters. - if (!cluster.should_show_on_prominent_ui_surfaces && - cluster.visits.size() == 1) { - auto [unused_iterator, newly_inserted] = - seen_single_visit_cluster_urls->insert( - cluster.visits[0].url_for_deduping); - return !newly_inserted; - } + clusters.erase(base::ranges::remove_if( + clusters, + [&](const history::Cluster& cluster) { + // Erase all duplicate single-visit non-prominent + // clusters. + if (!cluster.should_show_on_prominent_ui_surfaces && + cluster.visits.size() == 1) { + auto [unused_iterator, newly_inserted] = + seen_single_visit_cluster_urls->insert( + cluster.visits[0].url_for_deduping); + return !newly_inserted; + } - return false; - }), - clusters->end()); + return false; + }), + clusters.end()); + } +} + +void HideAndCullLowScoringVisits(std::vector<history::Cluster>& clusters) { + for (auto& cluster : clusters) { + for (size_t i = 0; i < cluster.visits.size(); ++i) { + auto& visit = cluster.visits[i]; + // Even a 0.0 visit shouldn't be hidden if this is the first visit we + // encounter. The assumption is that the visits are always ranked by score + // in a descending order. + // TODO(crbug.com/1313631): Simplify this after removing "Show More" UI. + if ((visit.score == 0.0 && i != 0) || + (visit.score < GetConfig().min_score_to_always_show_above_the_fold && + i >= GetConfig().num_visits_to_always_show_above_the_fold)) { + visit.hidden = true; + } + } + + if (GetConfig().drop_hidden_visits) { + cluster.visits.erase( + base::ranges::remove_if( + cluster.visits, [](const auto& visit) { return visit.hidden; }), + cluster.visits.end()); + } + } +} + +void CoalesceRelatedSearches(std::vector<history::Cluster>& clusters) { + constexpr size_t kMaxRelatedSearches = 5; + + for (auto& cluster : clusters) { + for (const auto& visit : cluster.visits) { + // Coalesce the unique related searches of this visit into the cluster + // until the cap is reached. + for (const auto& search_query : + visit.annotated_visit.content_annotations.related_searches) { + if (cluster.related_searches.size() >= kMaxRelatedSearches) { + return; + } + + if (!base::Contains(cluster.related_searches, search_query)) { + cluster.related_searches.push_back(search_query); + } + } + } } }
diff --git a/components/history_clusters/core/history_clusters_util.h b/components/history_clusters/core/history_clusters_util.h index 1f0c682..88ec4487 100644 --- a/components/history_clusters/core/history_clusters_util.h +++ b/components/history_clusters/core/history_clusters_util.h
@@ -37,14 +37,14 @@ bool trim_after_host = false); // Stable sorts visits according to score, then reverse-chronologically. -void StableSortVisits(std::vector<history::ClusterVisit>* visits); +void StableSortVisits(std::vector<history::ClusterVisit>& visits); // Erases all clusters that don't match `query`. Also may re-score the visits // within matching clusters. // // If `query` is an empty string, leaves `clusters` unmodified. void ApplySearchQuery(const std::string& query, - std::vector<history::Cluster>* clusters); + std::vector<history::Cluster>& clusters); // If `query` is empty, erases all non-prominent clusters. // @@ -54,9 +54,16 @@ // `seen_single_visit_cluster_urls` and this function updates that set. void CullNonProminentOrDuplicateClusters( std::string query, - std::vector<history::Cluster>* clusters, + std::vector<history::Cluster>& clusters, std::set<GURL>* seen_single_visit_cluster_urls); +// Marks low scoring visits as hidden, and drops them if necessary. +void HideAndCullLowScoringVisits(std::vector<history::Cluster>& clusters); + +// Coalesces the related searches off of individual visits and places them at +// the cluster level with numerical limits defined by flags. +void CoalesceRelatedSearches(std::vector<history::Cluster>& clusters); + } // namespace history_clusters #endif // COMPONENTS_HISTORY_CLUSTERS_CORE_HISTORY_CLUSTERS_UTIL_H_
diff --git a/components/history_clusters/core/history_clusters_util_unittest.cc b/components/history_clusters/core/history_clusters_util_unittest.cc index a522a51..d3eda43 100644 --- a/components/history_clusters/core/history_clusters_util_unittest.cc +++ b/components/history_clusters/core/history_clusters_util_unittest.cc
@@ -117,7 +117,7 @@ test_data[i].query.c_str())); auto clusters = all_clusters; - ApplySearchQuery(test_data[i].query, &clusters); + ApplySearchQuery(test_data[i].query, clusters); size_t expected_size = static_cast<size_t>(test_data[i].expect_first_cluster) + @@ -150,7 +150,7 @@ // No promotion when we match a keyword. { std::vector clusters = all_clusters; - ApplySearchQuery("apples", &clusters); + ApplySearchQuery("apples", clusters); ASSERT_EQ(clusters.size(), 1U); ASSERT_EQ(clusters[0].visits.size(), 2U); EXPECT_EQ(clusters[0].visits[0].annotated_visit.visit_row.visit_id, 1); @@ -162,7 +162,7 @@ // Promote the second visit over the first if we match the second visit. { std::vector clusters = all_clusters; - ApplySearchQuery("git", &clusters); + ApplySearchQuery("git", clusters); ASSERT_EQ(clusters.size(), 1U); ASSERT_EQ(clusters[0].visits.size(), 2U); EXPECT_EQ(clusters[0].visits[0].annotated_visit.visit_row.visit_id, 2); @@ -197,7 +197,7 @@ SetConfigForTesting(config); std::vector clusters = all_clusters; - ApplySearchQuery("search", &clusters); + ApplySearchQuery("search", clusters); ASSERT_EQ(clusters.size(), 2U); EXPECT_EQ(clusters[0].cluster_id, 1); EXPECT_EQ(clusters[1].cluster_id, 2); @@ -213,7 +213,7 @@ SetConfigForTesting(config); std::vector clusters = all_clusters; - ApplySearchQuery("search", &clusters); + ApplySearchQuery("search", clusters); ASSERT_EQ(clusters.size(), 2U); EXPECT_EQ(clusters[0].cluster_id, 2); EXPECT_EQ(clusters[1].cluster_id, 1); @@ -228,7 +228,7 @@ SetConfigForTesting(config); std::vector clusters = all_clusters; - ApplySearchQuery("google", &clusters); + ApplySearchQuery("google", clusters); ASSERT_EQ(clusters.size(), 2U); EXPECT_EQ(clusters[0].cluster_id, 1); EXPECT_EQ(clusters[1].cluster_id, 2); @@ -237,5 +237,100 @@ } } +TEST(HistoryClustersUtilTest, HideAndCullLowScoringVisits) { + std::vector<history::Cluster> clusters; + + // High scoring visits should always be above the fold. + history::Cluster cluster1; + cluster1.cluster_id = 4; + cluster1.visits.push_back(GetHardcodedClusterVisit(1, 1)); + cluster1.visits.push_back(GetHardcodedClusterVisit(1, .8)); + cluster1.visits.push_back(GetHardcodedClusterVisit(1, .5)); + cluster1.visits.push_back(GetHardcodedClusterVisit(1, .5)); + cluster1.visits.push_back(GetHardcodedClusterVisit(1, .5)); + cluster1.keywords.push_back(u"keyword"); + + // Low scoring visits should be above the fold only if they're one of top 4. + history::Cluster cluster2; + cluster2.cluster_id = 6; + cluster2.visits.push_back(GetHardcodedClusterVisit(1, .4)); + cluster2.visits.push_back(GetHardcodedClusterVisit(1, .4)); + cluster2.visits.push_back(GetHardcodedClusterVisit(1, .4)); + cluster2.visits.push_back(GetHardcodedClusterVisit(1, .4)); + cluster2.visits.push_back(GetHardcodedClusterVisit(1, .4)); + cluster2.keywords.push_back(u"keyword"); + + // 0 scoring visits should be above the fold only if they're 1st. + history::Cluster cluster3; + cluster3.cluster_id = 8; + cluster3.visits.push_back(GetHardcodedClusterVisit(1, 0.0)); + cluster3.visits.push_back(GetHardcodedClusterVisit(1, 0.0)); + cluster3.keywords.push_back(u"keyword"); + + clusters.push_back(cluster1); + clusters.push_back(cluster2); + clusters.push_back(cluster3); + + HideAndCullLowScoringVisits(clusters); + + { + EXPECT_EQ(clusters[0].cluster_id, 4); + const auto& visits = clusters[0].visits; + ASSERT_EQ(visits.size(), 5u); + EXPECT_EQ(visits[0].hidden, false); + EXPECT_EQ(visits[1].hidden, false); + EXPECT_EQ(visits[2].hidden, false); + EXPECT_EQ(visits[3].hidden, false); + EXPECT_EQ(visits[4].hidden, false); + } + + { + EXPECT_EQ(clusters[1].cluster_id, 6); + const auto& visits = clusters[1].visits; + ASSERT_EQ(visits.size(), 5u); + EXPECT_EQ(visits[0].hidden, false); + EXPECT_EQ(visits[1].hidden, false); + EXPECT_EQ(visits[2].hidden, false); + EXPECT_EQ(visits[3].hidden, false); + EXPECT_EQ(visits[4].hidden, true); + } + + { + EXPECT_EQ(clusters[2].cluster_id, 8); + ASSERT_EQ(clusters[2].visits.size(), 2u); + EXPECT_EQ(clusters[2].visits[0].hidden, false); + EXPECT_EQ(clusters[2].visits[1].hidden, true); + } +} + +TEST(HistoryClustersUtilTest, CoalesceRelatedSearches) { + // canonical_visit has the same URL as Visit1. + history::ClusterVisit visit1 = GetHardcodedClusterVisit(1); + visit1.annotated_visit.content_annotations.related_searches.push_back( + "search1"); + visit1.annotated_visit.content_annotations.related_searches.push_back( + "search2"); + visit1.annotated_visit.content_annotations.related_searches.push_back( + "search3"); + + history::ClusterVisit visit2 = GetHardcodedClusterVisit(2); + visit2.annotated_visit.content_annotations.related_searches.push_back( + "search4"); + visit2.annotated_visit.content_annotations.related_searches.push_back( + "search5"); + visit2.annotated_visit.content_annotations.related_searches.push_back( + "search6"); + + history::Cluster cluster; + cluster.visits = {visit1, visit2}; + std::vector<history::Cluster> clusters; + clusters.push_back(cluster); + + CoalesceRelatedSearches(clusters); + EXPECT_THAT(clusters[0].related_searches, + testing::ElementsAre("search1", "search2", "search3", "search4", + "search5")); +} + } // namespace } // namespace history_clusters
diff --git a/components/history_clusters/core/on_device_clustering_util.cc b/components/history_clusters/core/on_device_clustering_util.cc index a1c325f..faf9a8d 100644 --- a/components/history_clusters/core/on_device_clustering_util.cc +++ b/components/history_clusters/core/on_device_clustering_util.cc
@@ -83,7 +83,7 @@ DCHECK(clusters); // Within each cluster, sort visits. for (auto& cluster : *clusters) { - StableSortVisits(&cluster.visits); + StableSortVisits(cluster.visits); } // After that, sort clusters reverse-chronologically based on their highest
diff --git a/components/history_clusters/core/query_clusters_state.cc b/components/history_clusters/core/query_clusters_state.cc index 80a1ffd35..e16b694f 100644 --- a/components/history_clusters/core/query_clusters_state.cc +++ b/components/history_clusters/core/query_clusters_state.cc
@@ -30,9 +30,16 @@ std::vector<history::Cluster> PostProcess( std::vector<history::Cluster> clusters) { - ApplySearchQuery(query_, &clusters); - CullNonProminentOrDuplicateClusters(query_, &clusters, + ApplySearchQuery(query_, clusters); + CullNonProminentOrDuplicateClusters(query_, clusters, &seen_single_visit_cluster_urls_); + // We have to do this AFTER applying the search query, because applying the + // search query re-scores matching visits to promote them above non-matching + // visits. + HideAndCullLowScoringVisits(clusters); + // Do this AFTER we cull the low scoring visits, so those visits don't get + // their related searches coalesced onto the cluster level. + CoalesceRelatedSearches(clusters); return clusters; }
diff --git a/components/metrics/field_trials_provider.cc b/components/metrics/field_trials_provider.cc index 26936025..e55dea9 100644 --- a/components/metrics/field_trials_provider.cc +++ b/components/metrics/field_trials_provider.cc
@@ -35,7 +35,6 @@ void FieldTrialsProvider::GetFieldTrialIds( std::vector<ActiveGroupId>* field_trial_ids) const { - // We use the default field trial suffixing (no suffix). variations::GetFieldTrialActiveGroupIds(suffix_, field_trial_ids); } @@ -89,7 +88,7 @@ if (registry_) { std::vector<ActiveGroupId> synthetic_trials; registry_->GetSyntheticFieldTrialsOlderThan(log_creation_time_, - &synthetic_trials); + &synthetic_trials, suffix_); WriteFieldTrials(synthetic_trials, system_profile_proto); } }
diff --git a/components/metrics/field_trials_provider.h b/components/metrics/field_trials_provider.h index 56f869a..12eb221f 100644 --- a/components/metrics/field_trials_provider.h +++ b/components/metrics/field_trials_provider.h
@@ -43,9 +43,9 @@ void SetLogCreationTimeForTesting(base::TimeTicks time); private: - // Overrideable for testing. - virtual void GetFieldTrialIds( - std::vector<ActiveGroupId>* field_trial_ids) const; + // Populates |field_trial_ids| with currently active field trials groups. The + // trial and group names are suffixed with |suffix_| before being hashed. + void GetFieldTrialIds(std::vector<ActiveGroupId>* field_trial_ids) const; // Gets active FieldTrials and SyntheticFieldTrials and populates // |system_profile_proto| with them.
diff --git a/components/metrics/field_trials_provider_unittest.cc b/components/metrics/field_trials_provider_unittest.cc index 4341b01..dbc26a5a 100644 --- a/components/metrics/field_trials_provider_unittest.cc +++ b/components/metrics/field_trials_provider_unittest.cc
@@ -4,6 +4,7 @@ #include "components/metrics/field_trials_provider.h" +#include "base/metrics/field_trial.h" #include "base/threading/platform_thread.h" #include "components/variations/active_field_trials.h" #include "components/variations/synthetic_trial_registry.h" @@ -11,38 +12,36 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/metrics_proto/system_profile.pb.h" +using ActiveGroup = base::FieldTrial::ActiveGroup; + namespace variations { namespace { -const ActiveGroupId kFieldTrialIds[] = {MakeActiveGroupId("Trial1", "Group1"), - MakeActiveGroupId("Trial2", "Group2"), - MakeActiveGroupId("Trial3", "Group3")}; -const SyntheticTrialGroup kSyntheticFieldTrials[] = { - SyntheticTrialGroup("Synthetic1", - "SyntheticGroup1", - variations::SyntheticTrialAnnotationMode::kNextLog), - SyntheticTrialGroup("Synthetic2", - "SyntheticGroup2", - variations::SyntheticTrialAnnotationMode::kNextLog)}; +constexpr const char* kSuffix = "UKM"; + +const ActiveGroup kFieldTrials[] = {{"Trial1", "Group1"}, + {"Trial2", "Group2"}, + {"Trial3", "Group3"}}; +const ActiveGroup kSyntheticFieldTrials[] = {{"Synthetic1", "SyntheticGroup1"}, + {"Synthetic2", "SyntheticGroup2"}}; + +ActiveGroupId ToActiveGroupId(ActiveGroup active_group, + std::string suffix = ""); + +const ActiveGroupId kFieldTrialIds[] = {ToActiveGroupId(kFieldTrials[0]), + ToActiveGroupId(kFieldTrials[1]), + ToActiveGroupId(kFieldTrials[2])}; const ActiveGroupId kAllTrialIds[] = { - kFieldTrialIds[0], kFieldTrialIds[1], kFieldTrialIds[2], - kSyntheticFieldTrials[0].id(), kSyntheticFieldTrials[1].id()}; - -class TestProvider : public FieldTrialsProvider { - public: - TestProvider(SyntheticTrialRegistry* registry, base::StringPiece suffix) - : FieldTrialsProvider(registry, suffix) {} - ~TestProvider() override {} - - void GetFieldTrialIds( - std::vector<ActiveGroupId>* field_trial_ids) const override { - ASSERT_TRUE(field_trial_ids->empty()); - for (const ActiveGroupId& id : kFieldTrialIds) { - field_trial_ids->push_back(id); - } - } -}; + ToActiveGroupId(kFieldTrials[0]), ToActiveGroupId(kFieldTrials[1]), + ToActiveGroupId(kFieldTrials[2]), ToActiveGroupId(kSyntheticFieldTrials[0]), + ToActiveGroupId(kSyntheticFieldTrials[1])}; +const ActiveGroupId kAllTrialIdsWithSuffixes[] = { + ToActiveGroupId(kFieldTrials[0], kSuffix), + ToActiveGroupId(kFieldTrials[1], kSuffix), + ToActiveGroupId(kFieldTrials[2], kSuffix), + ToActiveGroupId(kSyntheticFieldTrials[0], kSuffix), + ToActiveGroupId(kSyntheticFieldTrials[1], kSuffix)}; // Check that the field trials in |system_profile| correspond to |expected|. void CheckFieldTrialsInSystemProfile( @@ -56,24 +55,43 @@ } } +ActiveGroupId ToActiveGroupId(ActiveGroup active_group, std::string suffix) { + return MakeActiveGroupId(active_group.trial_name + suffix, + active_group.group_name + suffix); +} + } // namespace class FieldTrialsProviderTest : public ::testing::Test { public: - FieldTrialsProviderTest() {} - ~FieldTrialsProviderTest() override {} + FieldTrialsProviderTest() = default; + ~FieldTrialsProviderTest() override = default; protected: + void SetUp() override { + // Register the field trials. + for (const ActiveGroup& trial : kFieldTrials) { + base::FieldTrial* field_trial = base::FieldTrialList::CreateFieldTrial( + trial.trial_name, trial.group_name); + // Call group() to finalize and mark the field trial as active. + field_trial->group(); + } + } + // Register trials which should get recorded. void RegisterExpectedSyntheticTrials() { - for (const SyntheticTrialGroup& synthetic_trial : kSyntheticFieldTrials) { - registry_.RegisterSyntheticFieldTrial(synthetic_trial); + for (const ActiveGroup& trial : kSyntheticFieldTrials) { + registry_.RegisterSyntheticFieldTrial(SyntheticTrialGroup( + trial.trial_name, trial.group_name, + /*annotation_mode=*/ + variations::SyntheticTrialAnnotationMode::kNextLog)); } } // Register trial which shouldn't get recorded. void RegisterExtraSyntheticTrial() { registry_.RegisterSyntheticFieldTrial(SyntheticTrialGroup( "ExtraSynthetic", "ExtraGroup", + /*annotation_mode=*/ variations::SyntheticTrialAnnotationMode::kNextLog)); } @@ -89,7 +107,7 @@ }; TEST_F(FieldTrialsProviderTest, ProvideSyntheticTrials) { - TestProvider provider(®istry_, base::StringPiece()); + FieldTrialsProvider provider(®istry_, base::StringPiece()); RegisterExpectedSyntheticTrials(); // Make sure these trials are older than the log. @@ -113,7 +131,7 @@ } TEST_F(FieldTrialsProviderTest, NoSyntheticTrials) { - TestProvider provider(nullptr, base::StringPiece()); + FieldTrialsProvider provider(nullptr, base::StringPiece()); metrics::SystemProfileProto proto; provider.ProvideSystemProfileMetricsWithLogCreationTime(base::TimeTicks(), @@ -136,7 +154,7 @@ trial->set_name_id(1); trial->set_group_id(1); - TestProvider provider(®istry_, base::StringPiece()); + FieldTrialsProvider provider(®istry_, base::StringPiece()); RegisterExpectedSyntheticTrials(); WaitUntilTimeChanges(base::TimeTicks::Now()); provider.SetLogCreationTimeForTesting(base::TimeTicks::Now()); @@ -148,4 +166,21 @@ CheckFieldTrialsInSystemProfile(uma_log.system_profile(), kAllTrialIds); } +TEST_F(FieldTrialsProviderTest, GetAndWriteFieldTrialsWithSuffixes) { + metrics::ChromeUserMetricsExtension uma_log; + uma_log.system_profile(); + + FieldTrialsProvider provider(®istry_, kSuffix); + RegisterExpectedSyntheticTrials(); + WaitUntilTimeChanges(base::TimeTicks::Now()); + provider.SetLogCreationTimeForTesting(base::TimeTicks::Now()); + + provider.ProvideCurrentSessionData(&uma_log); + + EXPECT_EQ(std::size(kAllTrialIdsWithSuffixes), + static_cast<size_t>(uma_log.system_profile().field_trial_size())); + CheckFieldTrialsInSystemProfile(uma_log.system_profile(), + kAllTrialIdsWithSuffixes); +} + } // namespace variations
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index a85a06e2..39887435 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -108,9 +108,9 @@ // Used to adjust the age threshold since the last visit in order to consider a // normalized keyword search term as a zero-prefix suggestion. If disabled, the -// default value of 7 days is used. If enabled, the age threshold is determined -// by this feature's companion parameter, -// OmniboxFieldTrial::kOmniboxLocalZeroSuggestAgeThresholdParam. +// default value of 60 days for Desktop and 7 days for Android and iOS is used. +// If enabled, the age threshold is determined by this feature's companion +// parameter, OmniboxFieldTrial::kOmniboxLocalZeroSuggestAgeThresholdParam. const base::Feature kOmniboxLocalZeroSuggestAgeThreshold{ "OmniboxLocalZeroSuggestAgeThreshold", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/pdf/README.md b/components/pdf/README.md index ebcbbb35..0ddfe9e0 100644 --- a/components/pdf/README.md +++ b/components/pdf/README.md
@@ -1,7 +1,5 @@ The PDF component contains code necessary for using the PDF plugin in -content-based clients. It provides an implementation for the PPB\_PDF PPAPI -interface, and the necessary browser and renderer-side code for processing the -relevant IPC messages. The PDF plugin code lives in `//pdf`. - -TODO(crbug.com/702993): Update description when the PDF plugin no longer uses -PPAPI and is also no longer a plugin process. +content-based clients. The PDF plugin code that lives in `//pdf` cannot depend +on `//content` directly, so it uses a variety of delegate interfaces which are +implement here. This component also contains code shared among content-based +clients that should not live in `//chrome`.
diff --git a/components/policy/core/browser/policy_conversions.cc b/components/policy/core/browser/policy_conversions.cc index 9b072d7..b140ca378 100644 --- a/components/policy/core/browser/policy_conversions.cc +++ b/components/policy/core/browser/policy_conversions.cc
@@ -92,10 +92,6 @@ return *this; } -std::string PolicyConversions::ToJSON() { - return client_->ConvertValueToJSON(ToValue()); -} - /** * DictionaryPolicyConversions */ @@ -105,7 +101,68 @@ : PolicyConversions(std::move(client)) {} DictionaryPolicyConversions::~DictionaryPolicyConversions() = default; -Value DictionaryPolicyConversions::ToValue() { +#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +DictionaryPolicyConversions& DictionaryPolicyConversions::WithUpdaterPolicies( + std::unique_ptr<PolicyMap> policies) { + PolicyConversions::SetUpdaterPolicies(std::move(policies)); + return *this; +} + +DictionaryPolicyConversions& +DictionaryPolicyConversions::WithUpdaterPolicySchemas( + PolicyToSchemaMap schemas) { + PolicyConversions::SetUpdaterPolicySchemas(std::move(schemas)); + return *this; +} +#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + +DictionaryPolicyConversions& DictionaryPolicyConversions::EnableConvertTypes( + bool enabled) { + PolicyConversions::EnableConvertTypes(enabled); + return *this; +} + +DictionaryPolicyConversions& DictionaryPolicyConversions::EnableConvertValues( + bool enabled) { + PolicyConversions::EnableConvertValues(enabled); + return *this; +} + +DictionaryPolicyConversions& +DictionaryPolicyConversions::EnableDeviceLocalAccountPolicies(bool enabled) { + PolicyConversions::EnableDeviceLocalAccountPolicies(enabled); + return *this; +} + +DictionaryPolicyConversions& DictionaryPolicyConversions::EnableDeviceInfo( + bool enabled) { + PolicyConversions::EnableDeviceInfo(enabled); + return *this; +} + +DictionaryPolicyConversions& DictionaryPolicyConversions::EnablePrettyPrint( + bool enabled) { + PolicyConversions::EnablePrettyPrint(enabled); + return *this; +} + +DictionaryPolicyConversions& DictionaryPolicyConversions::EnableUserPolicies( + bool enabled) { + PolicyConversions::EnableUserPolicies(enabled); + return *this; +} + +DictionaryPolicyConversions& DictionaryPolicyConversions::SetDropDefaultValues( + bool enabled) { + PolicyConversions::SetDropDefaultValues(enabled); + return *this; +} + +std::string DictionaryPolicyConversions::ToJSON() { + return client()->ConvertValueToJSON(Value(ToValueDict())); +} + +Value::Dict DictionaryPolicyConversions::ToValueDict() { Value::Dict all_policies; if (client()->HasUserPolicies()) { @@ -134,7 +191,7 @@ if (!identity_fields.empty()) all_policies.Merge(identity_fields); #endif // BUILDFLAG(IS_CHROMEOS_ASH) - return Value(std::move(all_policies)); + return all_policies; } #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -181,7 +238,52 @@ } #endif // BUILDFLAG(IS_CHROMEOS_LACROS) -Value ArrayPolicyConversions::ToValue() { +ArrayPolicyConversions& ArrayPolicyConversions::EnableConvertTypes( + bool enabled) { + PolicyConversions::EnableConvertTypes(enabled); + return *this; +} + +ArrayPolicyConversions& ArrayPolicyConversions::EnableConvertValues( + bool enabled) { + PolicyConversions::EnableConvertValues(enabled); + return *this; +} + +ArrayPolicyConversions& +ArrayPolicyConversions::EnableDeviceLocalAccountPolicies(bool enabled) { + PolicyConversions::EnableDeviceLocalAccountPolicies(enabled); + return *this; +} + +ArrayPolicyConversions& ArrayPolicyConversions::EnableDeviceInfo(bool enabled) { + PolicyConversions::EnableDeviceInfo(enabled); + return *this; +} + +ArrayPolicyConversions& ArrayPolicyConversions::EnablePrettyPrint( + bool enabled) { + PolicyConversions::EnablePrettyPrint(enabled); + return *this; +} + +ArrayPolicyConversions& ArrayPolicyConversions::EnableUserPolicies( + bool enabled) { + PolicyConversions::EnableUserPolicies(enabled); + return *this; +} + +ArrayPolicyConversions& ArrayPolicyConversions::SetDropDefaultValues( + bool enabled) { + PolicyConversions::SetDropDefaultValues(enabled); + return *this; +} + +std::string ArrayPolicyConversions::ToJSON() { + return client()->ConvertValueToJSON(Value(ToValueList())); +} + +Value::List ArrayPolicyConversions::ToValueList() { Value::List all_policies; if (client()->HasUserPolicies()) { @@ -222,7 +324,7 @@ all_policies.Append(std::move(identity_fields)); #endif // BUILDFLAG(IS_CHROMEOS_ASH) - return Value(std::move(all_policies)); + return all_policies; } #if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) @@ -233,6 +335,18 @@ chrome_policies_data.Set("policies", client()->GetUpdaterPolicies()); return chrome_policies_data; } + +ArrayPolicyConversions& ArrayPolicyConversions::WithUpdaterPolicies( + std::unique_ptr<PolicyMap> policies) { + PolicyConversions::SetUpdaterPolicies(std::move(policies)); + return *this; +} + +ArrayPolicyConversions& ArrayPolicyConversions::WithUpdaterPolicySchemas( + PolicyToSchemaMap schemas) { + PolicyConversions::SetUpdaterPolicySchemas(std::move(schemas)); + return *this; +} #endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) Value::Dict ArrayPolicyConversions::GetChromePolicies() {
diff --git a/components/policy/core/browser/policy_conversions.h b/components/policy/core/browser/policy_conversions.h index b0f03f54..501ebbf0 100644 --- a/components/policy/core/browser/policy_conversions.h +++ b/components/policy/core/browser/policy_conversions.h
@@ -45,39 +45,38 @@ // Set to get policy types as human friendly string instead of enum integer. // Policy types includes policy source, policy scope and policy level. // Enabled by default. - PolicyConversions& EnableConvertTypes(bool enabled); + virtual PolicyConversions& EnableConvertTypes(bool enabled); // Set to get dictionary policy value as JSON string. // Disabled by default. - PolicyConversions& EnableConvertValues(bool enabled); + virtual PolicyConversions& EnableConvertValues(bool enabled); // Set to get device local account policies on ChromeOS. // Disabled by default. - PolicyConversions& EnableDeviceLocalAccountPolicies(bool enabled); + virtual PolicyConversions& EnableDeviceLocalAccountPolicies(bool enabled); // Set to get device basic information on ChromeOS. // Disabled by default. - PolicyConversions& EnableDeviceInfo(bool enabled); + virtual PolicyConversions& EnableDeviceInfo(bool enabled); // Set to enable pretty print for all JSON string. // Enabled by default. - PolicyConversions& EnablePrettyPrint(bool enabled); + virtual PolicyConversions& EnablePrettyPrint(bool enabled); // Set to get all user scope policies. // Enabled by default. - PolicyConversions& EnableUserPolicies(bool enabled); + virtual PolicyConversions& EnableUserPolicies(bool enabled); // Set to drop the policies of which value is a default one set by the policy // provider. Disabled by default. - PolicyConversions& SetDropDefaultValues(bool enabled); + virtual PolicyConversions& SetDropDefaultValues(bool enabled); #if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) // Sets the updater policies. - PolicyConversions& WithUpdaterPolicies(std::unique_ptr<PolicyMap> policies); + virtual PolicyConversions& WithUpdaterPolicies( + std::unique_ptr<PolicyMap> policies); // Sets the updater policy schemas. - PolicyConversions& WithUpdaterPolicySchemas(PolicyToSchemaMap schemas); + virtual PolicyConversions& WithUpdaterPolicySchemas( + PolicyToSchemaMap schemas); #endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) - // Returns the policy data as a base::Value object. - virtual base::Value ToValue() = 0; - // Returns the policy data as a JSON string; - virtual std::string ToJSON(); + virtual std::string ToJSON() = 0; protected: PolicyConversionsClient* client() { return client_.get(); } @@ -95,8 +94,34 @@ delete; ~DictionaryPolicyConversions() override; - // TODO(chromium:1321529): Investigate returning base::Value::Dict. - base::Value ToValue() override; + DictionaryPolicyConversions& EnableConvertTypes(bool enabled) override; + + DictionaryPolicyConversions& EnableConvertValues(bool enabled) override; + + DictionaryPolicyConversions& EnableDeviceLocalAccountPolicies( + bool enabled) override; + + DictionaryPolicyConversions& EnableDeviceInfo(bool enabled) override; + + DictionaryPolicyConversions& EnablePrettyPrint(bool enabled) override; + + DictionaryPolicyConversions& EnableUserPolicies(bool enabled) override; + + DictionaryPolicyConversions& SetDropDefaultValues(bool enabled) override; + +#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // Sets the updater policies. + DictionaryPolicyConversions& WithUpdaterPolicies( + std::unique_ptr<PolicyMap> policies) override; + + // Sets the updater policy schemas. + DictionaryPolicyConversions& WithUpdaterPolicySchemas( + PolicyToSchemaMap schemas) override; +#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + + std::string ToJSON() override; + + base::Value::Dict ToValueDict(); private: base::Value::Dict GetExtensionPolicies(PolicyDomain policy_domain); @@ -114,8 +139,34 @@ ArrayPolicyConversions& operator=(const ArrayPolicyConversions&) = delete; ~ArrayPolicyConversions() override; - // TODO(chromium:1321529): Investigate returning base::Value::List. - base::Value ToValue() override; + ArrayPolicyConversions& EnableConvertTypes(bool enabled) override; + + ArrayPolicyConversions& EnableConvertValues(bool enabled) override; + + ArrayPolicyConversions& EnableDeviceLocalAccountPolicies( + bool enabled) override; + + ArrayPolicyConversions& EnableDeviceInfo(bool enabled) override; + + ArrayPolicyConversions& EnablePrettyPrint(bool enabled) override; + + ArrayPolicyConversions& EnableUserPolicies(bool enabled) override; + + ArrayPolicyConversions& SetDropDefaultValues(bool enabled) override; + +#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // Sets the updater policies. + ArrayPolicyConversions& WithUpdaterPolicies( + std::unique_ptr<PolicyMap> policies) override; + + // Sets the updater policy schemas. + ArrayPolicyConversions& WithUpdaterPolicySchemas( + PolicyToSchemaMap schemas) override; +#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + + std::string ToJSON() override; + + base::Value::List ToValueList(); #if BUILDFLAG(IS_CHROMEOS_LACROS) // Additional Chrome policies that need to be displayed, though not available
diff --git a/components/policy/core/browser/webui/json_generation.cc b/components/policy/core/browser/webui/json_generation.cc index 994a3a3..bb5e3b8 100644 --- a/components/policy/core/browser/webui/json_generation.cc +++ b/components/policy/core/browser/webui/json_generation.cc
@@ -23,8 +23,8 @@ std::string GenerateJson(std::unique_ptr<PolicyConversionsClient> client, base::Value status, const JsonGenerationParams& params) { - base::Value chrome_metadata(base::Value::Type::DICTIONARY); - chrome_metadata.SetKey("application", base::Value(params.application_name)); + base::Value::Dict chrome_metadata; + chrome_metadata.Set("application", params.application_name); std::string version = base::StringPrintf( "%s (%s)%s %s%s", version_info::GetVersionNumber().c_str(), @@ -36,25 +36,23 @@ params.processor_variation.c_str(), params.cohort_name ? params.cohort_name->c_str() : ""); - chrome_metadata.SetKey("version", base::Value(version)); + chrome_metadata.Set("version", version); if (params.os_name && !params.os_name->empty()) { - chrome_metadata.SetKey("OS", base::Value(params.os_name.value())); + chrome_metadata.Set("OS", params.os_name.value()); } if (params.platform_name && !params.platform_name->empty()) { - chrome_metadata.SetKey("platform", - base::Value(params.platform_name.value())); + chrome_metadata.Set("platform", params.platform_name.value()); } - chrome_metadata.SetKey("revision", - base::Value(version_info::GetLastChange())); + chrome_metadata.Set("revision", version_info::GetLastChange()); - base::Value dict = - policy::DictionaryPolicyConversions(std::move(client)).ToValue(); + base::Value::Dict dict = + policy::DictionaryPolicyConversions(std::move(client)).ToValueDict(); - dict.SetKey("chromeMetadata", std::move(chrome_metadata)); - dict.SetKey("status", std::move(status)); + dict.Set("chromeMetadata", std::move(chrome_metadata)); + dict.Set("status", std::move(status)); std::string json_policies; base::JSONWriter::WriteWithOptions(
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc index 68922c94..768f6d2 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.cc +++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/containers/contains.h" -#include "base/feature_list.h" #include "base/guid.h" #include "base/json/json_reader.h" #include "base/logging.h" @@ -27,7 +26,6 @@ #include "components/policy/core/common/cloud/encrypted_reporting_job_configuration.h" #include "components/policy/core/common/cloud/realtime_reporting_job_configuration.h" #include "components/policy/core/common/cloud/signing_service.h" -#include "components/policy/core/common/features.h" #include "components/policy/proto/device_management_backend.pb.h" #include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_urls.h" @@ -452,10 +450,8 @@ #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) // Only set browser device identifier for CBCM Chrome cloud policy on // desktop. - if (base::FeatureList::IsEnabled( - features::kUploadBrowserDeviceIdentifier) && - type_to_fetch.first == - dm_protocol::kChromeMachineLevelUserCloudPolicyType) { + if (type_to_fetch.first == + dm_protocol::kChromeMachineLevelUserCloudPolicyType) { fetch_request->set_allocated_browser_device_identifier( GetBrowserDeviceIdentifier().release()); }
diff --git a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc index cb1b63e..793bb0ae 100644 --- a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc +++ b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
@@ -17,13 +17,11 @@ #include "base/callback.h" #include "base/callback_helpers.h" #include "base/compiler_specific.h" -#include "base/feature_list.h" #include "base/json/json_reader.h" #include "base/memory/ref_counted.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/values.h" #include "build/build_config.h" @@ -36,7 +34,6 @@ #include "components/policy/core/common/cloud/mock_signing_service.h" #include "components/policy/core/common/cloud/realtime_reporting_job_configuration.h" #include "components/policy/core/common/cloud/reporting_job_configuration_base.h" -#include "components/policy/core/common/features.h" #include "components/policy/proto/device_management_backend.pb.h" #include "components/version_info/version_info.h" #include "google_apis/gaia/gaia_urls.h" @@ -663,10 +660,6 @@ #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || \ (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) TEST_F(CloudPolicyClientTest, RegistrationWithTokenAndPolicyFetch) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kUploadBrowserDeviceIdentifier); - const em::DeviceManagementResponse policy_response = GetPolicyResponse(); ExpectAndCaptureJob(GetRegistrationResponse()); @@ -702,10 +695,6 @@ } TEST_F(CloudPolicyClientTest, RegistrationWithTokenTestTimeout) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kUploadBrowserDeviceIdentifier); - ExpectAndCaptureJob(GetRegistrationResponse()); EXPECT_CALL(observer_, OnRegistrationStateChanged); EXPECT_CALL(device_dmtoken_callback_observer_, @@ -1101,10 +1090,6 @@ TEST_F(CloudPolicyClientTest, PolicyFetchWithBrowserDeviceIdentifier) { RegisterClient(); - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kUploadBrowserDeviceIdentifier); - // Add the policy type that contains browser device identifier. client_->AddPolicyTypeToFetch( dm_protocol::kChromeMachineLevelUserCloudPolicyType, std::string());
diff --git a/components/policy/core/common/features.cc b/components/policy/core/common/features.cc index 86b1a5c..7282c13c 100644 --- a/components/policy/core/common/features.cc +++ b/components/policy/core/common/features.cc
@@ -13,9 +13,6 @@ const base::Feature kDefaultChromeAppsMigration{ "EnableDefaultAppsMigration", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kUploadBrowserDeviceIdentifier{ - "UploadBrowserDeviceIdentifier", base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kLoginEventReporting{"LoginEventReporting", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/policy/core/common/features.h b/components/policy/core/common/features.h index df236a9..17db17d 100644 --- a/components/policy/core/common/features.h +++ b/components/policy/core/common/features.h
@@ -17,9 +17,6 @@ // Enable force installed Chrome apps policy migration. POLICY_EXPORT extern const base::Feature kDefaultChromeAppsMigration; -// Update browser device identifier during enrollment and fetching policies. -POLICY_EXPORT extern const base::Feature kUploadBrowserDeviceIdentifier; - // Enable reporting Login events to the reporting connector when the Password // Manager detects that the user logged in to a web page. POLICY_EXPORT extern const base::Feature kLoginEventReporting;
diff --git a/components/policy/core/common/policy_loader_common.cc b/components/policy/core/common/policy_loader_common.cc index 5d64293b..38ecdb3c 100644 --- a/components/policy/core/common/policy_loader_common.cc +++ b/components/policy/core/common/policy_loader_common.cc
@@ -46,6 +46,7 @@ key::kChromeCleanupReportingEnabled, key::kCommandLineFlagSecurityWarningsEnabled, key::kDefaultSearchProviderEnabled, + key::kFirstPartySetsOverrides, key::kHomepageIsNewTabPage, key::kHomepageLocation, key::kMetricsReportingEnabled,
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 41142ce..ed1564b 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -30629,7 +30629,9 @@ Wildcards (*) are not supported as a policy value, nor within any First-Party Set in these lists. All sets provided by to policy must be valid First-Party Sets, if they aren't then an - appropriate error will be outputted.''', + appropriate error will be outputted. + + This policy is available only on Windows instances that are joined to a <ph name="MS_AD_NAME">Microsoft® Active Directory®</ph> domain or Windows 10 Pro or Enterprise instances that are enrolled for device management, and macOS instances that are managed via MDM or joined to a domain via MCX.''', }, { 'name': 'DeviceEncryptedReportingPipelineEnabled',
diff --git a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm index b99bc242..28c5308 100644 --- a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm +++ b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
@@ -4,7 +4,6 @@ #import "components/remote_cocoa/app_shim/native_widget_mac_nswindow.h" -#include "base/auto_reset.h" #include "base/debug/dump_without_crashing.h" #include "base/mac/foundation_util.h" #include "base/trace_event/trace_event.h" @@ -16,65 +15,6 @@ #import "ui/base/cocoa/user_interface_item_command_handler.h" #import "ui/base/cocoa/window_size_constants.h" -namespace { - -// AppKit quirk: -[NSWindow orderWindow] does not handle reordering for children -// windows. Their order is fixed to the attachment order (the last attached -// window is on the top). Therefore, work around it by re-parenting in our -// desired order. -void OrderChildWindow(NSWindow* childWindow, - NSWindow* otherWindow, - NSWindowOrderingMode orderingMode) { - NSWindow* parent = [childWindow parentWindow]; - DCHECK(parent); - - // `orderedChildren` sorts children windows back to front. - NSArray<NSWindow*>* children = [[childWindow parentWindow] childWindows]; - std::vector<std::pair<NSInteger, NSWindow*>> orderedChildren; - for (NSWindow* child in children) - orderedChildren.push_back({[child orderedIndex], child}); - std::sort(orderedChildren.begin(), orderedChildren.end(), std::greater<>()); - - // If `otherWindow` is nullptr, place `childWindow` in front of (or behind) - // all other children windows. - if (otherWindow == nullptr) { - otherWindow = - orderingMode == NSWindowAbove ? orderedChildren.back().second : parent; - } - - if (childWindow == otherWindow) - return; - - const bool relativeToParent = [childWindow parentWindow] == otherWindow; - DCHECK(orderingMode != NSWindowBelow || !relativeToParent) - << "Placing a child window behind its parent is not supported."; - - for (NSWindow* child in children) - [parent removeChildWindow:child]; - - // If `relativeToParent` is true, `childWindow` is the first child of its - // parent. - if (relativeToParent) - [parent addChildWindow:childWindow ordered:NSWindowAbove]; - - // Re-parent children windows in the desired order. - for (auto [orderedIndex, child] : orderedChildren) { - if (child != childWindow && child != otherWindow) { - [parent addChildWindow:child ordered:NSWindowAbove]; - } else if (child == otherWindow && !relativeToParent) { - if (orderingMode == NSWindowAbove) { - [parent addChildWindow:otherWindow ordered:NSWindowAbove]; - [parent addChildWindow:childWindow ordered:NSWindowAbove]; - } else { - [parent addChildWindow:childWindow ordered:NSWindowAbove]; - [parent addChildWindow:otherWindow ordered:NSWindowAbove]; - } - } - } -} - -} // namespace - @interface NSWindow (Private) + (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle; - (BOOL)hasKeyAppearance; @@ -144,7 +84,6 @@ BOOL _willUpdateRestorableState; BOOL _isEnforcingNeverMadeVisible; BOOL _preventKeyWindow; - BOOL _orderingWindow; } @synthesize bridgedNativeWidgetId = _bridgedNativeWidgetId; @synthesize bridge = _bridge; @@ -160,7 +99,6 @@ defer:deferCreation])) { _commandDispatcher.reset([[CommandDispatcher alloc] initWithOwner:self]); } - _orderingWindow = NO; return self; } @@ -391,29 +329,7 @@ // when ordering in a window for the first time. - (void)orderWindow:(NSWindowOrderingMode)orderingMode relativeTo:(NSInteger)otherWindowNumber { - // AppKit will enter -[NativeWidgetMacNSWindow orderWindow:] before - // OrderChildWindow() exits. On re-entrance, pass to -[NSWindow orderWindow:] - // to prevent infinite re-entrancy. - if (_orderingWindow) { - [super orderWindow:orderingMode relativeTo:otherWindowNumber]; - return; - } - base::AutoReset<BOOL> orderingWindow(&_orderingWindow, YES); - - // `otherWindow` is nil if `otherWindowNumber` is 0. It means to place - // `self` at the top / bottom. - NSWindow* otherWindow = [NSApp windowWithWindowNumber:otherWindowNumber]; - - // For unknown reason we have to call -[NSWindow orderWindow] before the - // special handling for child window, otherwise Chrome will freeze. [super orderWindow:orderingMode relativeTo:otherWindowNumber]; - - if ([self parentWindow] != nullptr && - (otherWindow == nullptr || - [self parentWindow] == [otherWindow parentWindow] || - [self parentWindow] == otherWindow)) - OrderChildWindow(self, otherWindow, orderingMode); - [[self viewsNSWindowDelegate] onWindowOrderChanged:nil]; }
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm index 3d8affd..dbbe949 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
@@ -422,7 +422,7 @@ } void NativeWidgetNSWindowBridge::StackAtTop() { - [window_ orderWindow:NSWindowAbove relativeTo:0]; + [window_ setOrderedIndex:0]; } void NativeWidgetNSWindowBridge::ShowEmojiPanel() {
diff --git a/components/translate/translate_internals/translate_internals_handler.cc b/components/translate/translate_internals/translate_internals_handler.cc index 1c47977e..aaa5b1fd 100644 --- a/components/translate/translate_internals/translate_internals_handler.cc +++ b/components/translate/translate_internals/translate_internals_handler.cc
@@ -68,19 +68,19 @@ } void TranslateInternalsHandler::RegisterMessageCallbacks() { - RegisterDeprecatedMessageCallback( + RegisterMessageCallback( "removePrefItem", base::BindRepeating(&TranslateInternalsHandler::OnRemovePrefItem, base::Unretained(this))); - RegisterDeprecatedMessageCallback( + RegisterMessageCallback( "setRecentTargetLanguage", base::BindRepeating(&TranslateInternalsHandler::OnSetRecentTargetLanguage, base::Unretained(this))); - RegisterDeprecatedMessageCallback( + RegisterMessageCallback( "requestInfo", base::BindRepeating(&TranslateInternalsHandler::OnRequestInfo, base::Unretained(this))); - RegisterDeprecatedMessageCallback( + RegisterMessageCallback( "overrideCountry", base::BindRepeating(&TranslateInternalsHandler::OnOverrideCountry, base::Unretained(this))); @@ -160,31 +160,32 @@ SendMessageToJs("translateEventDetailsAdded", dict); } -void TranslateInternalsHandler::OnRemovePrefItem(const base::ListValue* args) { +void TranslateInternalsHandler::OnRemovePrefItem( + const base::Value::List& args) { std::unique_ptr<translate::TranslatePrefs> translate_prefs = GetTranslateClient()->GetTranslatePrefs(); - if (!args->GetListDeprecated()[0].is_string()) + if (!args[0].is_string()) return; - const std::string& pref_name = args->GetListDeprecated()[0].GetString(); + const std::string& pref_name = args[0].GetString(); if (pref_name == "blocked_languages") { - if (!args->GetListDeprecated()[1].is_string()) + if (!args[1].is_string()) return; - const std::string& language = args->GetListDeprecated()[1].GetString(); + const std::string& language = args[1].GetString(); translate_prefs->UnblockLanguage(language); } else if (pref_name == "site_blocklist") { - if (!args->GetListDeprecated()[1].is_string()) + if (!args[1].is_string()) return; - const std::string& site = args->GetListDeprecated()[1].GetString(); + const std::string& site = args[1].GetString(); translate_prefs->RemoveSiteFromNeverPromptList(site); } else if (pref_name == "allowlists") { - if (!args->GetListDeprecated()[1].is_string()) + if (!args[1].is_string()) return; - if (!args->GetListDeprecated()[2].is_string()) + if (!args[2].is_string()) return; - const std::string& from = args->GetListDeprecated()[1].GetString(); - const std::string& to = args->GetListDeprecated()[2].GetString(); + const std::string& from = args[1].GetString(); + const std::string& to = args[2].GetString(); translate_prefs->RemoveLanguagePairFromAlwaysTranslateList(from, to); } else { return; @@ -194,29 +195,31 @@ } void TranslateInternalsHandler::OnSetRecentTargetLanguage( - const base::ListValue* args) { + const base::Value::List& args) { std::unique_ptr<translate::TranslatePrefs> translate_prefs = GetTranslateClient()->GetTranslatePrefs(); - if (!args->GetListDeprecated()[0].is_string()) + if (!args[0].is_string()) return; - const std::string& new_value = args->GetListDeprecated()[0].GetString(); + const std::string& new_value = args[0].GetString(); translate_prefs->SetRecentTargetLanguage(new_value); SendPrefsToJs(); } -void TranslateInternalsHandler::OnOverrideCountry(const base::ListValue* args) { - if (args->GetListDeprecated()[0].is_string()) { - const std::string& country = args->GetListDeprecated()[0].GetString(); +void TranslateInternalsHandler::OnOverrideCountry( + const base::Value::List& args) { + if (args[0].is_string()) { + const std::string& country = args[0].GetString(); variations::VariationsService* variations_service = GetVariationsService(); SendCountryToJs( variations_service->OverrideStoredPermanentCountry(country)); } } -void TranslateInternalsHandler::OnRequestInfo(const base::ListValue* /*args*/) { +void TranslateInternalsHandler::OnRequestInfo( + const base::Value::List& /*args*/) { SendPrefsToJs(); SendSupportedLanguagesToJs(); SendCountryToJs(false);
diff --git a/components/translate/translate_internals/translate_internals_handler.h b/components/translate/translate_internals/translate_internals_handler.h index 457911a..73a3699 100644 --- a/components/translate/translate_internals/translate_internals_handler.h +++ b/components/translate/translate_internals/translate_internals_handler.h
@@ -17,7 +17,6 @@ #include "components/variations/service/variations_service.h" namespace base { -class ListValue; class Value; } // namespace base @@ -50,18 +49,6 @@ virtual void RegisterMessageCallback(const std::string& message, MessageCallback callback) = 0; - // Always use RegisterMessageCallback() above in new code. - // - // TODO(crbug.com/1243386): Existing callers of - // RegisterDeprecatedMessageCallback() should be migrated to - // RegisterMessageCallback() if possible. - // - // Registers to handle |message| from JavaScript with |callback|. - using DeprecatedMessageCallback = - base::RepeatingCallback<void(const base::ListValue*)>; - virtual void RegisterDeprecatedMessageCallback( - const std::string& message, - const DeprecatedMessageCallback& callback) = 0; // Calls a Javascript function with the given name and arguments. virtual void CallJavascriptFunction( const std::string& function_name, @@ -85,22 +72,22 @@ // Handles the Javascript message 'removePrefItem'. This message is sent // when UI requests to remove an item in the preference. - void OnRemovePrefItem(const base::ListValue* args); + void OnRemovePrefItem(const base::Value::List& args); // Handles the JavaScript message 'setRecentTargetLanguage'. This message is // sent when the UI requests to change the 'translate_recent_target' // preference. - void OnSetRecentTargetLanguage(const base::ListValue* args); + void OnSetRecentTargetLanguage(const base::Value::List& args); // Handles the Javascript message 'overrideCountry'. This message is sent // when UI requests to override the stored country. - void OnOverrideCountry(const base::ListValue* country); + void OnOverrideCountry(const base::Value::List& country); // Handles the Javascript message 'requestInfo'. This message is sent // when UI needs to show information concerned with the translation. // For now, this returns only prefs to Javascript. // |args| is not used. - void OnRequestInfo(const base::ListValue* args); + void OnRequestInfo(const base::Value::List& args); // Sends a message to Javascript. void SendMessageToJs(const std::string& message, const base::Value& value);
diff --git a/components/variations/active_field_trials.cc b/components/variations/active_field_trials.cc index 5f100d25..789082e 100644 --- a/components/variations/active_field_trials.cc +++ b/components/variations/active_field_trials.cc
@@ -22,20 +22,6 @@ base::LazyInstance<std::string>::Leaky g_seed_version; -// Populates |name_group_ids| based on |active_groups|. Field trial names are -// suffixed with |suffix| before hashing is executed. -void GetFieldTrialActiveGroupIdsForActiveGroups( - base::StringPiece suffix, - const base::FieldTrial::ActiveGroups& active_groups, - std::vector<ActiveGroupId>* name_group_ids) { - DCHECK(name_group_ids->empty()); - for (auto it = active_groups.begin(); it != active_groups.end(); ++it) { - name_group_ids->push_back( - MakeActiveGroupId(it->trial_name + std::string(suffix), - it->group_name + std::string(suffix))); - } -} - void AppendActiveGroupIdsAsStrings( const std::vector<ActiveGroupId> name_group_ids, std::vector<std::string>* output) { @@ -55,6 +41,18 @@ return id; } +void GetFieldTrialActiveGroupIdsForActiveGroups( + base::StringPiece suffix, + const base::FieldTrial::ActiveGroups& active_groups, + std::vector<ActiveGroupId>* name_group_ids) { + DCHECK(name_group_ids->empty()); + for (const auto& active_group : active_groups) { + name_group_ids->push_back( + MakeActiveGroupId(active_group.trial_name + std::string(suffix), + active_group.group_name + std::string(suffix))); + } +} + void GetFieldTrialActiveGroupIds(base::StringPiece suffix, std::vector<ActiveGroupId>* name_group_ids) { DCHECK(name_group_ids->empty());
diff --git a/components/variations/active_field_trials.h b/components/variations/active_field_trials.h index a7bb12a8..f3b5273 100644 --- a/components/variations/active_field_trials.h +++ b/components/variations/active_field_trials.h
@@ -40,6 +40,14 @@ } }; +// Populates |name_group_ids| based on |active_groups|. Field trial names are +// suffixed with |suffix| before hashing is executed. +COMPONENT_EXPORT(VARIATIONS) +void GetFieldTrialActiveGroupIdsForActiveGroups( + base::StringPiece suffix, + const base::FieldTrial::ActiveGroups& active_groups, + std::vector<ActiveGroupId>* name_group_ids); + // Fills the supplied vector |name_group_ids| (which must be empty when called) // with unique ActiveGroupIds for each Field Trial that has a chosen group. // Field Trials for which a group has not been chosen yet are NOT returned in
diff --git a/components/variations/synthetic_trial_registry.cc b/components/variations/synthetic_trial_registry.cc index 8fb9c1e..0c6fca23 100644 --- a/components/variations/synthetic_trial_registry.cc +++ b/components/variations/synthetic_trial_registry.cc
@@ -10,6 +10,7 @@ #include "base/metrics/histogram_functions.h" #include "base/observer_list.h" #include "base/strings/string_number_conversions.h" +#include "components/variations/active_field_trials.h" #include "components/variations/hashing.h" #include "components/variations/variations_associated_data.h" @@ -165,14 +166,19 @@ void SyntheticTrialRegistry::GetSyntheticFieldTrialsOlderThan( base::TimeTicks time, - std::vector<ActiveGroupId>* synthetic_trials) const { + std::vector<ActiveGroupId>* synthetic_trials, + base::StringPiece suffix) const { DCHECK(synthetic_trials); synthetic_trials->clear(); + base::FieldTrial::ActiveGroups active_groups; for (const auto& entry : synthetic_trial_groups_) { if (entry.start_time() <= time || entry.annotation_mode() == SyntheticTrialAnnotationMode::kCurrentLog) - synthetic_trials->push_back(entry.id()); + active_groups.push_back(entry.active_group()); } + + GetFieldTrialActiveGroupIdsForActiveGroups(suffix, active_groups, + synthetic_trials); } } // namespace variations
diff --git a/components/variations/synthetic_trial_registry.h b/components/variations/synthetic_trial_registry.h index 63d8700..6e299bcc 100644 --- a/components/variations/synthetic_trial_registry.h +++ b/components/variations/synthetic_trial_registry.h
@@ -85,6 +85,8 @@ friend SyntheticTrialRegistryTest; FRIEND_TEST_ALL_PREFIXES(SyntheticTrialRegistryTest, RegisterSyntheticTrial); FRIEND_TEST_ALL_PREFIXES(SyntheticTrialRegistryTest, + GetSyntheticFieldTrialsOlderThanSuffix); + FRIEND_TEST_ALL_PREFIXES(SyntheticTrialRegistryTest, GetSyntheticFieldTrialActiveGroups); FRIEND_TEST_ALL_PREFIXES(VariationsCrashKeysTest, BasicFunctionality); @@ -119,10 +121,12 @@ const std::string& experiment_id); // Returns a list of synthetic field trials that are either (1) older than - // |time|, or (2) specify |kCurrentLog| as |annotation_mode|. + // |time|, or (2) specify |kCurrentLog| as |annotation_mode|. The trial and + // group names are suffixed with |suffix| before being hashed. void GetSyntheticFieldTrialsOlderThan( base::TimeTicks time, - std::vector<ActiveGroupId>* synthetic_trials) const; + std::vector<ActiveGroupId>* synthetic_trials, + base::StringPiece suffix = "") const; // Notifies observers on a synthetic trial list change. void NotifySyntheticTrialObservers();
diff --git a/components/variations/synthetic_trial_registry_unittest.cc b/components/variations/synthetic_trial_registry_unittest.cc index 129a213..6ab67c82 100644 --- a/components/variations/synthetic_trial_registry_unittest.cc +++ b/components/variations/synthetic_trial_registry_unittest.cc
@@ -134,6 +134,28 @@ EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial4", "Group4")); } +TEST_F(SyntheticTrialRegistryTest, GetSyntheticFieldTrialsOlderThanSuffix) { + SyntheticTrialRegistry registry; + SyntheticTrialGroup trial("TestTrial", "Group", + SyntheticTrialAnnotationMode::kCurrentLog); + registry.RegisterSyntheticFieldTrial(trial); + + std::vector<ActiveGroupId> synthetic_trials; + // Get list of synthetic trials, but with no added suffixes to the trial and + // group names. + registry.GetSyntheticFieldTrialsOlderThan(base::TimeTicks::Now(), + &synthetic_trials); + ASSERT_EQ(1U, synthetic_trials.size()); + EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial", "Group")); + + // Get list of synthetic trials, but with "UKM" suffixed to the trial and + // group names. + registry.GetSyntheticFieldTrialsOlderThan(base::TimeTicks::Now(), + &synthetic_trials, "UKM"); + ASSERT_EQ(1U, synthetic_trials.size()); + EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrialUKM", "GroupUKM")); +} + TEST_F(SyntheticTrialRegistryTest, RegisterExternalExperiments_NoAllowlist) { SyntheticTrialRegistry registry(false); const std::string context = "TestTrial1";
diff --git a/components/variations/synthetic_trials.cc b/components/variations/synthetic_trials.cc index 0eacdc1..9ffdf9c 100644 --- a/components/variations/synthetic_trials.cc +++ b/components/variations/synthetic_trials.cc
@@ -19,12 +19,12 @@ SyntheticTrialGroup::SyntheticTrialGroup(const SyntheticTrialGroup&) = default; void SyntheticTrialGroup::SetTrialName(base::StringPiece trial_name) { - trial_name_ = std::string(trial_name); + active_group_.trial_name = std::string(trial_name); id_.name = variations::HashName(trial_name); } void SyntheticTrialGroup::SetGroupName(base::StringPiece group_name) { - group_name_ = std::string(group_name); + active_group_.group_name = std::string(group_name); id_.group = variations::HashName(group_name); }
diff --git a/components/variations/synthetic_trials.h b/components/variations/synthetic_trials.h index a1accab..5e8445d 100644 --- a/components/variations/synthetic_trials.h +++ b/components/variations/synthetic_trials.h
@@ -44,8 +44,9 @@ ~SyntheticTrialGroup() = default; - base::StringPiece trial_name() const { return trial_name_; } - base::StringPiece group_name() const { return group_name_; } + base::FieldTrial::ActiveGroup active_group() const { return active_group_; } + base::StringPiece trial_name() const { return active_group_.trial_name; } + base::StringPiece group_name() const { return active_group_.group_name; } ActiveGroupId id() const { return id_; } base::TimeTicks start_time() const { return start_time_; } SyntheticTrialAnnotationMode annotation_mode() const { @@ -62,8 +63,7 @@ void SetIsExternal(bool is_external) { is_external_ = is_external; } private: - std::string trial_name_; - std::string group_name_; + base::FieldTrial::ActiveGroup active_group_; ActiveGroupId id_; base::TimeTicks start_time_;
diff --git a/components/viz/service/display/display_scheduler_unittest.cc b/components/viz/service/display/display_scheduler_unittest.cc index 041b801..c26548b 100644 --- a/components/viz/service/display/display_scheduler_unittest.cc +++ b/components/viz/service/display/display_scheduler_unittest.cc
@@ -181,7 +181,9 @@ : wait_for_all_surfaces_before_draw_(wait_for_all_surfaces_before_draw), fake_begin_frame_source_(0.f, false), task_runner_(new base::NullTaskRunner), - surface_manager_(nullptr, 4u), + surface_manager_(nullptr, + /*activation_deadline_in_frames=*/4u, + /*max_uncommitted_frames=*/0), resource_provider_(&shared_bitmap_manager_), aggregator_(&surface_manager_, &resource_provider_, false, false), damage_tracker_(
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc index c6ce8e1e..b464a80 100644 --- a/components/viz/service/display/display_unittest.cc +++ b/components/viz/service/display/display_unittest.cc
@@ -284,7 +284,7 @@ settings.partial_swap_enabled = true; SetUpSoftwareDisplay(settings); gfx::ColorSpace color_space_1 = gfx::ColorSpace::CreateXYZD50(); - gfx::ColorSpace color_space_2 = gfx::ColorSpace::CreateSCRGBLinear(); + gfx::ColorSpace color_space_2 = gfx::ColorSpace::CreateSRGBLinear(); gfx::DisplayColorSpaces color_spaces_1(color_space_1); gfx::DisplayColorSpaces color_spaces_2(color_space_2);
diff --git a/components/viz/service/display/frame_rate_decider_unittest.cc b/components/viz/service/display/frame_rate_decider_unittest.cc index e9f55fa..2be3702 100644 --- a/components/viz/service/display/frame_rate_decider_unittest.cc +++ b/components/viz/service/display/frame_rate_decider_unittest.cc
@@ -29,7 +29,9 @@ ~FrameRateDeciderTest() override = default; void SetUp() override { - surface_manager_ = std::make_unique<SurfaceManager>(this, absl::nullopt); + surface_manager_ = std::make_unique<SurfaceManager>( + this, /*activation_deadline_in_frames=*/absl::nullopt, + /*max_uncommitted_frames=*/0); bool hw_support_for_multiple_refresh_rates = true; frame_rate_decider_ = std::make_unique<FrameRateDecider>( surface_manager_.get(), this, hw_support_for_multiple_refresh_rates,
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 7fb66452..e0a8510 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -3700,15 +3700,6 @@ absl::optional<gfx::HDRMetadata> hdr_metadata) { DCHECK(dst_color_space.IsValid()); gfx::ColorSpace adjusted_src_color_space = src_color_space; - if (adjust_src_white_level && src_color_space.IsHDR()) { - // TODO(b/183236148): consider using the destination's HDR static metadata - // in current_frame()->display_color_spaces.hdr_static_metadata() and the - // color volume metadata in |src_hdr_metadata| for the tone mapping; e.g. - // the content might be mastered in 0-1000 nits but the display only be able - // to represent 0 to 500. - adjusted_src_color_space = src_color_space.GetWithSDRWhiteLevel( - current_frame()->display_color_spaces.GetSDRMaxLuminanceNits()); - } ProgramKey program_key = program_key_no_color; const gfx::ColorTransform* color_transform =
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 814376b..22af7c5 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -4726,12 +4726,6 @@ } this->display_color_spaces_ = gfx::DisplayColorSpaces(this->dst_color_space_); - float sdr_max_luminance_nits = - this->display_color_spaces_.GetSDRMaxLuminanceNits(); - if (src_color_space_.GetSDRWhiteLevel(&sdr_max_luminance_nits)) { - this->display_color_spaces_.SetSDRMaxLuminanceNits( - sdr_max_luminance_nits); - } this->premultiplied_alpha_ = std::get<3>(GetParam()); } @@ -4773,7 +4767,7 @@ } gfx::ColorTransform::Options options; - options.sdr_max_luminance_nits = gfx::ColorSpace::kDefaultSDRWhiteLevelV2; + options.sdr_max_luminance_nits = gfx::ColorSpace::kDefaultSDRWhiteLevel; std::unique_ptr<gfx::ColorTransform> transform = gfx::ColorTransform::NewColorTransform(this->src_color_space_, this->dst_color_space_, options);
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc index 4e45462731..3625745 100644 --- a/components/viz/service/display/surface_aggregator_unittest.cc +++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -6000,13 +6000,13 @@ gfx::BufferFormat::RGBA_8888); display_color_spaces.SetOutputColorSpaceAndBufferFormat( gfx::ContentColorUsage::kWideColorGamut, true /* needs_alpha */, - gfx::ColorSpace::CreateSCRGBLinear(), gfx::BufferFormat::RGBA_8888); + gfx::ColorSpace::CreateSRGBLinear(), gfx::BufferFormat::RGBA_8888); display_color_spaces.SetOutputColorSpaceAndBufferFormat( gfx::ContentColorUsage::kHDR, false /* needs_alpha */, gfx::ColorSpace::CreateHDR10(), gfx::BufferFormat::BGRA_1010102); display_color_spaces.SetOutputColorSpaceAndBufferFormat( gfx::ContentColorUsage::kHDR, true /* needs_alpha */, - gfx::ColorSpace::CreateSCRGBLinear(), gfx::BufferFormat::RGBA_F16); + gfx::ColorSpace::CreateSRGBLinear(), gfx::BufferFormat::RGBA_F16); std::vector<Pass> passes = { Pass(quads[0], CompositorRenderPassId{2}, kSurfaceSize), @@ -6085,7 +6085,7 @@ gfx::BufferFormat::BGRA_1010102); display_color_spaces.SetOutputColorSpaceAndBufferFormat( gfx::ContentColorUsage::kHDR, true /* needs_alpha */, - gfx::ColorSpace::CreateSCRGBLinear(), gfx::BufferFormat::RGBA_F16); + gfx::ColorSpace::CreateSRGBLinear(), gfx::BufferFormat::RGBA_F16); // Opaque content renders to the appropriate space directly. passes[1].has_transparent_background = false;
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index 51c829c9..4828b3e 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -192,6 +192,14 @@ begin_frame_interval_ = interval; } +void CompositorFrameSinkSupport::OnSurfaceCommitted(Surface* surface) { + if (surface->HasPendingFrame()) { + // Make sure we periodically check if the frame should activate. + pending_surfaces_.insert(surface); + UpdateNeedsBeginFramesInternal(); + } +} + void CompositorFrameSinkSupport::OnSurfaceActivated(Surface* surface) { DCHECK(surface); DCHECK(surface->HasActiveFrame()); @@ -281,7 +289,7 @@ frame_sink_manager_->OnFrameTokenChanged(frame_sink_id_, frame_token); } -void CompositorFrameSinkSupport::OnSurfaceProcessed(Surface* surface) { +void CompositorFrameSinkSupport::SendCompositorFrameAck() { DidReceiveCompositorFrameAck(); } @@ -676,9 +684,7 @@ TRACE_EVENT_SCOPE_THREAD); return SubmitResult::SIZE_MISMATCH; case Surface::QueueFrameResult::ACCEPTED_PENDING: - // Make sure we periodically check if the frame should activate. - pending_surfaces_.insert(current_surface); - UpdateNeedsBeginFramesInternal(); + // Pending frames are processed in OnSurfaceCommitted. break; case Surface::QueueFrameResult::ACCEPTED_ACTIVE: // Nothing to do here.
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h index f3a5548..704adeff 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -141,6 +141,7 @@ void ThrottleBeginFrame(base::TimeDelta interval); // SurfaceClient implementation. + void OnSurfaceCommitted(Surface* surface) override; void OnSurfaceActivated(Surface* surface) override; void OnSurfaceDestroyed(Surface* surface) override; void OnSurfaceWillDraw(Surface* surface) override; @@ -155,7 +156,7 @@ std::vector<PendingCopyOutputRequest> TakeCopyOutputRequests( const LocalSurfaceId& local_surface_id) override; void OnFrameTokenChanged(uint32_t frame_token) override; - void OnSurfaceProcessed(Surface* surface) override; + void SendCompositorFrameAck() override; void OnSurfaceAggregatedDamage( Surface* surface, const LocalSurfaceId& local_surface_id,
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index 0a4a21b..dad49bc 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -70,7 +70,9 @@ : shared_bitmap_manager_(params.shared_bitmap_manager), output_surface_provider_(params.output_surface_provider), gmb_context_provider_(params.gmb_context_provider), - surface_manager_(this, params.activation_deadline_in_frames), + surface_manager_(this, + params.activation_deadline_in_frames, + params.max_uncommitted_frames), hit_test_manager_(surface_manager()), restart_id_(params.restart_id), run_all_compositor_stages_before_draw_(
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h index 833d23c8..d736d6b 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -87,6 +87,7 @@ DebugRendererSettings debug_renderer_settings; base::ProcessId host_process_id = base::kNullProcessId; raw_ptr<HintSessionFactory> hint_session_factory = nullptr; + size_t max_uncommitted_frames = 0; }; explicit FrameSinkManagerImpl(const InitParams& params);
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc index 900270f..9a68ef9 100644 --- a/components/viz/service/surfaces/surface.cc +++ b/components/viz/service/surfaces/surface.cc
@@ -80,11 +80,13 @@ Surface::Surface(const SurfaceInfo& surface_info, SurfaceManager* surface_manager, SurfaceAllocationGroup* allocation_group, - base::WeakPtr<SurfaceClient> surface_client) + base::WeakPtr<SurfaceClient> surface_client, + size_t max_uncommitted_frames) : surface_info_(surface_info), surface_manager_(surface_manager), surface_client_(std::move(surface_client)), - allocation_group_(allocation_group) { + allocation_group_(allocation_group), + max_uncommitted_frames_(max_uncommitted_frames) { TRACE_EVENT_ASYNC_BEGIN1(TRACE_DISABLED_BY_DEFAULT("viz.surface_lifetime"), "Surface", this, "surface_info", surface_info.ToString()); @@ -189,30 +191,70 @@ return QueueFrameResult::REJECTED; } - QueueFrameResult result = QueueFrameResult::ACCEPTED_ACTIVE; + // Receive and track the resources referenced from the CompositorFrame + // regardless of whether it's pending or active. + surface_client_->ReceiveFromChild(frame.resource_list); + + QueueFrameResult result = QueueFrameResult::ACCEPTED_PENDING; + + if (!max_uncommitted_frames_) { + result = CommitFrame(FrameData(std::move(frame), frame_index)); + } else { + // Return oldest frame if uncommitted queue is full. + DCHECK_LE(uncommitted_frames_.size(), max_uncommitted_frames_); + if (uncommitted_frames_.size() == max_uncommitted_frames_) { + TRACE_EVENT_INSTANT1("viz", "DropUncommitedFrame", + TRACE_EVENT_SCOPE_THREAD, "queue_length", + uncommitted_frames_.size()); + + UnrefFrameResourcesAndRunCallbacks( + std::move(uncommitted_frames_.front())); + uncommitted_frames_.pop_front(); + } + + uncommitted_frames_.push_back(FrameData(std::move(frame), frame_index)); + + // If we still have space in queue we should send ack the client because we + // can receive another frame without dropping it. + if (uncommitted_frames_.size() < max_uncommitted_frames_) { + TRACE_EVENT_INSTANT1("viz", "AckingUncommitedFrame", + TRACE_EVENT_SCOPE_THREAD, "queue_length", + uncommitted_frames_.size()); + uncommitted_frames_.back().SendAckIfNeeded(surface_client_.get()); + } + + surface_manager_->OnSurfaceHasNewUncommittedFrame(this); + } + // The frame should not fail to display beyond this point. Release the + // callback so it is not called. + std::ignore = frame_rejected_callback.Release(); + + return result; +} + +Surface::QueueFrameResult Surface::CommitFrame(FrameData frame) { + TRACE_EVENT1("viz", "Surface::CommitFrame", "SurfaceId", + surface_id().ToString()); is_latency_info_taken_ = false; if (active_frame_data_ || pending_frame_data_) previous_frame_surface_id_ = surface_id(); - TakePendingLatencyInfo(&frame.metadata.latency_info); + TakePendingLatencyInfo(&frame.frame.metadata.latency_info); absl::optional<FrameData> previous_pending_frame_data = std::move(pending_frame_data_); pending_frame_data_.reset(); - UpdateActivationDependencies(frame); + UpdateActivationDependencies(frame.frame); - // Receive and track the resources referenced from the CompositorFrame - // regardless of whether it's pending or active. - surface_client_->ReceiveFromChild(frame.resource_list); - + QueueFrameResult result = QueueFrameResult::ACCEPTED_ACTIVE; if (activation_dependencies_.empty()) { // If there are no blockers, then immediately activate the frame. - ActivateFrame(FrameData(std::move(frame), frame_index)); + ActivateFrame(std::move(frame)); } else { - pending_frame_data_ = FrameData(std::move(frame), frame_index); + pending_frame_data_ = std::move(frame); auto traced_value = std::make_unique<base::trace_event::TracedValue>(); traced_value->BeginArray("Pending"); @@ -240,9 +282,8 @@ // Returns resources for the previous pending frame. UnrefFrameResourcesAndRunCallbacks(std::move(previous_pending_frame_data)); - // The frame should not fail to display beyond this point. Release the - // callback so it is not called. - std::ignore = frame_rejected_callback.Release(); + if (surface_client_) + surface_client_->OnSurfaceCommitted(this); return result; } @@ -340,6 +381,14 @@ Surface::FrameData::~FrameData() = default; +void Surface::FrameData::SendAckIfNeeded(SurfaceClient* client) { + if (!frame_acked) { + frame_acked = true; + if (client) + client->SendCompositorFrameAck(); + } +} + void Surface::ActivatePendingFrame() { DCHECK(pending_frame_data_); FrameData frame_data = std::move(*pending_frame_data_); @@ -356,6 +405,67 @@ ActivateFrame(std::move(frame_data)); } +void Surface::CommitFramesRecursively(const CommitPredicate& predicate) { + TRACE_EVENT1("viz", "Surface::CommitFramesRecursively", "SurfaceId", + surface_id().ToString()); + + // This should only be called if we use uncommitted frames queue. + DCHECK_GT(max_uncommitted_frames_, 0u); + + while (!uncommitted_frames_.empty()) { + const auto& ack = + uncommitted_frames_.front().frame.metadata.begin_frame_ack; + + if (!predicate.Run(surface_id(), ack.frame_id)) + break; + + CommitFrame(std::move(uncommitted_frames_.front())); + uncommitted_frames_.pop_front(); + } + + if (HasPendingFrame()) { + for (auto& range : pending_frame_data_->frame.metadata.referenced_surfaces) + surface_manager_->CommitFramesInRangeRecursively(range, predicate); + } + + if (HasActiveFrame()) { + for (auto& range : active_frame_data_->frame.metadata.referenced_surfaces) + surface_manager_->CommitFramesInRangeRecursively(range, predicate); + } + + // If we freed up some space in queue send ack for the last frame if it's + // still unacked, so client can continue producing frames. + if (uncommitted_frames_.size() < max_uncommitted_frames_) { + if (!uncommitted_frames_.empty()) + uncommitted_frames_.back().SendAckIfNeeded(surface_client_.get()); + + // Only last frame can be unacked because we ack frames as we put them in + // queue if queue isn't full. If we acked frame above, now verify that + // they all are acked, to ensure we ack frame in order. +#if DCHECK_IS_ON() + for (auto& frames : uncommitted_frames_) { + DCHECK(frames.frame_acked); + } +#endif + } +} + +absl::optional<BeginFrameId> Surface::GetFirstUncommitedFrameId() { + if (uncommitted_frames_.empty()) + return absl::nullopt; + return uncommitted_frames_.front().frame.metadata.begin_frame_ack.frame_id; +} + +absl::optional<BeginFrameId> Surface::GetUncommitedFrameIdNewerThan( + const BeginFrameId& frame_id) { + for (auto& frame : uncommitted_frames_) { + if (frame.frame.metadata.begin_frame_ack.frame_id.IsNextInSequenceTo( + frame_id)) + return frame.frame.metadata.begin_frame_ack.frame_id; + } + return absl::nullopt; +} + void Surface::UpdateReferencedAllocationGroups( std::vector<SurfaceAllocationGroup*> new_referenced_allocation_groups) { base::flat_set<SurfaceAllocationGroup*> new_set( @@ -668,11 +778,8 @@ } void Surface::SendAckToClient() { - if (!active_frame_data_ || active_frame_data_->frame_acked) - return; - active_frame_data_->frame_acked = true; - if (surface_client_) - surface_client_->OnSurfaceProcessed(this); + if (active_frame_data_) + active_frame_data_->SendAckIfNeeded(surface_client_.get()); } void Surface::MarkAsDrawn() { @@ -718,8 +825,7 @@ resource.sync_token.Clear(); surface_client_->UnrefResources(std::move(resources)); - if (!frame_data->frame_acked) - surface_client_->OnSurfaceProcessed(this); + frame_data->SendAckIfNeeded(surface_client_.get()); // If we won't be getting a presented notification, we'll notify the client // when the frame is unref'd. @@ -790,7 +896,6 @@ } void Surface::ActivatePendingFrameForInheritedDeadline() { - DCHECK(HasPendingFrame()); // Deadline inheritance implies that this surface was blocking the embedder, // so there shouldn't be an active frame. DCHECK(!HasActiveFrame());
diff --git a/components/viz/service/surfaces/surface.h b/components/viz/service/surfaces/surface.h index 30c4619..565c043 100644 --- a/components/viz/service/surfaces/surface.h +++ b/components/viz/service/surfaces/surface.h
@@ -17,6 +17,7 @@ #include "base/callback.h" #include "base/callback_helpers.h" +#include "base/containers/circular_deque.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/platform_thread.h" @@ -53,24 +54,32 @@ // A Surface is a representation of a sequence of CompositorFrames with a // common set of properties uniquely identified by a SurfaceId. In particular, // all CompositorFrames submitted to a single Surface share properties described -// in SurfaceInfo: device scale factor and size. A Surface can hold up to two +// in SurfaceInfo: device scale factor and size. A Surface can hold up few // CompositorFrames at a given time: // -// Active frame: An active frame is a candidate for display. A -// CompositorFrame is active if it has been explicitly marked -// as active after a deadline has passed or all its -// dependencies are active. +// Uncommitted frames: It's frame that has been received, but hasn't been +// processed yet. There can be up to +// `max_uncommitted_frames_` in this state. If +// `max_uncommitted_frames_` is zero all frames are +// committed as soon as they are received. // -// Pending frame: A pending CompositorFrame cannot be displayed on screen. A -// CompositorFrame is pending if it has unresolved -// dependencies: surface Ids to which there are no active -// CompositorFrames. +// Pending frame: A pending CompositorFrame cannot be displayed on +// screen. A CompositorFrame is pending when it has been +// committed but has unresolved dependencies: surface Ids +// to which there are no active CompositorFrames. There +// can be only one pending frame. // -// This two stage mechanism for managing CompositorFrames from a client exists -// to enable best-effort synchronization across clients. A surface subtree will -// remain pending until all dependencies are resolved: all clients have -// submitted CompositorFrames corresponding to a new property of the subtree -// (e.g. a new size). +// Active frame: An active frame is a candidate for display. A +// CompositorFrame is active if it has been explicitly +// marked as active after a deadline has passed or all +// its dependencies are active. There can be only one +// active frame. +// +// This pending+active frame mechanism for managing CompositorFrames from a +// client exists to enable best-effort synchronization across clients. A surface +// subtree will remain pending until all dependencies are resolved: all clients +// have submitted CompositorFrames corresponding to a new property of the +// subtree (e.g. a new size). // // Clients are assumed to be untrusted and so a client may not submit a // CompositorFrame to satisfy the dependency of the parent. Thus, by default, a @@ -78,6 +87,13 @@ // deadline passes, then the CompositorFrame will activate despite missing // dependencies. The activated CompositorFrame can specify fallback behavior in // the event of missing dependencies at display time. +// +// On WebView display compositor runs asynchronously in regards of BeginFrames +// and CompositorFrame submissions, to avoid frame drops due to racyness +// uncommitted queue mechanism is used. When clients submits frame it goes to +// the queue and when the display compositor draws frames are committed from +// the queue to the pending or active frame. + class VIZ_SERVICE_EXPORT Surface final { public: class PresentationHelper { @@ -103,10 +119,14 @@ base::OnceCallback<void(const gfx::PresentationFeedback&)>; enum QueueFrameResult { REJECTED, ACCEPTED_ACTIVE, ACCEPTED_PENDING }; + using CommitPredicate = + base::RepeatingCallback<bool(const SurfaceId&, const BeginFrameId&)>; + Surface(const SurfaceInfo& surface_info, SurfaceManager* surface_manager, SurfaceAllocationGroup* allocation_group, - base::WeakPtr<SurfaceClient> surface_client); + base::WeakPtr<SurfaceClient> surface_client, + size_t max_uncommitted_frames); Surface(const Surface&) = delete; Surface& operator=(const Surface&) = delete; @@ -137,14 +157,19 @@ void SetPreviousFrameSurface(Surface* surface); - // Returns false if |frame| is invalid. - // |frame_rejected_callback| will be called once if the frame will not be - // displayed. + // Returns false if |frame| is invalid. |frame_rejected_callback| will be + // called once if the frame will not be displayed. QueueFrameResult QueueFrame( CompositorFrame frame, uint64_t frame_index, base::ScopedClosureRunner frame_rejected_callback); + // Commits frame(s) in this Surface and its dependencies. For each affected + // surface, the predicate will be called for each uncommitted frame in each + // surface from the oldest to the newest and will abort at first case of + // returning false. + void CommitFramesRecursively(const CommitPredicate& predicate); + // Notifies the Surface that a blocking SurfaceId now has an active // frame. void NotifySurfaceIdAvailable(const SurfaceId& surface_id); @@ -286,6 +311,14 @@ void DidAggregate(); + // Returns frame id of the oldest uncommitted frame if any, + absl::optional<BeginFrameId> GetFirstUncommitedFrameId(); + + // Returns frame id of the oldest uncommitted frame that is newer than + // provided `frame_id`. + absl::optional<BeginFrameId> GetUncommitedFrameIdNewerThan( + const BeginFrameId& frame_id); + private: struct FrameData { FrameData(CompositorFrame&& frame, uint64_t frame_index); @@ -299,6 +332,8 @@ return std::move(frame.metadata.delegated_ink_metadata); } + void SendAckIfNeeded(SurfaceClient* client); + CompositorFrame frame; uint64_t frame_index; // Whether the frame has been displayed or not. @@ -337,6 +372,10 @@ // Called when all of the surface's dependencies have been resolved. void ActivateFrame(FrameData frame_data); + // Called when display compositor is ready for this frame to be processed and + // it can become pending or active. + QueueFrameResult CommitFrame(FrameData frame); + // Resolve the activation deadline specified by |current_frame| into a wall // time to be used by SurfaceDependencyDeadline. FrameDeadline ResolveFrameDeadline(const CompositorFrame& current_frame); @@ -362,6 +401,10 @@ absl::optional<FrameData> pending_frame_data_; absl::optional<FrameData> active_frame_data_; + + // Queue of uncommitted frames, oldest first. + base::circular_deque<FrameData> uncommitted_frames_; + absl::optional<CompositorFrame> interpolated_frame_; bool seen_first_frame_activation_ = false; bool seen_first_surface_embedding_ = false; @@ -397,6 +440,8 @@ bool has_damage_from_interpolated_frame_ = false; + const size_t max_uncommitted_frames_; + base::WeakPtrFactory<Surface> weak_factory_{this}; };
diff --git a/components/viz/service/surfaces/surface_allocation_group.h b/components/viz/service/surfaces/surface_allocation_group.h index 29cc141..8a89ccc 100644 --- a/components/viz/service/surfaces/surface_allocation_group.h +++ b/components/viz/service/surfaces/surface_allocation_group.h
@@ -127,6 +127,8 @@ return surfaces_.empty() ? nullptr : surfaces_.back(); } + const std::vector<Surface*>& surfaces() const { return surfaces_; } + private: // Returns an iterator to the latest surface in |surfaces_| whose SurfaceId is // older than or equal to |surface_id|. The returned surface may not be active
diff --git a/components/viz/service/surfaces/surface_client.h b/components/viz/service/surfaces/surface_client.h index 19e303c..37482e1 100644 --- a/components/viz/service/surfaces/surface_client.h +++ b/components/viz/service/surfaces/surface_client.h
@@ -40,6 +40,10 @@ virtual ~SurfaceClient() = default; + // Called when |surface| has committed a new CompositorFrame that become + // pending or active. + virtual void OnSurfaceCommitted(Surface* surface) = 0; + // Called when |surface| has a new CompositorFrame available for display. virtual void OnSurfaceActivated(Surface* surface) = 0; @@ -73,9 +77,9 @@ // Notifies the client that a frame with |token| has been activated. virtual void OnFrameTokenChanged(uint32_t frame_token) = 0; - // Notifies the client that the submitted CompositorFrame has been processed - // (where processed may mean the frame has been displayed, or discarded). - virtual void OnSurfaceProcessed(Surface* surface) = 0; + // Sends a compositor frame ack to the client. Usually happens when viz is + // ready to receive another frame without dropping previous one. + virtual void SendCompositorFrameAck() = 0; // Notifies the client that a frame with |token| has been presented. virtual void OnSurfacePresented(
diff --git a/components/viz/service/surfaces/surface_manager.cc b/components/viz/service/surfaces/surface_manager.cc index 43a0037..924fe2d 100644 --- a/components/viz/service/surfaces/surface_manager.cc +++ b/components/viz/service/surfaces/surface_manager.cc
@@ -38,12 +38,14 @@ SurfaceManager::SurfaceManager( SurfaceManagerDelegate* delegate, - absl::optional<uint32_t> activation_deadline_in_frames) + absl::optional<uint32_t> activation_deadline_in_frames, + size_t max_uncommitted_frames) : delegate_(delegate), activation_deadline_in_frames_(activation_deadline_in_frames), root_surface_id_(FrameSinkId(0u, 0u), LocalSurfaceId(1u, base::UnguessableToken::Create())), - tick_clock_(base::DefaultTickClock::GetInstance()) { + tick_clock_(base::DefaultTickClock::GetInstance()), + max_uncommitted_frames_(max_uncommitted_frames) { thread_checker_.DetachFromThread(); // Android WebView doesn't have a task runner and doesn't need the timer. @@ -113,8 +115,9 @@ if (!allocation_group) return nullptr; - std::unique_ptr<Surface> surface = std::make_unique<Surface>( - surface_info, this, allocation_group, surface_client); + std::unique_ptr<Surface> surface = + std::make_unique<Surface>(surface_info, this, allocation_group, + surface_client, max_uncommitted_frames_); surface->SetDependencyDeadline( std::make_unique<SurfaceDependencyDeadline>(tick_clock_)); surface_map_[surface_info.id()] = std::move(surface); @@ -450,6 +453,11 @@ observer.OnFirstSurfaceActivation(surface_info); } +void SurfaceManager::OnSurfaceHasNewUncommittedFrame(Surface* surface) { + for (auto& observer : observer_list_) + observer.OnSurfaceHasNewUncommittedFrame(surface->surface_id()); +} + void SurfaceManager::SurfaceActivated(Surface* surface) { // Trigger a display frame if necessary. const CompositorFrameMetadata& metadata = surface->GetActiveFrameMetadata(); @@ -629,4 +637,33 @@ delegate_->AggregatedFrameSinksChanged(); } +void SurfaceManager::CommitFramesInRangeRecursively( + const SurfaceRange& range, + const CommitPredicate& predicate) { + // Technically we need only latest active surface, but because activation will + // happen during commit, it's impossible to predict which one will be active, + // so we're committing all surfaces in range. + + // If start of the range is in a different allocation group, process it first + // to keep activation in order. + if (range.start() && range.start()->local_surface_id().embed_token() != + range.end().local_surface_id().embed_token()) { + if (auto* allocation_group = + GetAllocationGroupForSurfaceId(*range.start())) { + for (auto* surface : allocation_group->surfaces()) { + if (range.IsInRangeInclusive(surface->surface_id())) + surface->CommitFramesRecursively(predicate); + } + } + } + + // Process the allocation group of the end of the range. + if (auto* allocation_group = GetAllocationGroupForSurfaceId(range.end())) { + for (auto* surface : allocation_group->surfaces()) { + if (range.IsInRangeInclusive(surface->surface_id())) + surface->CommitFramesRecursively(predicate); + } + } +} + } // namespace viz
diff --git a/components/viz/service/surfaces/surface_manager.h b/components/viz/service/surfaces/surface_manager.h index b20b20bb..36ca45d 100644 --- a/components/viz/service/surfaces/surface_manager.h +++ b/components/viz/service/surfaces/surface_manager.h
@@ -44,11 +44,13 @@ class SurfaceRange; struct BeginFrameAck; struct BeginFrameArgs; +struct BeginFrameId; class VIZ_SERVICE_EXPORT SurfaceManager { public: SurfaceManager(SurfaceManagerDelegate* delegate, - absl::optional<uint32_t> activation_deadline_in_frames); + absl::optional<uint32_t> activation_deadline_in_frames, + size_t max_uncommitted_frames); SurfaceManager(const SurfaceManager&) = delete; SurfaceManager& operator=(const SurfaceManager&) = delete; @@ -108,6 +110,9 @@ // Called when a surface has an active frame for the first time. void FirstSurfaceActivation(const SurfaceInfo& surface_info); + // Called when there is new frame in uncommitted queue of the surface. + void OnSurfaceHasNewUncommittedFrame(Surface* surface); + // Called when a CompositorFrame within |surface| has activated. void SurfaceActivated(Surface* surface); @@ -200,6 +205,15 @@ // changed since the previous aggregation. void AggregatedFrameSinksChanged(); + using CommitPredicate = + base::RepeatingCallback<bool(const SurfaceId&, const BeginFrameId&)>; + // Commits all surfaces in range and their referenced surfaces. For each + // surface processed calls `predicate` for each uncommitted frame from oldest + // to newest. If predicate returns true, surface is committed. If not the + // surface processing stops and we go to the next surface. + void CommitFramesInRangeRecursively(const SurfaceRange& range, + const CommitPredicate& predicate); + private: friend class CompositorFrameSinkSupportTest; friend class FrameSinkManagerTest; @@ -326,6 +340,10 @@ bool allocation_groups_need_garbage_collection_ = false; + // Maximum length of uncommitted queue, zero means all frames are committed + // automatically. + const size_t max_uncommitted_frames_; + base::WeakPtrFactory<SurfaceManager> weak_factory_{this}; };
diff --git a/components/viz/service/surfaces/surface_observer.h b/components/viz/service/surfaces/surface_observer.h index 7bbb7b9..6bb23de 100644 --- a/components/viz/service/surfaces/surface_observer.h +++ b/components/viz/service/surfaces/surface_observer.h
@@ -23,6 +23,9 @@ // time. virtual void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) {} + // Called when there is new frame in uncommitted queue of the surface. + virtual void OnSurfaceHasNewUncommittedFrame(const SurfaceId& surface_id) {} + // Called when a CompositorFrame within a surface corresponding to // |surface_id| activates. virtual void OnSurfaceActivated(const SurfaceId& surface_id) {}
diff --git a/components/viz/test/stub_surface_client.h b/components/viz/test/stub_surface_client.h index 7c8b0873..9eba8cb 100644 --- a/components/viz/test/stub_surface_client.h +++ b/components/viz/test/stub_surface_client.h
@@ -18,6 +18,7 @@ StubSurfaceClient(); ~StubSurfaceClient() override; + void OnSurfaceCommitted(Surface* surface) override {} void OnSurfaceActivated(Surface* surface) override {} void OnSurfaceDestroyed(Surface* surface) override {} void OnSurfaceWillDraw(Surface* surface) override {} @@ -30,7 +31,7 @@ std::vector<PendingCopyOutputRequest> TakeCopyOutputRequests( const LocalSurfaceId& latest_surface_id) override; void OnFrameTokenChanged(uint32_t frame_token) override {} - void OnSurfaceProcessed(Surface* surface) override {} + void SendCompositorFrameAck() override {} void OnSurfaceAggregatedDamage( Surface* surface, const LocalSurfaceId& local_surface_id,
diff --git a/components/webapps/browser/BUILD.gn b/components/webapps/browser/BUILD.gn index 594604a..76e56c9 100644 --- a/components/webapps/browser/BUILD.gn +++ b/components/webapps/browser/BUILD.gn
@@ -22,6 +22,8 @@ "banners/app_banner_metrics.h", "banners/app_banner_settings_helper.cc", "banners/app_banner_settings_helper.h", + "features.cc", + "features.h", "installable/installable_data.cc", "installable/installable_data.h", "installable/installable_logging.cc", @@ -76,8 +78,6 @@ "android/app_banner_manager_android.h", "android/bottomsheet/pwa_bottom_sheet_controller.cc", "android/bottomsheet/pwa_bottom_sheet_controller.h", - "android/features.cc", - "android/features.h", "android/installable/installable_ambient_badge_client.h", "android/installable/installable_ambient_badge_infobar.cc", "android/installable/installable_ambient_badge_infobar.h",
diff --git a/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc b/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc index ecc8f3e7..e10a2957 100644 --- a/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc +++ b/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc
@@ -25,6 +25,7 @@ #include "components/favicon_base/favicon_types.h" #include "components/webapps/browser/android/webapps_icon_utils.h" #include "components/webapps/browser/android/webapps_utils.h" +#include "components/webapps/browser/features.h" #include "components/webapps/browser/installable/installable_manager.h" #include "components/webapps/common/constants.h" #include "components/webapps/common/web_page_metadata.mojom.h" @@ -57,7 +58,7 @@ params.valid_primary_icon = true; params.prefer_maskable_icon = WebappsIconUtils::DoesAndroidSupportMaskableIcons(); - params.wait_for_worker = true; + params.wait_for_worker = !features::SkipInstallServiceWorkerCheck(); return params; } @@ -65,11 +66,11 @@ InstallableParams params; params.check_eligibility = true; params.valid_manifest = true; - params.has_worker = true; + params.has_worker = !features::SkipInstallServiceWorkerCheck(); + params.wait_for_worker = !features::SkipInstallServiceWorkerCheck(); params.valid_primary_icon = true; params.prefer_maskable_icon = WebappsIconUtils::DoesAndroidSupportMaskableIcons(); - params.wait_for_worker = true; return params; } @@ -274,7 +275,8 @@ return; bool webapk_compatible = - (data.NoBlockingErrors() && data.valid_manifest && data.has_worker && + (data.NoBlockingErrors() && data.valid_manifest && + data.worker_check_passed && WebappsUtils::AreWebManifestUrlsWebApkCompatible(data.manifest)); if (!webapk_compatible && !data.errors.empty()) { installable_status_code_ = data.errors[0];
diff --git a/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc b/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc index 0c10727..e85f32e 100644 --- a/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc +++ b/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc
@@ -18,9 +18,11 @@ #include "base/strings/utf_string_conversions.h" #include "base/task/cancelable_task_tracker.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "components/favicon/content/large_favicon_provider_getter.h" #include "components/favicon/core/large_favicon_provider.h" #include "components/favicon_base/favicon_types.h" +#include "components/webapps/browser/features.h" #include "components/webapps/browser/installable/installable_logging.h" #include "components/webapps/browser/installable/installable_manager.h" #include "components/webapps/browser/installable/installable_metrics.h" @@ -175,7 +177,7 @@ nullptr /* splash_icon */, params.prefer_maskable_icon, std::vector<SkBitmap>() /* screenshots */, params.valid_manifest ? is_installable : false, - params.has_worker ? is_installable : false}); + params.has_worker ? is_installable : true}); } void SetHasServiceWorker(bool worker) { has_worker_ = worker; } @@ -431,6 +433,11 @@ // but not be WebAPK-compatible. Only relevant when checking WebAPK // compatibility. TEST_F(AddToHomescreenDataFetcherTest, ServiceWorkerCheckTimesOutPwa) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {}, {features::kSkipServiceWorkerCheckInstallOnly, + features::kSkipServiceWorkerCheckAll}); + SetManifest(BuildDefaultManifest()); SetShouldServiceWorkerTimeOut(true); @@ -450,6 +457,11 @@ } TEST_F(AddToHomescreenDataFetcherTest, ServiceWorkerCheckTimesOutNonPwa) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {}, {features::kSkipServiceWorkerCheckInstallOnly, + features::kSkipServiceWorkerCheckAll}); + SetManifest(BuildDefaultManifest()); SetShouldServiceWorkerTimeOut(true); SetHasServiceWorker(false); @@ -470,6 +482,11 @@ } TEST_F(AddToHomescreenDataFetcherTest, ServiceWorkerCheckTimesOutUnknown) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {}, {features::kSkipServiceWorkerCheckInstallOnly, + features::kSkipServiceWorkerCheckAll}); + SetManifest(BuildDefaultManifest()); SetShouldServiceWorkerTimeOut(true); SetHasServiceWorker(false); @@ -514,6 +531,11 @@ } TEST_F(AddToHomescreenDataFetcherTest, ManifestNameClobbersWebApplicationName) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {}, {features::kSkipServiceWorkerCheckInstallOnly, + features::kSkipServiceWorkerCheckAll}); + // Test that when the manifest provides Manifest::name but not // Manifest::short_name that Manifest::name is used as the title. { @@ -615,4 +637,88 @@ GURL(kDefaultIconUrl)); } +TEST_F(AddToHomescreenDataFetcherTest, + NoServiceWorkerInstallable_InstallOnlyFlag) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {features::kSkipServiceWorkerCheckInstallOnly}, + {features::kSkipServiceWorkerCheckAll}); + SetManifest(BuildDefaultManifest()); + SetHasServiceWorker(false); + + // Check where InstallableManager doesn't finish working after the timeout. + // This is akin to waiting for a service worker forever. + base::HistogramTester histograms; + ObserverWaiter waiter; + std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); + RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName, + kDefaultManifestName, blink::mojom::DisplayMode::kStandalone, + true /*is_webapk_compatible*/, + InstallableStatusCode::NO_ERROR_DETECTED); + + // Navigate to ensure the histograms are written. + NavigateAndCommit(GURL("about:blank")); + CheckHistograms(histograms); + + EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); + EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, + GURL(kDefaultIconUrl)); +} + +TEST_F(AddToHomescreenDataFetcherTest, NoServiceWorkerInstallable_SkipAllFlag) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {features::kSkipServiceWorkerCheckAll}, + {features::kSkipServiceWorkerCheckInstallOnly}); + SetManifest(BuildDefaultManifest()); + SetHasServiceWorker(false); + + // Check where InstallableManager doesn't finish working after the timeout. + // This is akin to waiting for a service worker forever. + base::HistogramTester histograms; + ObserverWaiter waiter; + std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); + RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName, + kDefaultManifestName, blink::mojom::DisplayMode::kStandalone, + true /*is_webapk_compatible*/, + InstallableStatusCode::NO_ERROR_DETECTED); + + // Navigate to ensure the histograms are written. + NavigateAndCommit(GURL("about:blank")); + CheckHistograms(histograms); + + EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); + EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, + GURL(kDefaultIconUrl)); +} + +TEST_F(AddToHomescreenDataFetcherTest, ServiceWorkerTimeOutInstallable) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {features::kSkipServiceWorkerCheckInstallOnly, + features::kSkipServiceWorkerCheckAll}, + {}); + + SetManifest(BuildDefaultManifest()); + SetShouldServiceWorkerTimeOut(true); + + // Check where InstallableManager doesn't finish working after the timeout. + // This is akin to waiting for a service worker forever. + base::HistogramTester histograms; + ObserverWaiter waiter; + std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); + RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName, + kDefaultManifestName, blink::mojom::DisplayMode::kStandalone, + true /*is_webapk_compatible*/, + InstallableStatusCode::NO_ERROR_DETECTED); + + // Navigate to ensure the histograms are written. + NavigateAndCommit(GURL("about:blank")); + CheckHistograms(histograms); + + EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); + EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, + GURL(kDefaultIconUrl)); +} + } // namespace webapps
diff --git a/components/webapps/browser/android/app_banner_manager_android.cc b/components/webapps/browser/android/app_banner_manager_android.cc index 312388cf..aacbfba 100644 --- a/components/webapps/browser/android/app_banner_manager_android.cc +++ b/components/webapps/browser/android/app_banner_manager_android.cc
@@ -26,7 +26,6 @@ #include "components/webapps/browser/android/add_to_homescreen_coordinator.h" #include "components/webapps/browser/android/add_to_homescreen_params.h" #include "components/webapps/browser/android/bottomsheet/pwa_bottom_sheet_controller.h" -#include "components/webapps/browser/android/features.h" #include "components/webapps/browser/android/installable/installable_ambient_badge_infobar_delegate.h" #include "components/webapps/browser/android/shortcut_info.h" #include "components/webapps/browser/android/webapps_icon_utils.h" @@ -34,6 +33,7 @@ #include "components/webapps/browser/android/webapps_utils.h" #include "components/webapps/browser/banners/app_banner_metrics.h" #include "components/webapps/browser/banners/app_banner_settings_helper.h" +#include "components/webapps/browser/features.h" #include "components/webapps/browser/installable/installable_data.h" #include "components/webapps/browser/installable/installable_metrics.h" #include "components/webapps/browser/webapps_client.h"
diff --git a/components/webapps/browser/android/features.cc b/components/webapps/browser/android/features.cc deleted file mode 100644 index eaff933..0000000 --- a/components/webapps/browser/android/features.cc +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/webapps/browser/android/features.h" - -#include "base/feature_list.h" - -namespace webapps { -namespace features { - -const base::Feature kAddToHomescreenMessaging{ - "AddToHomescreenMessaging", base::FEATURE_DISABLED_BY_DEFAULT}; - -// Enables or disables the installable ambient badge infobar. -const base::Feature kInstallableAmbientBadgeInfoBar{ - "InstallableAmbientBadgeInfoBar", base::FEATURE_ENABLED_BY_DEFAULT}; - -// Enables or disables the installable ambient badge message. -const base::Feature kInstallableAmbientBadgeMessage{ - "InstallableAmbientBadgeMessage", base::FEATURE_DISABLED_BY_DEFAULT}; - -} // namespace features -} // namespace webapps
diff --git a/components/webapps/browser/android/features.h b/components/webapps/browser/android/features.h deleted file mode 100644 index 8973d172..0000000 --- a/components/webapps/browser/android/features.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2020 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_WEBAPPS_BROWSER_ANDROID_FEATURES_H_ -#define COMPONENTS_WEBAPPS_BROWSER_ANDROID_FEATURES_H_ - -namespace base { -struct Feature; -} // namespace base - -namespace webapps { -namespace features { - -extern const base::Feature kAddToHomescreenMessaging; -extern const base::Feature kInstallableAmbientBadgeInfoBar; -extern const base::Feature kInstallableAmbientBadgeMessage; - -} // namespace features -} // namespace webapps - -#endif // COMPONENTS_WEBAPPS_BROWSER_ANDROID_FEATURES_H_
diff --git a/components/webapps/browser/android/installable/installable_ambient_badge_infobar_delegate.cc b/components/webapps/browser/android/installable/installable_ambient_badge_infobar_delegate.cc index 9e37ea91..efe28c9 100644 --- a/components/webapps/browser/android/installable/installable_ambient_badge_infobar_delegate.cc +++ b/components/webapps/browser/android/installable/installable_ambient_badge_infobar_delegate.cc
@@ -11,8 +11,8 @@ #include "base/metrics/field_trial_params.h" #include "components/infobars/content/content_infobar_manager.h" #include "components/strings/grit/components_strings.h" -#include "components/webapps/browser/android/features.h" #include "components/webapps/browser/android/installable/installable_ambient_badge_infobar.h" +#include "components/webapps/browser/features.h" #include "components/webapps/browser/webapps_client.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/components/webapps/browser/banners/app_banner_manager.cc b/components/webapps/browser/banners/app_banner_manager.cc index bdf41e4..9cff729 100644 --- a/components/webapps/browser/banners/app_banner_manager.cc +++ b/components/webapps/browser/banners/app_banner_manager.cc
@@ -22,6 +22,7 @@ #include "components/site_engagement/content/site_engagement_service.h" #include "components/webapps/browser/banners/app_banner_metrics.h" #include "components/webapps/browser/banners/app_banner_settings_helper.h" +#include "components/webapps/browser/features.h" #include "components/webapps/browser/installable/installable_data.h" #include "components/webapps/browser/installable/installable_manager.h" #include "components/webapps/browser/installable/installable_metrics.h" @@ -364,8 +365,8 @@ InstallableParams params; params.valid_primary_icon = true; params.valid_manifest = true; - params.has_worker = true; - params.wait_for_worker = true; + params.has_worker = !features::SkipBannerServiceWorkerCheck(); + params.wait_for_worker = !features::SkipBannerServiceWorkerCheck(); return params; } @@ -392,10 +393,23 @@ return; UpdateState(State::ACTIVE); - if (data.has_worker && data.valid_manifest) + if (data.worker_check_passed && data.valid_manifest) TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED); auto error = data.NoBlockingErrors() ? NO_ERROR_DETECTED : data.errors[0]; + + // When |features::SkipInstallServiceWorkerCheck| is true, a service worker is + // still required to display the banner prompt. This would mean that while a + // banner may not appear, the site is still consider installabled if it only + // failed service worker checks. + bool worker_errors_ignored_for_installs = false; + if (features::SkipInstallServiceWorkerCheck() && + data.HasErrorOnlyServiceWorkerErrors()) { + DCHECK(error != NO_ERROR_DETECTED); + worker_errors_ignored_for_installs = true; + error = NO_ERROR_DETECTED; + } + if (error != NO_ERROR_DETECTED) { if (error == NO_MATCHING_SERVICE_WORKER) TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); @@ -420,10 +434,19 @@ return; } + if (worker_errors_ignored_for_installs) { + DCHECK(data.HasErrorOnlyServiceWorkerErrors()); + + SetInstallableWebAppCheckResult( + InstallableWebAppCheckResult::kYes_ByUserRequest); + Stop(SERVICE_WORKER_NOT_REQUIRED); + return; + } + SetInstallableWebAppCheckResult( InstallableWebAppCheckResult::kYes_Promotable); - DCHECK(data.has_worker && data.valid_manifest); + DCHECK(data.worker_check_passed && data.valid_manifest); DCHECK(!data.primary_icon_url.is_empty()); DCHECK(data.primary_icon);
diff --git a/components/webapps/browser/features.cc b/components/webapps/browser/features.cc new file mode 100644 index 0000000..51a8ed3 --- /dev/null +++ b/components/webapps/browser/features.cc
@@ -0,0 +1,43 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/webapps/browser/features.h" + +#include "base/feature_list.h" + +namespace webapps { +namespace features { + +#if BUILDFLAG(IS_ANDROID) +const base::Feature kAddToHomescreenMessaging{ + "AddToHomescreenMessaging", base::FEATURE_DISABLED_BY_DEFAULT}; + +// Enables or disables the installable ambient badge infobar. +const base::Feature kInstallableAmbientBadgeInfoBar{ + "InstallableAmbientBadgeInfoBar", base::FEATURE_ENABLED_BY_DEFAULT}; + +// Enables or disables the installable ambient badge message. +const base::Feature kInstallableAmbientBadgeMessage{ + "InstallableAmbientBadgeMessage", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif // BUILDFLAG(IS_ANDROID) + +// Skip the service worker all install criteria check. +const base::Feature kSkipServiceWorkerCheckAll{ + "SkipServiceWorkerCheckAll", base::FEATURE_DISABLED_BY_DEFAULT}; + +// Skip the service worker install criteria check for installing WebAPKs. +const base::Feature kSkipServiceWorkerCheckInstallOnly{ + "SkipServiceWorkerCheckInstallOnly", base::FEATURE_DISABLED_BY_DEFAULT}; + +bool SkipBannerServiceWorkerCheck() { + return base::FeatureList::IsEnabled(kSkipServiceWorkerCheckAll); +} + +bool SkipInstallServiceWorkerCheck() { + return base::FeatureList::IsEnabled(kSkipServiceWorkerCheckAll) || + base::FeatureList::IsEnabled(kSkipServiceWorkerCheckInstallOnly); +} + +} // namespace features +} // namespace webapps
diff --git a/components/webapps/browser/features.h b/components/webapps/browser/features.h new file mode 100644 index 0000000..cca853d --- /dev/null +++ b/components/webapps/browser/features.h
@@ -0,0 +1,32 @@ +// Copyright 2020 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_WEBAPPS_BROWSER_FEATURES_H_ +#define COMPONENTS_WEBAPPS_BROWSER_FEATURES_H_ + +#include "build/build_config.h" + +namespace base { +struct Feature; +} // namespace base + +namespace webapps { +namespace features { + +#if BUILDFLAG(IS_ANDROID) +extern const base::Feature kAddToHomescreenMessaging; +extern const base::Feature kInstallableAmbientBadgeInfoBar; +extern const base::Feature kInstallableAmbientBadgeMessage; +#endif // BUILDFLAG(IS_ANDROID) + +extern const base::Feature kSkipServiceWorkerCheckAll; +extern const base::Feature kSkipServiceWorkerCheckInstallOnly; + +bool SkipBannerServiceWorkerCheck(); +bool SkipInstallServiceWorkerCheck(); + +} // namespace features +} // namespace webapps + +#endif // COMPONENTS_WEBAPPS_BROWSER_FEATURES_H_
diff --git a/components/webapps/browser/installable/installable_data.cc b/components/webapps/browser/installable/installable_data.cc index f29affba..55a353e55 100644 --- a/components/webapps/browser/installable/installable_data.cc +++ b/components/webapps/browser/installable/installable_data.cc
@@ -5,6 +5,7 @@ #include "components/webapps/browser/installable/installable_data.h" #include <utility> +#include "installable_logging.h" namespace webapps { @@ -19,7 +20,7 @@ bool has_maskable_splash_icon, const std::vector<SkBitmap>& screenshots, bool valid_manifest, - bool has_worker) + bool worker_check_passed) : errors(std::move(errors)), manifest_url(manifest_url), manifest(manifest), @@ -31,7 +32,7 @@ has_maskable_splash_icon(has_maskable_splash_icon), screenshots(screenshots), valid_manifest(valid_manifest), - has_worker(has_worker) {} + worker_check_passed(worker_check_passed) {} InstallableData::~InstallableData() = default; @@ -40,4 +41,16 @@ (errors.size() == 1 && errors[0] == WARN_NOT_OFFLINE_CAPABLE); } +bool InstallableData::HasErrorOnlyServiceWorkerErrors() const { + if (errors.empty() || errors[0] == NO_ERROR_DETECTED) + return false; + + for (auto error : errors) { + if (error != NO_MATCHING_SERVICE_WORKER && error != NOT_OFFLINE_CAPABLE) { + return false; + } + } + return true; +} + } // namespace webapps
diff --git a/components/webapps/browser/installable/installable_data.h b/components/webapps/browser/installable/installable_data.h index 7a04b83..5f7a9f3 100644 --- a/components/webapps/browser/installable/installable_data.h +++ b/components/webapps/browser/installable/installable_data.h
@@ -33,7 +33,7 @@ bool has_maskable_splash_icon, const std::vector<SkBitmap>& screenshots, bool valid_manifest, - bool has_worker); + bool worker_check_passed); InstallableData(const InstallableData&) = delete; InstallableData& operator=(const InstallableData&) = delete; @@ -48,6 +48,10 @@ // M93. bool NoBlockingErrors() const; + // Returns true if there is any |errors| and all errors are service worker + // errors, i.e.|NO_MATCHING_SERVICE_WORKER| or |NOT_OFFLINE_CAPABLE|. + bool HasErrorOnlyServiceWorkerErrors() const; + // Contains all errors encountered during the InstallableManager::GetData // call. Empty if no errors were encountered. std::vector<InstallableStatusCode> errors; @@ -90,12 +94,13 @@ const std::vector<SkBitmap>& screenshots; // true if the site has a valid, installable web app manifest. If - // |valid_manifest| or |has_worker| was true and the site isn't installable, - // the reason will be in |errors|. + // |valid_manifest| or |worker_check_passed| was true and the site isn't + // installable, the reason will be in |errors|. const bool valid_manifest = false; - // true if the site has a service worker with a fetch handler. - const bool has_worker = false; + // true if the site has a service worker with a fetch handler or + // the service worker check was not requested when fetching this data. + const bool worker_check_passed = false; }; using InstallableCallback = base::OnceCallback<void(const InstallableData&)>;
diff --git a/components/webapps/browser/installable/installable_logging.cc b/components/webapps/browser/installable/installable_logging.cc index a0b5b25..31fccd2 100644 --- a/components/webapps/browser/installable/installable_logging.cc +++ b/components/webapps/browser/installable/installable_logging.cc
@@ -143,6 +143,7 @@ case SHOWING_APP_INSTALLATION_DIALOG: case DATA_TIMED_OUT: case WEBAPK_INSTALL_FAILED: + case SERVICE_WORKER_NOT_REQUIRED: case MAX_ERROR_CODE: break; case NOT_FROM_SECURE_ORIGIN: @@ -257,6 +258,7 @@ case SHOWING_APP_INSTALLATION_DIALOG: case DATA_TIMED_OUT: case WEBAPK_INSTALL_FAILED: + case SERVICE_WORKER_NOT_REQUIRED: case MAX_ERROR_CODE: break; case NOT_FROM_SECURE_ORIGIN:
diff --git a/components/webapps/browser/installable/installable_logging.h b/components/webapps/browser/installable/installable_logging.h index 838d191..0e1f5d8 100644 --- a/components/webapps/browser/installable/installable_logging.h +++ b/components/webapps/browser/installable/installable_logging.h
@@ -67,6 +67,7 @@ DATA_TIMED_OUT = 42, WEBAPK_INSTALL_FAILED = 43, MANIFEST_URL_SCHEME_NOT_SUPPORTED_FOR_WEBAPK = 44, + SERVICE_WORKER_NOT_REQUIRED = 45, MAX_ERROR_CODE, };
diff --git a/components/webapps/browser/installable/installable_manager.cc b/components/webapps/browser/installable/installable_manager.cc index 4001f52..eec2e687 100644 --- a/components/webapps/browser/installable/installable_manager.cc +++ b/components/webapps/browser/installable/installable_manager.cc
@@ -540,6 +540,8 @@ has_maskable_splash_icon = (splash_icon->purpose == IconPurpose::MASKABLE); } + bool worker_check_passed = worker_->has_worker || !params.has_worker; + InstallableData data = { std::move(errors), manifest_url(), @@ -552,7 +554,7 @@ has_maskable_splash_icon, screenshots_, valid_manifest_->is_valid, - worker_->has_worker, + worker_check_passed, }; std::move(task.callback).Run(data);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index f35c16b..7bd627b 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -3013,8 +3013,6 @@ "webauth/virtual_authenticator_manager_impl.cc", "webauth/virtual_authenticator_manager_impl.h", "webauth/virtual_authenticator_mojom_traits.h", - "webauth/virtual_authenticator_request_delegate.cc", - "webauth/virtual_authenticator_request_delegate.h", "webauth/virtual_discovery.cc", "webauth/virtual_discovery.h", "webauth/virtual_fido_discovery_factory.cc",
diff --git a/content/browser/devtools/protocol/webauthn_handler.cc b/content/browser/devtools/protocol/webauthn_handler.cc index 30b7e12..7328687 100644 --- a/content/browser/devtools/protocol/webauthn_handler.cc +++ b/content/browser/devtools/protocol/webauthn_handler.cc
@@ -155,12 +155,13 @@ WebAuthn::Dispatcher::wire(dispatcher, this); } -Response WebAuthnHandler::Enable() { +Response WebAuthnHandler::Enable(Maybe<bool> enable_ui) { if (!frame_host_) return Response::ServerError(kDevToolsNotAttached); AuthenticatorEnvironmentImpl::GetInstance()->EnableVirtualAuthenticatorFor( - frame_host_->frame_tree_node()); + frame_host_->frame_tree_node(), + enable_ui.fromMaybe(/*default_value=*/false)); return Response::Success(); }
diff --git a/content/browser/devtools/protocol/webauthn_handler.h b/content/browser/devtools/protocol/webauthn_handler.h index 18babd2..476adea 100644 --- a/content/browser/devtools/protocol/webauthn_handler.h +++ b/content/browser/devtools/protocol/webauthn_handler.h
@@ -28,7 +28,7 @@ void Wire(UberDispatcher* dispatcher) override; // WebAuthn::Backend - CONTENT_EXPORT Response Enable() override; + CONTENT_EXPORT Response Enable(Maybe<bool> enable_ui) override; CONTENT_EXPORT Response Disable() override; Response AddVirtualAuthenticator( std::unique_ptr<WebAuthn::VirtualAuthenticatorOptions> options,
diff --git a/content/browser/devtools/protocol/webauthn_handler_unittest.cc b/content/browser/devtools/protocol/webauthn_handler_unittest.cc index f9d558d..6bcfd3b71 100644 --- a/content/browser/devtools/protocol/webauthn_handler_unittest.cc +++ b/content/browser/devtools/protocol/webauthn_handler_unittest.cc
@@ -24,7 +24,7 @@ }; TEST_F(WebAuthnHandlerTest, EnableFailsGracefullyIfNoFrameHostSet) { - Response response = webauthn_handler()->Enable(); + Response response = webauthn_handler()->Enable(/*enable_ui=*/false); EXPECT_EQ(crdtp::DispatchCode::SERVER_ERROR, response.Code()); EXPECT_EQ("The DevTools session is not attached to a frame", response.Message());
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 9d3872d..1dae1b0 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -9764,11 +9764,26 @@ blink::PermissionsPolicy::CreateForFencedFrame(last_committed_origin_); return; } + RenderFrameHostImpl* parent_frame_host = GetParent(); + auto isolation_info = GetSiteInstance()->GetWebExposedIsolationInfo(); + + if (!parent_frame_host && isolation_info.is_isolated_application()) { + // In Isolated Apps, the top level frame should use the policy declared in + // the Web App Manifest. + blink::ParsedPermissionsPolicy manifest_policy = + GetContentClient()->browser()->GetPermissionsPolicyForIsolatedApp( + GetBrowserContext(), isolation_info.origin()); + permissions_policy_ = blink::PermissionsPolicy::CreateFromParsedPolicy( + manifest_policy, last_committed_origin_); + return; + } + const blink::PermissionsPolicy* parent_policy = parent_frame_host ? parent_frame_host->permissions_policy() : nullptr; blink::ParsedPermissionsPolicy container_policy = browsing_context_state_->effective_frame_policy().container_policy; + permissions_policy_ = blink::PermissionsPolicy::CreateFromParentPolicy( parent_policy, container_policy, last_committed_origin_); } @@ -10323,7 +10338,8 @@ if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableWebAuthDeprecatedMojoTestingApi)) { auto* environment_singleton = AuthenticatorEnvironmentImpl::GetInstance(); - environment_singleton->EnableVirtualAuthenticatorFor(frame_tree_node_); + environment_singleton->EnableVirtualAuthenticatorFor(frame_tree_node_, + /*enable_ui=*/false); environment_singleton->AddVirtualAuthenticatorReceiver(frame_tree_node_, std::move(receiver)); }
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index e1533953..f4fc156 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -101,6 +101,7 @@ #include "ui/base/ime/mock_input_method.h" #include "ui/base/ime/mojom/text_input_state.mojom.h" #include "ui/base/ime/virtual_keyboard_controller.h" +#include "ui/base/ui_base_features.h" #include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_types.h" #include "ui/compositor/compositor.h" @@ -707,6 +708,9 @@ view->TextInputStateChanged(state_with_type_text); } + void RunTimerBasedWheelEventPhaseInfoTest( + bool percent_based_scrolling_enabled); + BrowserTaskEnvironment task_environment_{ base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME}; std::unique_ptr<aura::test::AuraTestHelper> aura_test_helper_; @@ -1733,6 +1737,23 @@ } TEST_F(RenderWidgetHostViewAuraTest, TimerBasedWheelEventPhaseInfo) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature(features::kPercentBasedScrolling); + RunTimerBasedWheelEventPhaseInfoTest(false); +} + +TEST_F(RenderWidgetHostViewAuraTest, + TimerBasedWheelEventPhaseInfoWithPercentBasedScrolling) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kPercentBasedScrolling); + RunTimerBasedWheelEventPhaseInfoTest(true); +} + +void RenderWidgetHostViewAuraTest::RunTimerBasedWheelEventPhaseInfoTest( + bool percent_based_scrolling_enabled) { + // TODO(clchambers): consolidate into one header along with other declarations + // of this constant + const float kScrollPercentPerLineOrChar = 0.05f; InitViewForFrame(nullptr); view_->Show(); sink_->ClearMessages(); @@ -1765,7 +1786,11 @@ EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate, gesture_event->GetType()); EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x); - EXPECT_EQ(5U, gesture_event->data.scroll_update.delta_y); + EXPECT_EQ( + percent_based_scrolling_enabled + ? 5 * kScrollPercentPerLineOrChar / ui::MouseWheelEvent::kWheelDelta + : 5U, + gesture_event->data.scroll_update.delta_y); events[1]->ToEvent()->CallCallback( blink::mojom::InputEventResultState::kConsumed);
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc index 093b4c8..781b7dd0 100644 --- a/content/browser/webauth/authenticator_common.cc +++ b/content/browser/webauth/authenticator_common.cc
@@ -28,7 +28,7 @@ #include "content/browser/webauth/authenticator_environment_impl.h" #include "content/browser/webauth/client_data_json.h" #include "content/browser/webauth/is_uvpaa.h" -#include "content/browser/webauth/virtual_authenticator_request_delegate.h" +#include "content/browser/webauth/virtual_authenticator_manager_impl.h" #include "content/browser/webauth/virtual_fido_discovery_factory.h" #include "content/browser/webauth/webauth_request_security_checker.h" #include "content/public/browser/browser_context.h" @@ -386,13 +386,23 @@ AuthenticatorCommon::MaybeCreateRequestDelegate() { RenderFrameHostImpl* const render_frame_host_impl = static_cast<RenderFrameHostImpl*>(GetRenderFrameHost()); - if (AuthenticatorEnvironmentImpl::GetInstance() - ->IsVirtualAuthenticatorEnabledFor( - render_frame_host_impl->frame_tree_node())) { - return std::make_unique<VirtualAuthenticatorRequestDelegate>(); + std::unique_ptr<AuthenticatorRequestClientDelegate> delegate = + GetContentClient()->browser()->GetWebAuthenticationRequestDelegate( + render_frame_host_impl); + if (!delegate) { + return nullptr; } - return GetContentClient()->browser()->GetWebAuthenticationRequestDelegate( - render_frame_host_impl); + VirtualAuthenticatorManagerImpl* virtual_authenticator_manager = + AuthenticatorEnvironmentImpl::GetInstance() + ->MaybeGetVirtualAuthenticatorManager( + render_frame_host_impl->frame_tree_node()); + if (virtual_authenticator_manager) { + delegate->SetVirtualEnvironment(true); + if (!virtual_authenticator_manager->is_ui_enabled()) { + delegate->DisableUI(); + } + } + return delegate; } void AuthenticatorCommon::StartMakeCredentialRequest(
diff --git a/content/browser/webauth/authenticator_environment_impl.cc b/content/browser/webauth/authenticator_environment_impl.cc index abef488..b07042e 100644 --- a/content/browser/webauth/authenticator_environment_impl.cc +++ b/content/browser/webauth/authenticator_environment_impl.cc
@@ -38,15 +38,19 @@ AuthenticatorEnvironmentImpl::~AuthenticatorEnvironmentImpl() = default; void AuthenticatorEnvironmentImpl::EnableVirtualAuthenticatorFor( - FrameTreeNode* node) { + FrameTreeNode* node, + bool enable_ui) { // Do not create a new virtual authenticator if there is one already defined // for the |node|. if (base::Contains(virtual_authenticator_managers_, node)) return; node->AddObserver(this); - virtual_authenticator_managers_[node] = + auto virtual_authenticator_manager = std::make_unique<VirtualAuthenticatorManagerImpl>(); + virtual_authenticator_manager->enable_ui(enable_ui); + virtual_authenticator_managers_[node] = + std::move(virtual_authenticator_manager); } void AuthenticatorEnvironmentImpl::DisableVirtualAuthenticatorFor(
diff --git a/content/browser/webauth/authenticator_environment_impl.h b/content/browser/webauth/authenticator_environment_impl.h index 4c6ae34..3eff8ea 100644 --- a/content/browser/webauth/authenticator_environment_impl.h +++ b/content/browser/webauth/authenticator_environment_impl.h
@@ -46,7 +46,7 @@ // descendants. // Does not have any effect if the |node| already has the virtual environment // enabled. - void EnableVirtualAuthenticatorFor(FrameTreeNode* node); + void EnableVirtualAuthenticatorFor(FrameTreeNode* node, bool enable_ui); // Disables the scoped virtual authenticator environment for this |node|, // resetting the state. If the environment is set on one of the |node|'s
diff --git a/content/browser/webauth/virtual_authenticator_manager_impl.h b/content/browser/webauth/virtual_authenticator_manager_impl.h index b2846ec4d..d446914 100644 --- a/content/browser/webauth/virtual_authenticator_manager_impl.h +++ b/content/browser/webauth/virtual_authenticator_manager_impl.h
@@ -54,6 +54,10 @@ VirtualAuthenticator* AddAuthenticatorAndReturnNonOwningPointer( const blink::test::mojom::VirtualAuthenticatorOptions& options); + // Sets whether the UI is enabled or not. Defaults to false. + void enable_ui(bool enable_ui) { enable_ui_ = enable_ui; } + bool is_ui_enabled() const { return enable_ui_; } + // Returns the authenticator with the given |id|. Returns nullptr if no // authenticator matches the ID. VirtualAuthenticator* GetAuthenticator(const std::string& id); @@ -83,6 +87,8 @@ base::ObserverList<Observer> observers_; + bool enable_ui_ = false; + // The key is the unique_id of the corresponding value (the authenticator). std::map<std::string, std::unique_ptr<VirtualAuthenticator>> authenticators_;
diff --git a/content/browser/webauth/virtual_authenticator_request_delegate.cc b/content/browser/webauth/virtual_authenticator_request_delegate.cc deleted file mode 100644 index 7fd64aad..0000000 --- a/content/browser/webauth/virtual_authenticator_request_delegate.cc +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/webauth/virtual_authenticator_request_delegate.h" - -#include <vector> - -#include "base/callback.h" -#include "device/fido/authenticator_get_assertion_response.h" - -namespace content { - -VirtualAuthenticatorRequestDelegate::VirtualAuthenticatorRequestDelegate() = - default; - -VirtualAuthenticatorRequestDelegate::~VirtualAuthenticatorRequestDelegate() = - default; - -void VirtualAuthenticatorRequestDelegate::SelectAccount( - std::vector<device::AuthenticatorGetAssertionResponse> responses, - base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)> - callback) { - // TODO(crbug.com/991666): Provide a way to determine which account gets - // picked. - std::move(callback).Run(std::move(responses[0])); -} - -} // namespace content
diff --git a/content/browser/webauth/virtual_authenticator_request_delegate.h b/content/browser/webauth/virtual_authenticator_request_delegate.h deleted file mode 100644 index 8043d4c..0000000 --- a/content/browser/webauth/virtual_authenticator_request_delegate.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_WEBAUTH_VIRTUAL_AUTHENTICATOR_REQUEST_DELEGATE_H_ -#define CONTENT_BROWSER_WEBAUTH_VIRTUAL_AUTHENTICATOR_REQUEST_DELEGATE_H_ - -#include <vector> - -#include "base/callback_forward.h" -#include "content/public/browser/authenticator_request_client_delegate.h" -#include "device/fido/authenticator_get_assertion_response.h" - -namespace content { - -// An implementation of AuthenticatorRequestClientDelegate that allows -// automating webauthn requests through a virtual environment. -class VirtualAuthenticatorRequestDelegate - : public AuthenticatorRequestClientDelegate { - public: - // The |frame_tree_node| must outlive this instance. - VirtualAuthenticatorRequestDelegate(); - - VirtualAuthenticatorRequestDelegate( - const VirtualAuthenticatorRequestDelegate&) = delete; - VirtualAuthenticatorRequestDelegate& operator=( - const VirtualAuthenticatorRequestDelegate&) = delete; - - ~VirtualAuthenticatorRequestDelegate() override; - - // AuthenticatorRequestClientDelegate: - void SelectAccount( - std::vector<device::AuthenticatorGetAssertionResponse> responses, - base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)> - callback) override; -}; - -} // namespace content - -#endif // CONTENT_BROWSER_WEBAUTH_VIRTUAL_AUTHENTICATOR_REQUEST_DELEGATE_H_
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java index fc481f1..0b4e2e6 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
@@ -39,6 +39,8 @@ import org.chromium.base.annotations.NativeMethods; import org.chromium.base.compat.ApiHelperForM; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.content.R; import org.chromium.content.browser.ContentApiHelperForM; import org.chromium.content.browser.ContentClassFactory; @@ -139,6 +141,10 @@ private View mView; private ActionMode mActionMode; + // Supplier of whether action bar is showing now. + private final ObservableSupplierImpl<Boolean> mIsActionBarShowingSupplier = + new ObservableSupplierImpl<>(); + // Bit field for mappings from menu item to a flag indicating it is allowed. private int mAllowedMenuItems; @@ -488,7 +494,7 @@ // This is to work around an LGE email issue. See crbug.com/651706 for more details. LGEmailActionModeWorkaroundImpl.runIfNecessary(mContext, actionMode); } - mActionMode = actionMode; + setActionMode(actionMode); mUnselectAllOnDismiss = true; if (!isActionModeValid()) clearSelection(); @@ -612,7 +618,7 @@ mActionMode.finish(); // Should be nulled out in case #onDestroyActionMode() is not invoked in response. - mActionMode = null; + setActionMode(null); } } @@ -974,7 +980,7 @@ @Override public void onDestroyActionMode() { - mActionMode = null; + setActionMode(null); if (mUnselectAllOnDismiss) { clearSelection(); } @@ -1553,6 +1559,11 @@ return mLastSelectedText; } + private void setActionMode(ActionMode actionMode) { + mActionMode = actionMode; + mIsActionBarShowingSupplier.set(isSelectActionBarShowing()); + } + private boolean isShareAvailable() { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); @@ -1617,6 +1628,11 @@ } @Override + public ObservableSupplier<Boolean> isSelectActionBarShowingSupplier() { + return mIsActionBarShowingSupplier; + } + + @Override public ActionModeCallbackHelper getActionModeCallbackHelper() { return this; }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SelectionPopupController.java b/content/public/android/java/src/org/chromium/content_public/browser/SelectionPopupController.java index d5861a5f..5063c71 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/SelectionPopupController.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/SelectionPopupController.java
@@ -8,6 +8,7 @@ import android.view.ActionMode; import android.view.textclassifier.TextClassifier; +import org.chromium.base.supplier.ObservableSupplier; import org.chromium.content.browser.selection.SelectionPopupControllerImpl; import org.chromium.ui.base.WindowAndroid; @@ -88,6 +89,12 @@ boolean isSelectActionBarShowing(); /** + * @return An {@link ObservableSupplier<Boolean>} which holds true when a selection action bar + * is showing; otherwise, it holds false. + */ + ObservableSupplier<Boolean> isSelectActionBarShowingSupplier(); + + /** * @return {@link ActionModeCallbackHelper} object. */ ActionModeCallbackHelper getActionModeCallbackHelper();
diff --git a/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java b/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java index f26b6a0b..4fbb8c96 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java
@@ -605,6 +605,7 @@ // showActionModeOrClearOnFailure(). Mockito.verify(spyController, times(1)).finishActionMode(); assertTrue(spyController.isSelectActionBarShowing()); + assertTrue(spyController.isSelectActionBarShowingSupplier().get()); // Clear the selected text. spyController.onSelectionChanged(""); @@ -618,6 +619,7 @@ spyController.onSelectionEvent(SelectionEventType.SELECTION_HANDLES_CLEARED, 0, 0, 1, 1); assertFalse(spyController.isSelectActionBarShowing()); + assertFalse(spyController.isSelectActionBarShowingSupplier().get()); Mockito.verify(spyController, times(3)).finishActionMode(); } @@ -642,6 +644,7 @@ // showActionModeOrClearOnFailure(). Mockito.verify(spyController, times(1)).finishActionMode(); assertTrue(spyController.isSelectActionBarShowing()); + assertTrue(spyController.isSelectActionBarShowingSupplier().get()); // Setting the window to null should clear selections and reset the state. spyController.onWindowAndroidChanged(null); @@ -655,6 +658,7 @@ spyController.onSelectionEvent(SelectionEventType.SELECTION_HANDLES_CLEARED, 0, 0, 1, 1); assertFalse(spyController.isSelectActionBarShowing()); + assertFalse(spyController.isSelectActionBarShowingSupplier().get()); Mockito.verify(spyController, times(3)).finishActionMode(); }
diff --git a/content/public/browser/authenticator_request_client_delegate.cc b/content/public/browser/authenticator_request_client_delegate.cc index eaea2f5..0c205b7 100644 --- a/content/public/browser/authenticator_request_client_delegate.cc +++ b/content/public/browser/authenticator_request_client_delegate.cc
@@ -164,8 +164,12 @@ std::vector<device::AuthenticatorGetAssertionResponse> responses, base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)> callback) { - // SupportsResidentKeys returned false so this should never be called. - NOTREACHED(); + // Automatically choose the first account to allow resident keys for virtual + // authenticators without a browser implementation, e.g. on content shell. + // TODO(crbug.com/991666): Provide a way to determine which account gets + // picked. + DCHECK(virtual_environment_); + std::move(callback).Run(std::move(responses.at(0))); } void AuthenticatorRequestClientDelegate::DisableUI() {} @@ -174,6 +178,15 @@ return false; } +void AuthenticatorRequestClientDelegate::SetVirtualEnvironment( + bool virtual_environment) { + virtual_environment_ = virtual_environment; +} + +bool AuthenticatorRequestClientDelegate::IsVirtualEnvironmentEnabled() { + return virtual_environment_; +} + void AuthenticatorRequestClientDelegate::SetConditionalRequest( bool is_conditional) {}
diff --git a/content/public/browser/authenticator_request_client_delegate.h b/content/public/browser/authenticator_request_client_delegate.h index 87640cc4..872d6c8 100644 --- a/content/public/browser/authenticator_request_client_delegate.h +++ b/content/public/browser/authenticator_request_client_delegate.h
@@ -297,6 +297,13 @@ virtual bool IsWebAuthnUIEnabled(); + // Configures whether a virtual authenticator environment is enabled. The + // embedder might choose to e.g. automate account selection under a virtual + // environment. + void SetVirtualEnvironment(bool virtual_environment); + + bool IsVirtualEnvironmentEnabled(); + // Set to true to enable a mode where a prominent UI is only show for // discoverable platform credentials. virtual void SetConditionalRequest(bool is_conditional); @@ -327,6 +334,9 @@ void OnSampleCollected(int bio_samples_remaining) override; void FinishCollectToken() override; void OnRetryUserVerification(int attempts) override; + + private: + bool virtual_environment_ = false; }; } // namespace content
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index fabe75b..bb2cb82 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -253,6 +253,13 @@ return 0; } +blink::ParsedPermissionsPolicy +ContentBrowserClient::GetPermissionsPolicyForIsolatedApp( + content::BrowserContext* browser_context, + const url::Origin& app_origin) { + return blink::ParsedPermissionsPolicy(); +} + bool ContentBrowserClient::ShouldTryToUseExistingProcessHost( BrowserContext* browser_context, const GURL& url) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 7e22f3e..54550f4c 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -56,6 +56,7 @@ #include "services/network/public/mojom/websocket.mojom-forward.h" #include "storage/browser/file_system/file_system_context.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/permissions_policy/permissions_policy.h" #include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/public/mojom/browsing_topics/browsing_topics.mojom-forward.h" #include "third_party/blink/public/mojom/manifest/manifest.mojom-forward.h" @@ -538,6 +539,12 @@ // Must be less than or equal to the total number of RenderProcessHosts. virtual size_t GetProcessCountToIgnoreForLimit(); + // Returns the base permissions policy that is declared in an isolated app's + // Web App Manifest. + virtual blink::ParsedPermissionsPolicy GetPermissionsPolicyForIsolatedApp( + content::BrowserContext* browser_context, + const url::Origin& app_origin); + // Returns whether a new process should be created or an existing one should // be reused based on the URL we want to load. This should return false, // unless there is a good reason otherwise.
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java index 0bc1cd3..cfaf646 100644 --- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java +++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java
@@ -8,6 +8,8 @@ import android.view.ActionMode; import android.view.textclassifier.TextClassifier; +import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.content_public.browser.ActionModeCallbackHelper; import org.chromium.content_public.browser.SelectionClient; import org.chromium.content_public.browser.SelectionPopupController; @@ -54,6 +56,11 @@ } @Override + public ObservableSupplier<Boolean> isSelectActionBarShowingSupplier() { + return new ObservableSupplierImpl<>(); + } + + @Override public ActionModeCallbackHelper getActionModeCallbackHelper() { return null; }
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index dcbd04f..2bbdca40 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -317,11 +317,7 @@ RenderFrameImpl* render_frame, media::RequestRoutingTokenCallback request_routing_token_cb) : render_frame_(render_frame), - request_routing_token_cb_(std::move(request_routing_token_cb)) { - // Requesting a support check will ensure that the supplemental profiles - // cache is populated prior to anything that needs it on the media thread. - media::IsSupportedVideoType({}); -} + request_routing_token_cb_(std::move(request_routing_token_cb)) {} MediaFactory::~MediaFactory() { // Release the DecoderFactory to the media thread since it may still be in use
diff --git a/content/renderer/media/render_media_client.cc b/content/renderer/media/render_media_client.cc index 87adab2..a0b9262 100644 --- a/content/renderer/media/render_media_client.cc +++ b/content/renderer/media/render_media_client.cc
@@ -14,6 +14,34 @@ #include "media/base/video_color_space.h" #include "ui/display/display_switches.h" +namespace { + +// At present, HEVC is the only codec which has optional platform support. +// Some clients need this knowledge synchronously, so we try to populate +// it asynchronously ahead of time, but can fallback to a blocking call +// when it's needed synchronously. +#if BUILDFLAG(ENABLE_PLATFORM_HEVC) && \ + (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) +#define NEEDS_PROFILE_UPDATER 1 +#else +#define NEEDS_PROFILE_UPDATER 0 +#endif + +#if NEEDS_PROFILE_UPDATER +void UpdateVideoProfilesInternal(const gpu::GPUInfo& info) { + const auto gpu_profiles = info.video_decode_accelerator_supported_profiles; + base::flat_set<media::VideoCodecProfile> media_profiles; + media_profiles.reserve(gpu_profiles.size()); + for (const auto& profile : gpu_profiles) { + media_profiles.insert( + static_cast<media::VideoCodecProfile>(profile.profile)); + } + media::UpdateDefaultSupportedVideoProfiles(media_profiles); +} +#endif + +} // namespace + namespace content { void RenderMediaClient::Initialize() { @@ -21,11 +49,17 @@ media::SetMediaClient(client); } -RenderMediaClient::RenderMediaClient() {} +RenderMediaClient::RenderMediaClient() { +#if NEEDS_PROFILE_UPDATER + // Unretained is safe here since the MediaClient is never destructed. + RenderThreadImpl::current()->EstablishGpuChannel(base::BindOnce( + &RenderMediaClient::OnEstablishedGpuChannel, base::Unretained(this))); -RenderMediaClient::~RenderMediaClient() { +#endif } +RenderMediaClient::~RenderMediaClient() = default; + void RenderMediaClient::GetSupportedKeySystems( media::GetSupportedKeySystemsCB cb) { GetContentClient()->renderer()->GetSupportedKeySystems(std::move(cb)); @@ -36,27 +70,21 @@ } bool RenderMediaClient::IsSupportedVideoType(const media::VideoType& type) { -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) - // If we're not on the render thread (ie, from the media thread), then don't - // even bother trying to populate the cache. - if (auto* render_thread = RenderThreadImpl::current()) { - static const bool kHasGpuProfiles = [render_thread]() { - if (auto gpu_host = render_thread->EstablishGpuChannelSync()) { - const auto gpu_profiles = - gpu_host->gpu_info().video_decode_accelerator_supported_profiles; - base::flat_set<media::VideoCodecProfile> media_profiles; - for (const auto& profile : gpu_profiles) { - media_profiles.insert( - static_cast<media::VideoCodecProfile>(profile.profile)); - } - media::UpdateDefaultSupportedVideoProfiles(media_profiles); - return true; - } - return false; - }(); - std::ignore = kHasGpuProfiles; +#if NEEDS_PROFILE_UPDATER + if (!did_update_.IsSignaled()) { + // The asynchronous request didn't complete in time, so we must now block + // until until the information from the GPU channel is available. + if (auto* render_thread = content::RenderThreadImpl::current()) { + if (auto gpu_host = render_thread->EstablishGpuChannelSync()) + UpdateVideoProfilesInternal(gpu_host->gpu_info()); + did_update_.Signal(); + } else { + // There's already an asynchronous request on the main thread, so wait... + did_update_.Wait(); + } } #endif + return GetContentClient()->renderer()->IsSupportedVideoType(type); } @@ -72,4 +100,15 @@ audio_parameters); } +void RenderMediaClient::OnEstablishedGpuChannel( + scoped_refptr<gpu::GpuChannelHost> host) { +#if NEEDS_PROFILE_UPDATER + if (host && !did_update_.IsSignaled()) + UpdateVideoProfilesInternal(host->gpu_info()); + + // Signal even if host is nullptr, since that's the same has having no GPU. + did_update_.Signal(); +#endif +} + } // namespace content
diff --git a/content/renderer/media/render_media_client.h b/content/renderer/media/render_media_client.h index 189f7344..93e8d338 100644 --- a/content/renderer/media/render_media_client.h +++ b/content/renderer/media/render_media_client.h
@@ -5,9 +5,14 @@ #ifndef CONTENT_RENDERER_MEDIA_RENDER_MEDIA_CLIENT_H_ #define CONTENT_RENDERER_MEDIA_RENDER_MEDIA_CLIENT_H_ +#include "base/synchronization/waitable_event.h" #include "media/base/audio_parameters.h" #include "media/base/media_client.h" +namespace gpu { +class GpuChannelHost; +} + namespace content { // RenderMediaClient is purely plumbing to make content embedder customizations @@ -33,6 +38,13 @@ private: RenderMediaClient(); ~RenderMediaClient() override; + + void OnEstablishedGpuChannel(scoped_refptr<gpu::GpuChannelHost> host); + + // Used to indicate if optional video profile support information has been + // retrieved from the GPU channel. May be waited upon by any thread but the + // RenderThread since it's always signaled from the RenderThread. + base::WaitableEvent did_update_; }; } // namespace content
diff --git a/content/test/fuzzer/renderer_tree_fuzzer.cc b/content/test/fuzzer/renderer_tree_fuzzer.cc index b85501110..33d5c5b 100644 --- a/content/test/fuzzer/renderer_tree_fuzzer.cc +++ b/content/test/fuzzer/renderer_tree_fuzzer.cc
@@ -125,7 +125,7 @@ std::unique_ptr<base::Value> ToJson() const { std::unique_ptr<base::ListValue> result(new base::ListValue()); for (const auto& node : *this) { - result->Append(node->ToJson()); + result->GetList().Append(base::Value::FromUniquePtrValue(node->ToJson())); } return std::move(result); }
diff --git a/device/fido/fido_request_handler_base.cc b/device/fido/fido_request_handler_base.cc index a9489ae0..9641d49f 100644 --- a/device/fido/fido_request_handler_base.cc +++ b/device/fido/fido_request_handler_base.cc
@@ -396,11 +396,12 @@ void FidoRequestHandlerBase::OnHavePlatformCredentialStatus( std::vector<DiscoverableCredentialMetadata> creds, bool have_credential) { - DCHECK(!transport_availability_info_ - .has_recognized_platform_authenticator_credential.has_value()); + DCHECK_EQ(transport_availability_info_.has_platform_authenticator_credential, + RecognizedCredential::kUnknown); - transport_availability_info_ - .has_recognized_platform_authenticator_credential = have_credential; + transport_availability_info_.has_platform_authenticator_credential = + have_credential ? RecognizedCredential::kHasRecognizedCredential + : RecognizedCredential::kNoRecognizedCredential; transport_availability_info_.recognized_platform_authenticator_credentials = std::move(creds);
diff --git a/device/fido/fido_request_handler_base.h b/device/fido/fido_request_handler_base.h index b1d1266..9e52164 100644 --- a/device/fido/fido_request_handler_base.h +++ b/device/fido/fido_request_handler_base.h
@@ -48,6 +48,12 @@ using AuthenticatorMap = std::map<std::string, FidoAuthenticator*, std::less<>>; + enum class RecognizedCredential { + kUnknown, + kHasRecognizedCredential, + kNoRecognizedCredential + }; + // Encapsulates data required to initiate WebAuthN UX dialog. Once all // components of TransportAvailabilityInfo is set, // AuthenticatorRequestClientDelegate should be notified. @@ -69,15 +75,14 @@ base::flat_set<FidoTransportProtocol> available_transports; // Whether the platform authenticator has a matching credential for the - // request. This is only set for a GetAssertion request and if a platform - // authenticator has been added to the request handler. (The Windows - // WebAuthn API does NOT count as a platform authenticator in this case.) - absl::optional<bool> has_recognized_platform_authenticator_credential; + // request. This is only set for a GetAssertion request. + RecognizedCredential has_platform_authenticator_credential = + RecognizedCredential::kUnknown; // The set of recognized platform credential user entities that can fulfill // a GetAssertion request. Not all platform authenticators report this, so // the set might be empty even if - // |has_recognized_platform_authenticator_credential| is true. + // |has_platform_authenticator_credential| is |kHasRecognizedCredential|. std::vector<DiscoverableCredentialMetadata> recognized_platform_authenticator_credentials;
diff --git a/device/fido/fido_request_handler_unittest.cc b/device/fido/fido_request_handler_unittest.cc index 32137e39..661d9fb 100644 --- a/device/fido/fido_request_handler_unittest.cc +++ b/device/fido/fido_request_handler_unittest.cc
@@ -87,12 +87,14 @@ void WaitForAndExpectAvailableTransportsAre( base::flat_set<FidoTransportProtocol> expected_transports, - absl::optional<bool> has_platform_credential = absl::nullopt) { + FidoRequestHandlerBase::RecognizedCredential + has_platform_authenticator_credential = + FidoRequestHandlerBase::RecognizedCredential::kUnknown) { auto result = WaitForTransportAvailabilityInfo(); EXPECT_THAT(result.available_transports, ::testing::UnorderedElementsAreArray(expected_transports)); - EXPECT_EQ(result.has_recognized_platform_authenticator_credential, - has_platform_credential); + EXPECT_EQ(result.has_platform_authenticator_credential, + has_platform_authenticator_credential); } protected: @@ -203,7 +205,8 @@ } ~FakeFidoRequestHandler() override = default; - void set_has_platform_credential(bool has_platform_credential) { + void set_has_platform_credential( + RecognizedCredential has_platform_credential) { has_platform_credential_ = has_platform_credential; } @@ -227,8 +230,7 @@ FidoAuthenticator* authenticator) override { if (authenticator->AuthenticatorTransport() == FidoTransportProtocol::kInternal) { - transport_availability_info() - .has_recognized_platform_authenticator_credential = + transport_availability_info().has_platform_authenticator_credential = has_platform_credential_; } @@ -260,7 +262,8 @@ } CompletionCallback completion_callback_; - bool has_platform_credential_ = false; + RecognizedCredential has_platform_credential_ = + RecognizedCredential::kNoRecognizedCredential; base::WeakPtrFactory<FakeFidoRequestHandler> weak_factory_{this}; }; @@ -583,13 +586,14 @@ &fake_discovery_factory_, base::flat_set<FidoTransportProtocol>({FidoTransportProtocol::kInternal}), callback().callback()); - request_handler->set_has_platform_credential(true); + request_handler->set_has_platform_credential( + FidoRequestHandlerBase::RecognizedCredential::kHasRecognizedCredential); request_handler->set_observer(&observer); fake_discovery->AddDevice(std::move(device)); observer.WaitForAndExpectAvailableTransportsAre( {FidoTransportProtocol::kInternal}, - /*has_platform_credential=*/true); + FidoRequestHandlerBase::RecognizedCredential::kHasRecognizedCredential); callback().WaitForCallback(); EXPECT_TRUE(callback().status());
diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc index 59b1738..d002df3 100644 --- a/device/fido/get_assertion_request_handler.cc +++ b/device/fido/get_assertion_request_handler.cc
@@ -419,13 +419,15 @@ FidoAuthenticator* platform_authenticator) { DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); -#if BUILDFLAG(IS_MAC) - // In tests the platform authenticator may be a virtual device. - if (platform_authenticator->GetType() != FidoAuthenticator::Type::kTouchID) { - FidoRequestHandlerBase::GetPlatformCredentialStatus(platform_authenticator); + // The platform authenticator may be a virtual device. + if (platform_authenticator->GetType() == FidoAuthenticator::Type::kOther) { + // TODO(nsatragno): query the virtual authenticator for credential status. + OnHavePlatformCredentialStatus(/*user_entities=*/{}, + /*have_credential=*/false); return; } +#if BUILDFLAG(IS_MAC) fido::mac::TouchIdAuthenticator* touch_id_authenticator = static_cast<fido::mac::TouchIdAuthenticator*>(platform_authenticator); bool has_credential =
diff --git a/docs/README.md b/docs/README.md index 4eee5a2a..3553aa3 100644 --- a/docs/README.md +++ b/docs/README.md
@@ -406,7 +406,7 @@ ### Speed * [Chrome Speed](speed/README.md) - Documentation for performance measurements and regressions in Chrome. -* [Chrome Speed Metrics](speed_metrics/README.md) - Documentation about user experience metrics in the web and their JavaScript APIs. +* [Chrome Speed Metrics](speed_metrics/README.md) - Documentation about user experience metrics on the web and their JavaScript APIs. ### Probably Obsolete * [TPM Quick Reference](tpm_quick_ref.md) - Trusted Platform Module notes.
diff --git a/docs/process/release_cycle.md b/docs/process/release_cycle.md index d15623b..ca84d8d 100644 --- a/docs/process/release_cycle.md +++ b/docs/process/release_cycle.md
@@ -95,6 +95,11 @@ release generally reaches all users within one to two weeks unless major issues arise that cannot be addressed quickly. +To get better statistical data for staged rollouts, each rollout will consist of +two separate builds which are identical, except for the build number. There is no +harm in being on the lower build number, and all users are expected to be +automatically updated to the higher build number as part of the rollout process. + ### Stable Refresh The stable and extended stable channels are refreshed every two weeks. These
diff --git a/docs/windows_build_instructions.md b/docs/windows_build_instructions.md index 80d1de0..32532aa0 100644 --- a/docs/windows_build_instructions.md +++ b/docs/windows_build_instructions.md
@@ -52,9 +52,8 @@ ``` -You must have the version 10.0.20348.0 [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/) -installed. This -can be installed separately or by checking the appropriate box in the Visual -Studio Installer. +installed. This can be installed separately or by checking the appropriate box +in the Visual Studio Installer. The SDK Debugging Tools must also be installed. If the Windows 10 SDK was installed via the Visual Studio installer, then they can be installed by going
diff --git a/extensions/common/manifest_handlers/csp_info.cc b/extensions/common/manifest_handlers/csp_info.cc index b866206f..64bcbdb 100644 --- a/extensions/common/manifest_handlers/csp_info.cc +++ b/extensions/common/manifest_handlers/csp_info.cc
@@ -38,8 +38,11 @@ "sandbox allow-scripts allow-forms allow-popups allow-modals; " "script-src 'self' 'unsafe-inline' 'unsafe-eval'; child-src 'self';"; -// The default CSP to be used in order to prevent remote scripts. -static const char kDefaultMV3CSP[] = +// The default CSP to be used if no CSP provided. +static const char kDefaultMV3CSP[] = "script-src 'self'; object-src 'self';"; + +// The minimum CSP to be used in order to prevent remote scripts. +static const char kMinimumMV3CSP[] = "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"; #define PLATFORM_APP_LOCAL_CSP_SOURCES "'self' blob: filesystem: data:" @@ -120,7 +123,7 @@ } // static -const std::string* CSPInfo::GetDefaultCSPToAppend( +const std::string* CSPInfo::GetMinimumCSPToAppend( const Extension& extension, const std::string& relative_path) { if (!extension.is_extension()) @@ -135,11 +138,12 @@ if (extension.manifest_version() <= 2) return &GetExtensionPagesCSP(&extension); - // For manifest V3 extensions, append the default secure CSP. This + // For manifest V3 extensions, append the minimum secure CSP. This // additionally helps protect against bugs in our CSP parsing code which may // cause the parsed CSP to not be as strong as the default one. For example, // see crbug.com/1042963. - static const base::NoDestructor<std::string> default_csp(kDefaultMV3CSP); + + static const base::NoDestructor<std::string> default_csp(kMinimumMV3CSP); return default_csp.get(); } @@ -149,7 +153,7 @@ // The isolated world will use its own CSP which blocks remotely hosted // code. static const base::NoDestructor<std::string> default_isolated_world_csp( - kDefaultMV3CSP); + kMinimumMV3CSP); return default_isolated_world_csp.get(); }
diff --git a/extensions/common/manifest_handlers/csp_info.h b/extensions/common/manifest_handlers/csp_info.h index e3d7e7f7..1733fcc 100644 --- a/extensions/common/manifest_handlers/csp_info.h +++ b/extensions/common/manifest_handlers/csp_info.h
@@ -36,9 +36,9 @@ // shouldn't be returned for those cases. static const std::string& GetExtensionPagesCSP(const Extension* extension); - // Returns the default CSP (if any) to append for the `extension`'s resource + // Returns the minimum CSP (if any) to append for the `extension`'s resource // at the given `relative_path`. - static const std::string* GetDefaultCSPToAppend( + static const std::string* GetMinimumCSPToAppend( const Extension& extension, const std::string& relative_path);
diff --git a/extensions/common/manifest_handlers/csp_info_unittest.cc b/extensions/common/manifest_handlers/csp_info_unittest.cc index bbe74ed..0084691 100644 --- a/extensions/common/manifest_handlers/csp_info_unittest.cc +++ b/extensions/common/manifest_handlers/csp_info_unittest.cc
@@ -30,9 +30,9 @@ const char kDefaultExtensionPagesCSP[] = "script-src 'self' blob: filesystem:; " "object-src 'self' blob: filesystem:;"; -const char kDefaultSecureCSP[] = +const char kDefaultSecureCSP[] = "script-src 'self'; object-src 'self';"; +const char kMinimumMV3CSP[] = "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"; - } // namespace using CSPInfoUnitTest = ManifestTest; @@ -167,14 +167,14 @@ struct { const char* file_name; const char* csp; - } cases[] = {{"csp_dictionary_with_wasm.json", - "worker-src 'self' 'wasm-unsafe-eval'; default-src 'self'"}, - {"csp_dictionary_with_unsafe_wasm.json", - "worker-src 'self' 'wasm-unsafe-eval'; default-src 'self'"}, - {"csp_dictionary_empty_v3.json", - "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"}, - {"csp_dictionary_valid_1.json", "default-src 'none'"}, - {"csp_omitted_mv2.json", kDefaultExtensionPagesCSP}}; + } cases[] = { + {"csp_dictionary_with_wasm.json", + "worker-src 'self' 'wasm-unsafe-eval'; default-src 'self'"}, + {"csp_dictionary_with_unsafe_wasm.json", + "worker-src 'self' 'wasm-unsafe-eval'; default-src 'self'"}, + {"csp_dictionary_empty_v3.json", "script-src 'self'; object-src 'self';"}, + {"csp_dictionary_valid_1.json", "default-src 'none'"}, + {"csp_omitted_mv2.json", kDefaultExtensionPagesCSP}}; for (const auto& test_case : cases) { SCOPED_TRACE(base::StringPrintf("Testing %s.", test_case.file_name)); @@ -245,7 +245,7 @@ const std::string* isolated_world_csp = CSPInfo::GetIsolatedWorldCSP(*extension); ASSERT_TRUE(isolated_world_csp); - EXPECT_EQ(kDefaultSecureCSP, *isolated_world_csp); + EXPECT_EQ(kMinimumMV3CSP, *isolated_world_csp); EXPECT_EQ(kDefaultSandboxedPageCSP, CSPInfo::GetSandboxContentSecurityPolicy(extension.get()));
diff --git a/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Builder/properties.json b/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Builder/properties.json index 5ff6274..7801ada4 100644 --- a/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Builder/properties.json +++ b/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Builder/properties.json
@@ -1,4 +1,122 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "run_tests_serially": true + } + }, + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (Intel HD 630)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "parent": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "run_tests_serially": true + } + }, + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (NVIDIA)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "parent": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "run_tests_serially": true + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + } + ], + "builder_ids_in_scope_for_testing": [ + { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (Intel HD 630)", + "project": "chromium" + }, + { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (NVIDIA)", + "project": "chromium" + } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "dawn-win10-x86-deps-rel", + "group": "tryserver.chromium.dawn" + } + ] + } + }, "$build/reclient": { "instance": "rbe-chromium-trusted", "jobs": 80,
diff --git "a/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Release \050Intel HD 630\051/properties.json" "b/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Release \050Intel HD 630\051/properties.json" index 19bd319..e76a377 100644 --- "a/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Release \050Intel HD 630\051/properties.json" +++ "b/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Release \050Intel HD 630\051/properties.json"
@@ -1,4 +1,80 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "run_tests_serially": true + } + }, + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (Intel HD 630)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "parent": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "run_tests_serially": true + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (Intel HD 630)", + "project": "chromium" + } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "dawn-win10-x86-deps-rel", + "group": "tryserver.chromium.dawn" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Release \050NVIDIA\051/properties.json" "b/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Release \050NVIDIA\051/properties.json" index 19bd319..2dc667e 100644 --- "a/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Release \050NVIDIA\051/properties.json" +++ "b/infra/config/generated/builders/ci/Dawn Win10 x86 DEPS Release \050NVIDIA\051/properties.json"
@@ -1,4 +1,80 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "run_tests_serially": true + } + }, + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (NVIDIA)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "parent": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "run_tests_serially": true + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (NVIDIA)", + "project": "chromium" + } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "dawn-win10-x86-deps-rel", + "group": "tryserver.chromium.dawn" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/VR Linux/properties.json b/infra/config/generated/builders/ci/VR Linux/properties.json index 342b501..0fa52b9 100644 --- a/infra/config/generated/builders/ci/VR Linux/properties.json +++ b/infra/config/generated/builders/ci/VR Linux/properties.json
@@ -1,4 +1,54 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "VR Linux", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-fyi-archive", + "builder_group": "chromium.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "enable_reclient" + ], + "config": "chromium" + }, + "legacy_test_results_config": { + "config": "staging_server" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "VR Linux", + "project": "chromium" + } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "linux_vr", + "group": "tryserver.chromium.linux" + } + ] + } + }, "$build/reclient": { "instance": "rbe-chromium-trusted", "jobs": 500,
diff --git a/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/properties.json b/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/properties.json index 20179b4..6925f02 100644 --- a/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/properties.json +++ b/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/properties.json
@@ -1,4 +1,56 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "chromeos-arm-generic-dbg", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-chromiumos-archive", + "builder_group": "chromium.chromiumos", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Debug", + "config": "chromium", + "target_arch": "arm", + "target_bits": 32, + "target_cros_boards": [ + "arm-generic" + ], + "target_platform": "chromeos" + }, + "legacy_gclient_config": { + "apply_configs": [ + "chromeos" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "chromeos-arm-generic-dbg", + "project": "chromium" + } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "chromeos-arm-generic-dbg", + "group": "tryserver.chromium.chromiumos" + } + ] + } + }, "$build/reclient": { "instance": "rbe-chromium-trusted", "jobs": 500,
diff --git a/infra/config/generated/builders/ci/linux-bfcache-rel/properties.json b/infra/config/generated/builders/ci/linux-bfcache-rel/properties.json index 8d13aab7..0c8bd65c 100644 --- a/infra/config/generated/builders/ci/linux-bfcache-rel/properties.json +++ b/infra/config/generated/builders/ci/linux-bfcache-rel/properties.json
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "linux-bfcache-rel", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-linux-archive", + "builder_group": "chromium.linux", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "enable_reclient" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "linux-bfcache-rel", + "project": "chromium" + } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "linux-bfcache-rel", + "group": "tryserver.chromium.linux" + } + ] + } + }, "$build/reclient": { "instance": "rbe-chromium-trusted", "jobs": 250,
diff --git a/infra/config/generated/builders/ci/mac-archive-dbg/properties.json b/infra/config/generated/builders/ci/mac-archive-dbg/properties.json index fa75a041..079bf434 100644 --- a/infra/config/generated/builders/ci/mac-archive-dbg/properties.json +++ b/infra/config/generated/builders/ci/mac-archive-dbg/properties.json
@@ -1,4 +1,42 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "mac-archive-dbg", + "project": "chromium" + }, + "builder_spec": { + "builder_group": "chromium", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "clobber", + "mb" + ], + "build_config": "Debug", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "mac-archive-dbg", + "project": "chromium" + } + ] + } + }, "$build/goma": { "rpc_extra_params": "?prod", "server_host": "goma.chromium.org",
diff --git a/infra/config/generated/builders/ci/mac-archive-rel/properties.json b/infra/config/generated/builders/ci/mac-archive-rel/properties.json index 1adb5eb..12227eb 100644 --- a/infra/config/generated/builders/ci/mac-archive-rel/properties.json +++ b/infra/config/generated/builders/ci/mac-archive-rel/properties.json
@@ -7,6 +7,51 @@ "mac-archive-rel.json" ] }, + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "mac-archive-rel", + "project": "chromium" + }, + "builder_spec": { + "builder_group": "chromium", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "clobber", + "mb", + "goma_use_local" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "mac-archive-rel", + "project": "chromium" + } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "mac_chromium_archive_rel_ng", + "group": "tryserver.chromium.mac" + } + ] + } + }, "$build/goma": { "rpc_extra_params": "?prod", "server_host": "goma.chromium.org",
diff --git a/infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-canary/properties.json b/infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-canary/properties.json index 6f41cfd4..6a81908 100644 --- a/infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-canary/properties.json +++ b/infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-canary/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "goma", + "builder": "mac-archive-rel-goma-rbe-canary", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-fyi-archive", + "builder_group": "chromium.goma.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "clobber", + "mb", + "goma_use_local", + "goma_canary" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "goma", + "builder": "mac-archive-rel-goma-rbe-canary", + "project": "chromium" + } + ] + } + }, "$build/goma": { "jobs": 80, "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-latest/properties.json b/infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-latest/properties.json index 6f41cfd4..81643673 100644 --- a/infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-latest/properties.json +++ b/infra/config/generated/builders/goma/mac-archive-rel-goma-rbe-latest/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "goma", + "builder": "mac-archive-rel-goma-rbe-latest", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-fyi-archive", + "builder_group": "chromium.goma.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "clobber", + "mb", + "goma_use_local", + "goma_latest_client" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "goma", + "builder": "mac-archive-rel-goma-rbe-latest", + "project": "chromium" + } + ] + } + }, "$build/goma": { "jobs": 80, "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/chromeos-arm-generic-dbg/properties.json b/infra/config/generated/builders/try/chromeos-arm-generic-dbg/properties.json index 4aada5e..26e0dc45 100644 --- a/infra/config/generated/builders/try/chromeos-arm-generic-dbg/properties.json +++ b/infra/config/generated/builders/try/chromeos-arm-generic-dbg/properties.json
@@ -1,4 +1,50 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "chromeos-arm-generic-dbg", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-chromiumos-archive", + "builder_group": "chromium.chromiumos", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Debug", + "config": "chromium", + "target_arch": "arm", + "target_bits": 32, + "target_cros_boards": [ + "arm-generic" + ], + "target_platform": "chromeos" + }, + "legacy_gclient_config": { + "apply_configs": [ + "chromeos" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "chromeos-arm-generic-dbg", + "project": "chromium" + } + ] + } + }, "$build/goma": { "enable_ats": true, "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/dawn-win10-x86-deps-rel/properties.json b/infra/config/generated/builders/try/dawn-win10-x86-deps-rel/properties.json index d19a4586..27c2fd63 100644 --- a/infra/config/generated/builders/try/dawn-win10-x86-deps-rel/properties.json +++ b/infra/config/generated/builders/try/dawn-win10-x86-deps-rel/properties.json
@@ -1,4 +1,116 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "run_tests_serially": true + } + }, + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (Intel HD 630)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "parent": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "run_tests_serially": true + } + }, + { + "builder_id": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (NVIDIA)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-dawn-archive", + "builder_group": "chromium.dawn", + "execution_mode": "TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 32, + "target_platform": "win" + }, + "legacy_gclient_config": { + "config": "chromium" + }, + "parent": { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + }, + "run_tests_serially": true + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Builder", + "project": "chromium" + } + ], + "builder_ids_in_scope_for_testing": [ + { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (Intel HD 630)", + "project": "chromium" + }, + { + "bucket": "ci", + "builder": "Dawn Win10 x86 DEPS Release (NVIDIA)", + "project": "chromium" + } + ] + } + }, "$build/goma": { "enable_ats": false, "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/linux-bfcache-rel/properties.json b/infra/config/generated/builders/try/linux-bfcache-rel/properties.json index 19e0479..13b26f55 100644 --- a/infra/config/generated/builders/try/linux-bfcache-rel/properties.json +++ b/infra/config/generated/builders/try/linux-bfcache-rel/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "linux-bfcache-rel", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-linux-archive", + "builder_group": "chromium.linux", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "enable_reclient" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "linux-bfcache-rel", + "project": "chromium" + } + ] + } + }, "$build/goma": { "enable_ats": true, "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/linux_vr/properties.json b/infra/config/generated/builders/try/linux_vr/properties.json index 19e0479..f37f118 100644 --- a/infra/config/generated/builders/try/linux_vr/properties.json +++ b/infra/config/generated/builders/try/linux_vr/properties.json
@@ -1,4 +1,48 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "VR Linux", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-fyi-archive", + "builder_group": "chromium.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "enable_reclient" + ], + "config": "chromium" + }, + "legacy_test_results_config": { + "config": "staging_server" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "VR Linux", + "project": "chromium" + } + ] + } + }, "$build/goma": { "enable_ats": true, "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/mac_chromium_archive_rel_ng/properties.json b/infra/config/generated/builders/try/mac_chromium_archive_rel_ng/properties.json index 1112f12..25637ff3 100644 --- a/infra/config/generated/builders/try/mac_chromium_archive_rel_ng/properties.json +++ b/infra/config/generated/builders/try/mac_chromium_archive_rel_ng/properties.json
@@ -1,4 +1,43 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "mac-archive-rel", + "project": "chromium" + }, + "builder_spec": { + "builder_group": "chromium", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "clobber", + "mb", + "goma_use_local" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "mac-archive-rel", + "project": "chromium" + } + ] + } + }, "$build/goma": { "rpc_extra_params": "?prod", "server_host": "goma.chromium.org",
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index d66a4e8..f148b280 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1439,10 +1439,6 @@ includable_only: true } builders { - name: "chromium/try/linux-swangle-try-tot-angle-x64" - includable_only: true - } - builders { name: "chromium/try/linux-swangle-try-tot-swiftshader-x64" includable_only: true } @@ -1858,14 +1854,6 @@ includable_only: true } builders { - name: "chromium/try/win-swangle-try-tot-angle-x64" - includable_only: true - } - builders { - name: "chromium/try/win-swangle-try-tot-angle-x86" - includable_only: true - } - builders { name: "chromium/try/win-swangle-try-tot-swiftshader-x64" includable_only: true }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index a317d11..99f1286 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -35792,80 +35792,6 @@ } } builders { - name: "linux-swangle-tot-angle-x64" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/reclient": {' - ' "instance": "rbe-chromium-trusted",' - ' "jobs": 500,' - ' "metrics_project": "chromium-reclient-metrics"' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "chromium.swangle",' - ' "recipe": "angle_chromium",' - ' "sheriff_rotations": [' - ' "chromium.gpu"' - ' ]' - '}' - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "linux-swangle-tot-swiftshader-x64" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -40688,154 +40614,6 @@ } } builders { - name: "win-swangle-tot-angle-x64" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/reclient": {' - ' "instance": "rbe-chromium-trusted",' - ' "jobs": 80,' - ' "metrics_project": "chromium-reclient-metrics"' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "chromium.swangle",' - ' "recipe": "angle_chromium",' - ' "sheriff_rotations": [' - ' "chromium.gpu"' - ' ]' - '}' - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win-swangle-tot-angle-x86" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/reclient": {' - ' "instance": "rbe-chromium-trusted",' - ' "jobs": 80,' - ' "metrics_project": "chromium-reclient-metrics"' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "chromium.swangle",' - ' "recipe": "angle_chromium",' - ' "sheriff_rotations": [' - ' "chromium.gpu"' - ' ]' - '}' - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "win-swangle-tot-swiftshader-x64" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -67452,86 +67230,6 @@ } } builders { - name: "linux-swangle-try-tot-angle-x64" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.swangle.angle.linux.x64.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/goma": {' - ' "enable_ats": true,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "tryserver.chromium.swangle",' - ' "recipe": "angle_chromium_trybot"' - '}' - execution_timeout_secs: 7200 - expiration_secs: 7200 - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "linux-swangle-try-tot-swiftshader-x64" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -75007,166 +74705,6 @@ } } builders { - name: "win-swangle-try-tot-angle-x64" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.swangle.win.x64.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "tryserver.chromium.swangle",' - ' "recipe": "angle_chromium_trybot"' - '}' - execution_timeout_secs: 7200 - expiration_secs: 7200 - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win-swangle-try-tot-angle-x86" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.swangle.angle.win.x86.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/main" - cmd: "luciexe" - } - properties: - '{' - ' "$build/goma": {' - ' "enable_ats": false,' - ' "rpc_extra_params": "?prod",' - ' "server_host": "goma.chromium.org",' - ' "use_luci_auth": true' - ' },' - ' "$recipe_engine/resultdb/test_presentation": {' - ' "column_keys": [],' - ' "grouping_keys": [' - ' "status",' - ' "v.test_suite"' - ' ]' - ' },' - ' "builder_group": "tryserver.chromium.swangle",' - ' "recipe": "angle_chromium_trybot"' - '}' - execution_timeout_secs: 7200 - expiration_secs: 7200 - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://[^/]*blink_web_tests/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "win-swangle-try-tot-swiftshader-x64" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index d7d654d..110e610 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -11531,21 +11531,6 @@ short_name: "x64" } builders { - name: "buildbucket/luci.chromium.ci/win-swangle-tot-angle-x86" - category: "ToT ANGLE|Windows" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium.ci/win-swangle-tot-angle-x64" - category: "ToT ANGLE|Windows" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-swangle-tot-angle-x64" - category: "ToT ANGLE|Linux" - short_name: "x64" - } - builders { name: "buildbucket/luci.chromium.ci/win-swangle-tot-swiftshader-x86" category: "ToT SwiftShader|Windows" short_name: "x86" @@ -15173,9 +15158,6 @@ name: "buildbucket/luci.chromium.try/linux-swangle-chromium-try-x64" } builders { - name: "buildbucket/luci.chromium.try/linux-swangle-try-tot-angle-x64" - } - builders { name: "buildbucket/luci.chromium.try/linux-swangle-try-tot-swiftshader-x64" } builders { @@ -15431,12 +15413,6 @@ name: "buildbucket/luci.chromium.try/win-swangle-chromium-try-x86" } builders { - name: "buildbucket/luci.chromium.try/win-swangle-try-tot-angle-x64" - } - builders { - name: "buildbucket/luci.chromium.try/win-swangle-try-tot-angle-x86" - } - builders { name: "buildbucket/luci.chromium.try/win-swangle-try-tot-swiftshader-x64" } builders { @@ -16508,9 +16484,6 @@ name: "buildbucket/luci.chromium.try/linux-swangle-chromium-try-x64" } builders { - name: "buildbucket/luci.chromium.try/linux-swangle-try-tot-angle-x64" - } - builders { name: "buildbucket/luci.chromium.try/linux-swangle-try-tot-swiftshader-x64" } builders { @@ -16523,12 +16496,6 @@ name: "buildbucket/luci.chromium.try/win-swangle-chromium-try-x86" } builders { - name: "buildbucket/luci.chromium.try/win-swangle-try-tot-angle-x64" - } - builders { - name: "buildbucket/luci.chromium.try/win-swangle-try-tot-angle-x86" - } - builders { name: "buildbucket/luci.chromium.try/win-swangle-try-tot-swiftshader-x64" } builders {
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index f2795f4..40a2f405 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -5897,16 +5897,6 @@ } } job { - id: "linux-swangle-tot-angle-x64" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "ci" - builder: "linux-swangle-tot-angle-x64" - } -} -job { id: "linux-swangle-tot-swiftshader-x64" realm: "ci" acl_sets: "ci" @@ -6630,26 +6620,6 @@ } } job { - id: "win-swangle-tot-angle-x64" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "ci" - builder: "win-swangle-tot-angle-x64" - } -} -job { - id: "win-swangle-tot-angle-x86" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "ci" - builder: "win-swangle-tot-angle-x86" - } -} -job { id: "win-swangle-tot-swiftshader-x64" realm: "ci" acl_sets: "ci" @@ -7225,7 +7195,6 @@ triggers: "linux-rust-x64-dbg" triggers: "linux-rust-x64-rel" triggers: "linux-swangle-chromium-x64" - triggers: "linux-swangle-tot-angle-x64" triggers: "linux-swangle-tot-swiftshader-x64" triggers: "linux-swangle-x64" triggers: "linux-ubsan-vptr" @@ -7265,8 +7234,6 @@ triggers: "win-official" triggers: "win-pixel-builder-rel" triggers: "win-swangle-chromium-x86" - triggers: "win-swangle-tot-angle-x64" - triggers: "win-swangle-tot-angle-x86" triggers: "win-swangle-tot-swiftshader-x64" triggers: "win-swangle-tot-swiftshader-x86" triggers: "win-swangle-x64"
diff --git a/infra/config/generated/sheriff-rotations/chromium.gpu.txt b/infra/config/generated/sheriff-rotations/chromium.gpu.txt index 07007a6..d81cfb16 100644 --- a/infra/config/generated/sheriff-rotations/chromium.gpu.txt +++ b/infra/config/generated/sheriff-rotations/chromium.gpu.txt
@@ -68,13 +68,10 @@ ci/gpu-fyi-chromeos-octopus-exp ci/gpu-fyi-chromeos-zork-exp ci/linux-swangle-chromium-x64 -ci/linux-swangle-tot-angle-x64 ci/linux-swangle-tot-swiftshader-x64 ci/linux-swangle-x64 ci/mac-swangle-chromium-x64 ci/win-swangle-chromium-x86 -ci/win-swangle-tot-angle-x64 -ci/win-swangle-tot-angle-x86 ci/win-swangle-tot-swiftshader-x64 ci/win-swangle-tot-swiftshader-x86 ci/win-swangle-x64
diff --git a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star index 07533413..142018d 100644 --- a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star +++ b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
@@ -368,6 +368,28 @@ ci.builder( name = "chromeos-arm-generic-dbg", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "chromeos", + ], + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "mb", + ], + build_config = builder_config.build_config.DEBUG, + target_arch = builder_config.target_arch.ARM, + target_bits = 32, + target_cros_boards = [ + "arm-generic", + ], + target_platform = builder_config.target_platform.CHROMEOS, + ), + build_gs_bucket = "chromium-chromiumos-archive", + ), console_view_entry = consoles.console_view_entry( category = "simple|debug", short_name = "arm",
diff --git a/infra/config/subprojects/chromium/ci/chromium.dawn.star b/infra/config/subprojects/chromium/ci/chromium.dawn.star index 87d6340..3ceee624 100644 --- a/infra/config/subprojects/chromium/ci/chromium.dawn.star +++ b/infra/config/subprojects/chromium/ci/chromium.dawn.star
@@ -3,8 +3,9 @@ # found in the LICENSE file. """Definitions of builders in the chromium.dawn builder group.""" -load("//lib/builders.star", "goma") load("//lib/branches.star", "branches") +load("//lib/builder_config.star", "builder_config") +load("//lib/builders.star", "goma") load("//lib/ci.star", "ci", "rbe_instance", "rbe_jobs") load("//lib/consoles.star", "consoles") @@ -272,6 +273,22 @@ ci.gpu.windows_builder( name = "Dawn Win10 x86 DEPS Builder", branch_selector = branches.DESKTOP_EXTENDED_STABLE_MILESTONE, + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "mb", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 32, + target_platform = builder_config.target_platform.WIN, + ), + build_gs_bucket = "chromium-dawn-archive", + run_tests_serially = True, + ), console_view_entry = consoles.console_view_entry( category = "DEPS|Windows|Builder", short_name = "x86", @@ -287,6 +304,23 @@ ci.thin_tester( name = "Dawn Win10 x86 DEPS Release (Intel HD 630)", branch_selector = branches.DESKTOP_EXTENDED_STABLE_MILESTONE, + builder_spec = builder_config.builder_spec( + execution_mode = builder_config.execution_mode.TEST, + gclient_config = builder_config.gclient_config( + config = "chromium", + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "mb", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 32, + target_platform = builder_config.target_platform.WIN, + ), + build_gs_bucket = "chromium-dawn-archive", + run_tests_serially = True, + ), console_view_entry = consoles.console_view_entry( category = "DEPS|Windows|Intel", short_name = "x86", @@ -298,6 +332,23 @@ ci.thin_tester( name = "Dawn Win10 x86 DEPS Release (NVIDIA)", branch_selector = branches.DESKTOP_EXTENDED_STABLE_MILESTONE, + builder_spec = builder_config.builder_spec( + execution_mode = builder_config.execution_mode.TEST, + gclient_config = builder_config.gclient_config( + config = "chromium", + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "mb", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 32, + target_platform = builder_config.target_platform.WIN, + ), + build_gs_bucket = "chromium-dawn-archive", + run_tests_serially = True, + ), console_view_entry = consoles.console_view_entry( category = "DEPS|Windows|Nvidia", short_name = "x86",
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index 872355b5..68dc731 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -108,6 +108,26 @@ ci.builder( name = "VR Linux", branch_selector = branches.STANDARD_MILESTONE, + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "enable_reclient", + ], + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "mb", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + test_results_config = builder_config.test_results_config( + config = "staging_server", + ), + build_gs_bucket = "chromium-fyi-archive", + ), console_view_entry = consoles.console_view_entry( category = "linux", ),
diff --git a/infra/config/subprojects/chromium/ci/chromium.linux.star b/infra/config/subprojects/chromium/ci/chromium.linux.star index 92d2ee9..364d72b 100644 --- a/infra/config/subprojects/chromium/ci/chromium.linux.star +++ b/infra/config/subprojects/chromium/ci/chromium.linux.star
@@ -498,6 +498,23 @@ ci.builder( name = "linux-bfcache-rel", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "enable_reclient", + ], + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "mb", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + build_gs_bucket = "chromium-linux-archive", + ), console_view_entry = consoles.console_view_entry( category = "bfcache", short_name = "bfc",
diff --git a/infra/config/subprojects/chromium/ci/chromium.star b/infra/config/subprojects/chromium/ci/chromium.star index d7ded7e..cf2907f6 100644 --- a/infra/config/subprojects/chromium/ci/chromium.star +++ b/infra/config/subprojects/chromium/ci/chromium.star
@@ -300,6 +300,20 @@ ci.builder( name = "mac-archive-dbg", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "clobber", + "mb", + ], + build_config = builder_config.build_config.DEBUG, + target_bits = 64, + ), + ), console_view_entry = consoles.console_view_entry( category = "mac", short_name = "dbg", @@ -312,6 +326,21 @@ ci.builder( name = "mac-archive-rel", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "clobber", + "mb", + "goma_use_local", # to mitigate compile step timeout (crbug.com/1056935). + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + ), console_view_entry = consoles.console_view_entry( category = "mac", short_name = "rel",
diff --git a/infra/config/subprojects/chromium/ci/chromium.swangle.star b/infra/config/subprojects/chromium/ci/chromium.swangle.star index f7d791e1..58e3432 100644 --- a/infra/config/subprojects/chromium/ci/chromium.swangle.star +++ b/infra/config/subprojects/chromium/ci/chromium.swangle.star
@@ -19,15 +19,12 @@ consoles.console_view( name = "chromium.swangle", ordering = { - None: ["DEPS", "ToT ANGLE", "ToT SwiftShader"], + None: ["DEPS", "ToT SwiftShader", "Chromium"], "*os*": ["Windows", "Mac"], "*cpu*": consoles.ordering(short_names = ["x86", "x64"]), "DEPS": "*os*", "DEPS|Windows": "*cpu*", "DEPS|Linux": "*cpu*", - "ToT ANGLE": "*os*", - "ToT ANGLE|Windows": "*cpu*", - "ToT ANGLE|Linux": "*cpu*", "ToT SwiftShader": "*os*", "ToT SwiftShader|Windows": "*cpu*", "ToT SwiftShader|Linux": "*cpu*", @@ -48,17 +45,6 @@ ) ci.gpu.linux_builder( - name = "linux-swangle-tot-angle-x64", - console_view_entry = consoles.console_view_entry( - category = "ToT ANGLE|Linux", - short_name = "x64", - ), - goma_backend = None, - reclient_jobs = rbe_jobs.HIGH_JOBS_FOR_CI, - reclient_instance = rbe_instance.DEFAULT, -) - -ci.gpu.linux_builder( name = "linux-swangle-tot-swiftshader-x64", console_view_entry = consoles.console_view_entry( category = "ToT SwiftShader|Linux", @@ -104,28 +90,6 @@ ) ci.gpu.windows_builder( - name = "win-swangle-tot-angle-x64", - console_view_entry = consoles.console_view_entry( - category = "ToT ANGLE|Windows", - short_name = "x64", - ), - goma_backend = None, - reclient_jobs = rbe_jobs.LOW_JOBS_FOR_CI, - reclient_instance = rbe_instance.DEFAULT, -) - -ci.gpu.windows_builder( - name = "win-swangle-tot-angle-x86", - console_view_entry = consoles.console_view_entry( - category = "ToT ANGLE|Windows", - short_name = "x86", - ), - goma_backend = None, - reclient_jobs = rbe_jobs.LOW_JOBS_FOR_CI, - reclient_instance = rbe_instance.DEFAULT, -) - -ci.gpu.windows_builder( name = "win-swangle-tot-swiftshader-x64", console_view_entry = consoles.console_view_entry( category = "ToT SwiftShader|Windows",
diff --git a/infra/config/subprojects/chromium/swangle.try.star b/infra/config/subprojects/chromium/swangle.try.star index e1efb99..c4ed7ed 100644 --- a/infra/config/subprojects/chromium/swangle.try.star +++ b/infra/config/subprojects/chromium/swangle.try.star
@@ -58,11 +58,6 @@ ) swangle_linux_builder( - name = "linux-swangle-try-tot-angle-x64", - pool = "luci.chromium.swangle.angle.linux.x64.try", -) - -swangle_linux_builder( name = "linux-swangle-try-tot-swiftshader-x64", pool = "luci.chromium.swangle.sws.linux.x64.try", ) @@ -88,16 +83,6 @@ ) swangle_windows_builder( - name = "win-swangle-try-tot-angle-x64", - pool = "luci.chromium.swangle.win.x64.try", -) - -swangle_windows_builder( - name = "win-swangle-try-tot-angle-x86", - pool = "luci.chromium.swangle.angle.win.x86.try", -) - -swangle_windows_builder( name = "win-swangle-try-tot-swiftshader-x64", pool = "luci.chromium.swangle.win.x64.try", )
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star index 8da163b..d244f11 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -68,6 +68,9 @@ try_.builder( name = "chromeos-arm-generic-dbg", + mirrors = [ + "ci/chromeos-arm-generic-dbg", + ], ) try_.builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.dawn.star b/infra/config/subprojects/chromium/try/tryserver.chromium.dawn.star index 168f5d68..7faa6aa6e 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.dawn.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.dawn.star
@@ -101,6 +101,11 @@ try_.builder( name = "dawn-win10-x86-deps-rel", branch_selector = branches.DESKTOP_EXTENDED_STABLE_MILESTONE, + mirrors = [ + "ci/Dawn Win10 x86 DEPS Builder", + "ci/Dawn Win10 x86 DEPS Release (Intel HD 630)", + "ci/Dawn Win10 x86 DEPS Release (NVIDIA)", + ], main_list_view = "try", os = os.WINDOWS_ANY, tryjob = try_.job(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star index 0455300..a56d85ce 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -210,6 +210,9 @@ try_.builder( name = "linux-bfcache-rel", + mirrors = [ + "ci/linux-bfcache-rel", + ], ) try_.builder( @@ -630,6 +633,9 @@ try_.builder( name = "linux_vr", branch_selector = branches.STANDARD_MILESTONE, + mirrors = [ + "ci/VR Linux", + ], main_list_view = "try", tryjob = try_.job( location_regexp = [
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star index 03a09e5..28989381 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -190,6 +190,9 @@ try_.builder( name = "mac_chromium_archive_rel_ng", + mirrors = [ + "ci/mac-archive-rel", + ], ) try_.builder(
diff --git a/infra/config/subprojects/goma/goma.star b/infra/config/subprojects/goma/goma.star index dd6822c4..62a99d97 100644 --- a/infra/config/subprojects/goma/goma.star +++ b/infra/config/subprojects/goma/goma.star
@@ -206,6 +206,19 @@ fyi_goma_rbe_canary_builder( name = "mac-archive-rel-goma-rbe-canary", + builder_spec = builder_config.copy_from( + "ci/mac-archive-rel", + lambda spec: structs.evolve( + spec, + chromium_config = structs.extend( + spec.chromium_config, + apply_configs = [ + "goma_canary", + ], + ), + build_gs_bucket = "chromium-fyi-archive", + ), + ), cores = 4, goma_jobs = goma.jobs.J80, os = os.MAC_DEFAULT, @@ -454,6 +467,19 @@ fyi_goma_rbe_latest_client_builder( name = "mac-archive-rel-goma-rbe-latest", + builder_spec = builder_config.copy_from( + "ci/mac-archive-rel", + lambda spec: structs.evolve( + spec, + chromium_config = structs.extend( + spec.chromium_config, + apply_configs = [ + "goma_latest_client", + ], + ), + build_gs_bucket = "chromium-fyi-archive", + ), + ), cores = 4, goma_jobs = goma.jobs.J80, os = os.MAC_DEFAULT,
diff --git a/ios/chrome/browser/follow/follow_menu_updater.h b/ios/chrome/browser/follow/follow_menu_updater.h index 9da39ca..f5e54f7 100644 --- a/ios/chrome/browser/follow/follow_menu_updater.h +++ b/ios/chrome/browser/follow/follow_menu_updater.h
@@ -10,12 +10,12 @@ // Protocol defining a updater for follow menu item. @protocol FollowMenuUpdater -// Updates the follow menu item with follow |webPageURLs|, |status|, |title| and -// |enabled|. +// Updates the follow menu item with follow |webPageURLs|, |status|, +// |domainName| and |enabled|. - (void)updateFollowMenuItemWithFollowWebPageURLs: (FollowWebPageURLs*)webPageURLs status:(BOOL)status - title:(NSString*)title + domainName:(NSString*)domainName enabled:(BOOL)enabled; @end
diff --git a/ios/chrome/browser/follow/follow_tab_helper.mm b/ios/chrome/browser/follow/follow_tab_helper.mm index 130439bc..4ee195fc 100644 --- a/ios/chrome/browser/follow/follow_tab_helper.mm +++ b/ios/chrome/browser/follow/follow_tab_helper.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/follow/follow_tab_helper.h" #include "base/memory/ptr_util.h" +#include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/public/tracker.h" @@ -133,27 +134,21 @@ ios::GetChromeBrowserProvider().GetFollowProvider()->GetFollowStatus( web_page_urls); - NSString* title = nil; std::string domainName = web::GetMainFrame(web_state_)->GetSecurityOrigin().host(); if (domainName.substr(0, kRemovablePrefix.length()) == kRemovablePrefix) { domainName = domainName.substr(kRemovablePrefix.length(), domainName.length()); } - if (!status) { - title = l10n_util::GetNSStringF(IDS_IOS_TOOLS_MENU_FOLLOW, - base::UTF8ToUTF16(domainName)); - } else { - title = l10n_util::GetNSStringF(IDS_IOS_TOOLS_MENU_UNFOLLOW, - base::UTF8ToUTF16(domainName)); - } bool enabled = GetFollowActionState(web_state_) == FollowActionStateEnabled; - [follow_menu_updater_ updateFollowMenuItemWithFollowWebPageURLs:web_page_urls - status:status - title:title - enabled:enabled]; + [follow_menu_updater_ + updateFollowMenuItemWithFollowWebPageURLs:web_page_urls + status:status + domainName:base::SysUTF8ToNSString( + domainName) + enabled:enabled]; should_update_follow_item_ = false; }
diff --git a/ios/chrome/browser/ui/follow/BUILD.gn b/ios/chrome/browser/ui/follow/BUILD.gn index b887697..c0c5dfbe 100644 --- a/ios/chrome/browser/ui/follow/BUILD.gn +++ b/ios/chrome/browser/ui/follow/BUILD.gn
@@ -39,11 +39,13 @@ ] deps = [ ":first_follow_ui", + ":follow", "//ios/chrome/browser/favicon", "//ios/chrome/browser/main:public", "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/coordinators:chrome_coordinators", + "//ios/chrome/common/ui/confirmation_alert", "//ios/chrome/common/ui/favicon", "//ios/chrome/common/ui/favicon:favicon_constants", ] @@ -54,7 +56,6 @@ "first_follow_favicon_data_source.h", "first_follow_view_controller.h", "first_follow_view_controller.mm", - "first_follow_view_delegate.h", ] configs += [ "//build/config/compiler:enable_arc" ] deps = [ @@ -63,6 +64,7 @@ "//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/browser/ui/icons:symbols", "//ios/chrome/common/ui/colors", + "//ios/chrome/common/ui/confirmation_alert", "//ios/chrome/common/ui/favicon", "//ios/chrome/common/ui/util", "//ui/base",
diff --git a/ios/chrome/browser/ui/follow/first_follow_coordinator.mm b/ios/chrome/browser/ui/follow/first_follow_coordinator.mm index 3624206..8219c86b 100644 --- a/ios/chrome/browser/ui/follow/first_follow_coordinator.mm +++ b/ios/chrome/browser/ui/follow/first_follow_coordinator.mm
@@ -12,7 +12,8 @@ #import "ios/chrome/browser/ui/commands/new_tab_page_commands.h" #import "ios/chrome/browser/ui/follow/first_follow_favicon_data_source.h" #import "ios/chrome/browser/ui/follow/first_follow_view_controller.h" -#import "ios/chrome/browser/ui/follow/first_follow_view_delegate.h" +#import "ios/chrome/browser/ui/follow/followed_web_channel.h" +#import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_action_handler.h" #import "ios/chrome/common/ui/favicon/favicon_attributes.h" #import "ios/chrome/common/ui/favicon/favicon_constants.h" @@ -27,10 +28,14 @@ } // namespace -@interface FirstFollowCoordinator () <FirstFollowFaviconDataSource, - FirstFollowViewDelegate> +@interface FirstFollowCoordinator () <ConfirmationAlertActionHandler, + FirstFollowFaviconDataSource> // FaviconLoader retrieves favicons for a given page URL. @property(nonatomic, assign) FaviconLoader* faviconLoader; + +// The view controller is owned by the view hierarchy. +@property(nonatomic, weak) FirstFollowViewController* firstFollowViewController; + @end @implementation FirstFollowCoordinator @@ -43,7 +48,8 @@ firstFollowViewController.followedWebChannel = self.followedWebChannel; // Ownership is passed to VC so this object is not retained after VC closes. self.followedWebChannel = nil; - firstFollowViewController.delegate = self; + self.firstFollowViewController = firstFollowViewController; + firstFollowViewController.actionHandler = self; firstFollowViewController.faviconDataSource = self; self.faviconLoader = IOSChromeFaviconLoaderFactory::GetForBrowserState( @@ -78,23 +84,33 @@ } } -#pragma mark - FirstFollowViewDelegate +#pragma mark - ConfirmationAlertActionHandler -// Go To Feed button tapped. -- (void)handleGoToFeedTapped { - [self.newTabPageCommandsHandler - openNTPScrolledIntoFeedType:FeedTypeFollowing]; +- (void)confirmationAlertPrimaryAction { + if (self.firstFollowViewController.followedWebChannel.available) { + [self.newTabPageCommandsHandler + openNTPScrolledIntoFeedType:FeedTypeFollowing]; + } + if (self.baseViewController.presentedViewController) { + [self.baseViewController dismissViewControllerAnimated:YES completion:nil]; + } +} + +- (void)confirmationAlertSecondaryAction { + if (self.baseViewController.presentedViewController) { + [self.baseViewController dismissViewControllerAnimated:YES completion:nil]; + } } #pragma mark - FirstFollowFaviconDataSource - (void)faviconForURL:(CrURL*)URL completion:(void (^)(FaviconAttributes*))completion { - self.faviconLoader->FaviconForIconUrl(URL.gurl, kDesiredSmallFaviconSizePt, - kMinFaviconSizePt, - ^(FaviconAttributes* attributes) { - completion(attributes); - }); + self.faviconLoader->FaviconForPageUrl( + URL.gurl, kDesiredSmallFaviconSizePt, kMinFaviconSizePt, + /*fallback_to_google_server=*/true, ^(FaviconAttributes* attributes) { + completion(attributes); + }); } #pragma mark - Helpers
diff --git a/ios/chrome/browser/ui/follow/first_follow_view_controller.h b/ios/chrome/browser/ui/follow/first_follow_view_controller.h index 9eac94a4..96634a65 100644 --- a/ios/chrome/browser/ui/follow/first_follow_view_controller.h +++ b/ios/chrome/browser/ui/follow/first_follow_view_controller.h
@@ -7,20 +7,18 @@ #import <UIKit/UIKit.h> -@protocol FirstFollowViewDelegate; +#import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h" + @protocol FirstFollowFaviconDataSource; @class FollowedWebChannel; // The UI that informs the user about the feed and following channels the // first few times the user follows any channel. -@interface FirstFollowViewController : UIViewController +@interface FirstFollowViewController : ConfirmationAlertViewController // The web channel that was recently followed. @property(nonatomic, strong) FollowedWebChannel* followedWebChannel; -// Delegate to execute actions triggered in this UI. -@property(nonatomic, weak) id<FirstFollowViewDelegate> delegate; - // Data source for favicons. @property(nonatomic, weak) id<FirstFollowFaviconDataSource> faviconDataSource;
diff --git a/ios/chrome/browser/ui/follow/first_follow_view_controller.mm b/ios/chrome/browser/ui/follow/first_follow_view_controller.mm index c6846ae..d0cbc09 100644 --- a/ios/chrome/browser/ui/follow/first_follow_view_controller.mm +++ b/ios/chrome/browser/ui/follow/first_follow_view_controller.mm
@@ -6,7 +6,6 @@ #include "base/strings/sys_string_conversions.h" #import "ios/chrome/browser/ui/follow/first_follow_favicon_data_source.h" -#import "ios/chrome/browser/ui/follow/first_follow_view_delegate.h" #import "ios/chrome/browser/ui/follow/followed_web_channel.h" #import "ios/chrome/browser/ui/icons/chrome_symbol.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" @@ -23,300 +22,53 @@ namespace { -// Accessibility identifier for the Go To Feed button. -NSString* const kFirstFollowGoToFeedButtonIdentifier = - @"FirstFollowGoToFeedButtonIdentifier"; - -// Accessibility identifier for the Got It button. -NSString* const kFirstFollowGotItButtonIdentifier = - @"FirstFollowGotItButtonIdentifier"; - -// Optimal width of content. This is also the maxium. -constexpr CGFloat kContentOptimalWidth = 327; - -// Length of each side of the favicon frame (which contains the favicon and the -// surrounding whitespace). -constexpr CGFloat kFaviconFrameSideLength = 60; - -// Length of each side of the favicon. -constexpr CGFloat kFaviconSideLength = 30; - -// Length of each side of the favicon badge. -constexpr CGFloat kFaviconBadgeSideLength = 24; - -// Vertical inset of views inside |self.view|. -constexpr CGFloat kVerticalInset = 10.0; - -// Horizontal inset of views inside |self.view|. -constexpr CGFloat kHorizontalInset = 10.0; - -// Vertical space between favicon and labels. -constexpr CGFloat kVerticalSpacing = 10.0; - -// Vertical spacing between labels and buttons in stack views. -constexpr CGFloat kStackViewVerticalSpacing = 10.0; - -// The size of the symbol badge image. -NSInteger kSymbolBadgeImagePointSize = 13; - -// Properties of the favicon. -constexpr CGFloat kFaviconCornerRadius = 10; -constexpr CGFloat kFaviconShadowOffsetX = 0; -constexpr CGFloat kFaviconShadowOffsetY = 0; -constexpr CGFloat kFaviconShadowRadius = 10; -constexpr CGFloat kFaviconShadowOpacity = 0.2; +constexpr CGFloat customSpacingBeforeImageIfNoToolbar = 24; +constexpr CGFloat customSpacingAfterImage = 1; } // namespace @implementation FirstFollowViewController - (void)viewDidLoad { - [super viewDidLoad]; - self.view.backgroundColor = [UIColor colorNamed:kBackgroundColor]; + self.imageHasFixedSize = YES; + self.showDismissBarButton = NO; + self.customSpacingBeforeImageIfNoToolbar = + customSpacingBeforeImageIfNoToolbar; + self.customSpacingAfterImage = customSpacingAfterImage; + self.titleTextStyle = UIFontTextStyleTitle2; + self.topAlignedLayout = YES; - UIView* containerView = self.view; - UIView* faviconView = [self faviconView]; - UIView* labelsView = [self labelsView]; - UIView* buttonsView = [self buttonsView]; - [containerView addSubview:faviconView]; - [containerView addSubview:labelsView]; - [containerView addSubview:buttonsView]; + self.titleString = l10n_util::GetNSStringF( + IDS_IOS_FIRST_FOLLOW_TITLE, + base::SysNSStringToUTF16(self.followedWebChannel.title)); + self.secondaryTitleString = l10n_util::GetNSStringF( + IDS_IOS_FIRST_FOLLOW_SUBTITLE, + base::SysNSStringToUTF16(self.followedWebChannel.title)); + self.subtitleString = l10n_util::GetNSString(IDS_IOS_FIRST_FOLLOW_BODY); - [NSLayoutConstraint activateConstraints:@[ - // faviconView constraints. - [faviconView.centerXAnchor - constraintEqualToAnchor:containerView.centerXAnchor], - [faviconView.topAnchor constraintEqualToAnchor:containerView.topAnchor - constant:kVerticalInset], - - // labelsView constraints. - [labelsView.centerXAnchor - constraintEqualToAnchor:containerView.centerXAnchor], - [labelsView.topAnchor constraintEqualToAnchor:faviconView.bottomAnchor - constant:kVerticalSpacing], - [labelsView.leadingAnchor - constraintGreaterThanOrEqualToAnchor:containerView.leadingAnchor - constant:kHorizontalInset], - [labelsView.trailingAnchor - constraintLessThanOrEqualToAnchor:containerView.trailingAnchor - constant:-kHorizontalInset], - - // buttonsView constraints. - [buttonsView.centerXAnchor - constraintEqualToAnchor:containerView.centerXAnchor], - [buttonsView.topAnchor - constraintGreaterThanOrEqualToAnchor:labelsView.bottomAnchor - constant:kVerticalSpacing], - [buttonsView.leadingAnchor - constraintGreaterThanOrEqualToAnchor:containerView.leadingAnchor - constant:kHorizontalInset], - [buttonsView.trailingAnchor - constraintLessThanOrEqualToAnchor:containerView.trailingAnchor - constant:-kHorizontalInset], - [buttonsView.bottomAnchor - constraintEqualToAnchor:containerView.safeAreaLayoutGuide.bottomAnchor - constant:-kVerticalInset], - ]]; - - // This constraint ensures a max width by setting the priority slightly - // higher. - NSLayoutConstraint* labelsOptimalWidthConstraint = - [labelsView.widthAnchor constraintEqualToConstant:kContentOptimalWidth]; - NSLayoutConstraint* buttonsOptimalWidthConstraint = - [buttonsView.widthAnchor constraintEqualToConstant:kContentOptimalWidth]; - labelsOptimalWidthConstraint.priority = UILayoutPriorityDefaultHigh + 1; - buttonsOptimalWidthConstraint.priority = UILayoutPriorityDefaultHigh + 1; - [NSLayoutConstraint activateConstraints:@[ - labelsOptimalWidthConstraint, buttonsOptimalWidthConstraint - ]]; -} - -#pragma mark - Helpers - -// Calls delegate to go to feed and dismisses the sheet. -- (void)handleGoToFeedTapped { - [self.delegate handleGoToFeedTapped]; - [self.presentingViewController dismissViewControllerAnimated:YES - completion:nil]; -} - -// Dismisses the sheet. -- (void)handleGotItTapped { - [self.presentingViewController dismissViewControllerAnimated:YES - completion:nil]; -} - -// Returns a view with a favicon and a check mark badge on the upper right -// corner. -- (UIView*)faviconView { - FaviconContainerView* faviconContainerView = - [[FaviconContainerView alloc] init]; - faviconContainerView.translatesAutoresizingMaskIntoConstraints = NO; - - [self.faviconDataSource faviconForURL:self.followedWebChannel.faviconURL - completion:^(FaviconAttributes* attributes) { - DCHECK(attributes); - [faviconContainerView.faviconView - configureWithAttributes:attributes]; - }]; - - UIImageView* faviconBadgeView = [[UIImageView alloc] init]; - faviconBadgeView.translatesAutoresizingMaskIntoConstraints = NO; - faviconBadgeView.image = DefaultSymbolTemplateWithPointSize( - kCheckMarkCircleFillSymbol, kSymbolBadgeImagePointSize); - faviconBadgeView.tintColor = [UIColor colorNamed:kGreenColor]; - - UIView* view = [[UIView alloc] init]; - UIView* frameView = [[UIView alloc] init]; - [view addSubview:frameView]; - [view addSubview:faviconBadgeView]; - [frameView addSubview:faviconContainerView]; - view.translatesAutoresizingMaskIntoConstraints = NO; - frameView.translatesAutoresizingMaskIntoConstraints = NO; - - frameView.backgroundColor = [UIColor colorNamed:kBackgroundColor]; - frameView.layer.cornerRadius = kFaviconCornerRadius; - frameView.layer.shadowOffset = - CGSizeMake(kFaviconShadowOffsetX, kFaviconShadowOffsetY); - frameView.layer.shadowRadius = kFaviconShadowRadius; - frameView.layer.shadowOpacity = kFaviconShadowOpacity; - - [NSLayoutConstraint activateConstraints:@[ - // Size constraints. - [frameView.widthAnchor constraintEqualToConstant:kFaviconFrameSideLength], - [frameView.heightAnchor constraintEqualToConstant:kFaviconFrameSideLength], - [faviconContainerView.widthAnchor - constraintEqualToConstant:kFaviconSideLength], - [faviconContainerView.heightAnchor - constraintEqualToConstant:kFaviconSideLength], - [faviconBadgeView.widthAnchor - constraintEqualToConstant:kFaviconBadgeSideLength], - [faviconBadgeView.heightAnchor - constraintEqualToConstant:kFaviconBadgeSideLength], - - // Badge is on the upper right corner of the frame. - [frameView.topAnchor - constraintEqualToAnchor:faviconBadgeView.centerYAnchor], - [frameView.trailingAnchor - constraintEqualToAnchor:faviconBadgeView.centerXAnchor], - - // Favicon is centered in the frame. - [frameView.centerXAnchor - constraintEqualToAnchor:faviconContainerView.centerXAnchor], - [frameView.centerYAnchor - constraintEqualToAnchor:faviconContainerView.centerYAnchor], - - // Frame and badge define the whole view returned by this method. - [view.leadingAnchor constraintEqualToAnchor:frameView.leadingAnchor], - [view.bottomAnchor constraintEqualToAnchor:frameView.bottomAnchor], - [view.topAnchor constraintEqualToAnchor:faviconBadgeView.topAnchor], - [view.trailingAnchor - constraintEqualToAnchor:faviconBadgeView.trailingAnchor], - ]]; - return view; -} - -// Returns a stack view with the title, subtitle, and body labels. -- (UIView*)labelsView { - // Set strings. - UILabel* titleLabel = [self - labelWithText:l10n_util::GetNSStringF( - IDS_IOS_FIRST_FOLLOW_TITLE, - base::SysNSStringToUTF16(self.followedWebChannel.title)) - textStyle:UIFontTextStyleTitle1]; - UILabel* subTitleLabel = [self - labelWithText:l10n_util::GetNSStringF( - IDS_IOS_FIRST_FOLLOW_SUBTITLE, - base::SysNSStringToUTF16(self.followedWebChannel.title)) - textStyle:UIFontTextStyleHeadline]; - UILabel* bodyLabel = - [self labelWithText:l10n_util::GetNSString(IDS_IOS_FIRST_FOLLOW_BODY) - textStyle:UIFontTextStyleBody]; - - // Set colors. - titleLabel.textColor = [UIColor colorNamed:kTextPrimaryColor]; - subTitleLabel.textColor = [UIColor colorNamed:kTextSecondaryColor]; - bodyLabel.textColor = [UIColor colorNamed:kTextTertiaryColor]; - - UIStackView* verticalStack = [[UIStackView alloc] - initWithArrangedSubviews:@[ titleLabel, subTitleLabel, bodyLabel ]]; - - verticalStack.axis = UILayoutConstraintAxisVertical; - verticalStack.distribution = UIStackViewDistributionFillProportionally; - verticalStack.alignment = UIStackViewAlignmentCenter; - verticalStack.spacing = kStackViewVerticalSpacing; - verticalStack.translatesAutoresizingMaskIntoConstraints = NO; - - return verticalStack; -} - -// Returns a label with |textStyle|. -- (UILabel*)labelWithText:(NSString*)text textStyle:(UIFontTextStyle)textStyle { - UILabel* label = [[UILabel alloc] init]; - label.translatesAutoresizingMaskIntoConstraints = NO; - label.font = [UIFont preferredFontForTextStyle:textStyle]; - label.adjustsFontForContentSizeCategory = YES; - label.numberOfLines = 0; - label.textAlignment = NSTextAlignmentCenter; - label.text = text; - return label; -} - -// Returns a stack view with configured buttons. -- (UIView*)buttonsView { - UIButton* goToFeedButton = nil; - UIButton* gotItButton = nil; if (self.followedWebChannel.available) { // Go To Feed button is only displayed if the web channel is available. - goToFeedButton = PrimaryActionButton(YES); - gotItButton = [self plainButton]; + self.primaryActionString = + l10n_util::GetNSString(IDS_IOS_FIRST_FOLLOW_GO_TO_FEED); + self.secondaryActionString = + l10n_util::GetNSString(IDS_IOS_FIRST_FOLLOW_GOT_IT); } else { // Only one button is visible, and it is a primary action button (with a // solid background color). - gotItButton = PrimaryActionButton(YES); + self.primaryActionString = + l10n_util::GetNSString(IDS_IOS_FIRST_FOLLOW_GOT_IT); } - // Configure buttons. - if (goToFeedButton) { - [goToFeedButton - setTitle:l10n_util::GetNSString(IDS_IOS_FIRST_FOLLOW_GO_TO_FEED) - forState:UIControlStateNormal]; - [goToFeedButton - setAccessibilityIdentifier:kFirstFollowGoToFeedButtonIdentifier]; - [goToFeedButton addTarget:self - action:@selector(handleGoToFeedTapped) - forControlEvents:UIControlEventTouchUpInside]; + // TODO(crbug.com/1312124): Favicon styling needs more whitespace, shadow, and + // corner green checkmark badge. + if (self.followedWebChannel.webPageURL) { + [self.faviconDataSource faviconForURL:self.followedWebChannel.webPageURL + completion:^(FaviconAttributes* attributes) { + self.image = attributes.faviconImage; + }]; } - [gotItButton setTitle:l10n_util::GetNSString(IDS_IOS_FIRST_FOLLOW_GOT_IT) - forState:UIControlStateNormal]; - [gotItButton setAccessibilityIdentifier:kFirstFollowGotItButtonIdentifier]; - [gotItButton addTarget:self - action:@selector(handleGotItTapped) - forControlEvents:UIControlEventTouchUpInside]; - NSArray* buttons = - (goToFeedButton) ? @[ goToFeedButton, gotItButton ] : @[ gotItButton ]; - UIStackView* verticalStack = - [[UIStackView alloc] initWithArrangedSubviews:buttons]; - verticalStack.axis = UILayoutConstraintAxisVertical; - verticalStack.distribution = UIStackViewDistributionFill; - verticalStack.alignment = UIStackViewAlignmentFill; - verticalStack.spacing = kStackViewVerticalSpacing; - verticalStack.translatesAutoresizingMaskIntoConstraints = NO; - return verticalStack; -} - -// Returns a plain button. -- (UIButton*)plainButton { - UIButton* button = [[UIButton alloc] init]; - button.titleLabel.font = - [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; - button.titleLabel.adjustsFontForContentSizeCategory = YES; - button.titleLabel.textAlignment = NSTextAlignmentCenter; - [button setTranslatesAutoresizingMaskIntoConstraints:NO]; - [button setTitleColor:[UIColor colorNamed:kBlueColor] - forState:UIControlStateNormal]; - return button; + [super viewDidLoad]; } @end
diff --git a/ios/chrome/browser/ui/follow/first_follow_view_delegate.h b/ios/chrome/browser/ui/follow/first_follow_view_delegate.h deleted file mode 100644 index d8c04d0..0000000 --- a/ios/chrome/browser/ui/follow/first_follow_view_delegate.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_FOLLOW_FIRST_FOLLOW_VIEW_DELEGATE_H_ -#define IOS_CHROME_BROWSER_UI_FOLLOW_FIRST_FOLLOW_VIEW_DELEGATE_H_ - -// Actions triggered in the first follow UI. -@protocol FirstFollowViewDelegate - -// Go To Feed button tapped. -- (void)handleGoToFeedTapped; - -@end - -#endif // IOS_CHROME_BROWSER_UI_FOLLOW_FIRST_FOLLOW_VIEW_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/follow/followed_web_channel.h b/ios/chrome/browser/ui/follow/followed_web_channel.h index f28bf20..b440111 100644 --- a/ios/chrome/browser/ui/follow/followed_web_channel.h +++ b/ios/chrome/browser/ui/follow/followed_web_channel.h
@@ -17,10 +17,6 @@ // Title of the web channel. @property(nonatomic, copy) NSString* title; -// TODO(crbug.com/1296745): Deprecated. -// URL of the web channel. -@property(nonatomic, strong) CrURL* channelURL; - // URL of the web channel web page. @property(nonatomic, strong) CrURL* webPageURL; @@ -39,15 +35,6 @@ // Used to request to refollow this web channel, if it has been unfollowed. @property(nonatomic, copy) FollowRequestBlock refollowRequestBlock; -// TODO(crbug.com/1296745): Deprecated. -// Designated initializer with all the properties. -- (instancetype)initWithTitle:(NSString*)title - channelURL:(CrURL*)channelURL - faviconURL:(CrURL*)faviconURL - available:(BOOL)available - unfollowRequestBlock:(FollowRequestBlock)unfollowRequestBlock - refollowRequestBlock:(FollowRequestBlock)refollowRequestBlock; - @end #endif // IOS_CHROME_BROWSER_UI_FOLLOW_FOLLOWED_WEB_CHANNEL_H_
diff --git a/ios/chrome/browser/ui/follow/followed_web_channel.mm b/ios/chrome/browser/ui/follow/followed_web_channel.mm index 431b5d1f..e2945a6 100644 --- a/ios/chrome/browser/ui/follow/followed_web_channel.mm +++ b/ios/chrome/browser/ui/follow/followed_web_channel.mm
@@ -13,25 +13,6 @@ @implementation FollowedWebChannel -// TODO(crbug.com/1296745): Deprecated. -- (instancetype)initWithTitle:(NSString*)title - channelURL:(CrURL*)channelURL - faviconURL:(CrURL*)faviconURL - available:(BOOL)available - unfollowRequestBlock:(FollowRequestBlock)unfollowRequestBlock - refollowRequestBlock:(FollowRequestBlock)refollowRequestBlock { - self = [super init]; - if (self) { - _title = title; - _channelURL = channelURL; - _faviconURL = faviconURL; - _available = available; - _unfollowRequestBlock = unfollowRequestBlock; - _refollowRequestBlock = refollowRequestBlock; - } - return self; -} - #pragma mark - NSObject - (BOOL)isEqualToFollowedWebChannel:(FollowedWebChannel*)channel {
diff --git a/ios/chrome/browser/ui/icons/chrome_symbol.h b/ios/chrome/browser/ui/icons/chrome_symbol.h index e35e36f..dc57747e 100644 --- a/ios/chrome/browser/ui/icons/chrome_symbol.h +++ b/ios/chrome/browser/ui/icons/chrome_symbol.h
@@ -36,6 +36,7 @@ extern NSString* const kHelpFillSymbol; extern NSString* const kCheckMarkCircleFillSymbol; extern NSString* const kFailMarkCircleFillSymbol; +extern NSString* const kTrashSymbol; // Returns a SF symbol named |symbolName| configured with the given // |configuration|.
diff --git a/ios/chrome/browser/ui/icons/chrome_symbol.mm b/ios/chrome/browser/ui/icons/chrome_symbol.mm index ccd8344d..4c16a499 100644 --- a/ios/chrome/browser/ui/icons/chrome_symbol.mm +++ b/ios/chrome/browser/ui/icons/chrome_symbol.mm
@@ -74,6 +74,7 @@ NSString* const kHelpFillSymbol = @"questionmark.circle"; NSString* const kCheckMarkCircleFillSymbol = @"checkmark.circle.fill"; NSString* const kFailMarkCircleFillSymbol = @"exclamationmark.circle.fill"; +NSString* const kTrashSymbol = @"trash"; UIImage* DefaultSymbolWithConfiguration(NSString* symbolName, UIImageConfiguration* configuration) {
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn index 7b621b2..11d4983a 100644 --- a/ios/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -6,6 +6,7 @@ sources = [ "discover_feed_delegate.h", "discover_feed_preview_delegate.h", + "feed_control_delegate.h", "new_tab_page_configuring.h", "new_tab_page_content_delegate.h", "new_tab_page_controller_delegate.h", @@ -90,6 +91,7 @@ "//ios/chrome/browser/voice", "//ios/chrome/browser/web_state_list", "//ios/chrome/common/ui/util", + "//ios/public/provider/chrome/browser/follow", "//ios/public/provider/chrome/browser/ui_utils:ui_utils_api", "//ios/web/public", "//ui/base", @@ -114,7 +116,6 @@ sources = [ "discover_feed_wrapper_view_controller.h", "discover_feed_wrapper_view_controller.mm", - "feed_control_delegate.h", "feed_header_view_controller.h", "feed_header_view_controller.mm", "feed_menu_commands.h", @@ -224,6 +225,7 @@ "feed_metrics_recorder.mm", ] deps = [ + ":ntp", "//base", "//components/feed/core/v2/public:common", "//ios/chrome/browser/discover_feed:constants",
diff --git a/ios/chrome/browser/ui/ntp/feed_management/follow_management_mediator.mm b/ios/chrome/browser/ui/ntp/feed_management/follow_management_mediator.mm index 9d7804ba..072101a 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/follow_management_mediator.mm +++ b/ios/chrome/browser/ui/ntp/feed_management/follow_management_mediator.mm
@@ -50,11 +50,11 @@ - (void)faviconForURL:(CrURL*)URL completion:(void (^)(FaviconAttributes*))completion { - self.faviconLoader->FaviconForIconUrl(URL.gurl, kDesiredSmallFaviconSizePt, - kMinFaviconSizePt, - ^(FaviconAttributes* attributes) { - completion(attributes); - }); + self.faviconLoader->FaviconForPageUrl( + URL.gurl, kDesiredSmallFaviconSizePt, kMinFaviconSizePt, + /*fallback_to_google_server=*/true, ^(FaviconAttributes* attributes) { + completion(attributes); + }); } @end
diff --git a/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.mm b/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.mm index 2e2ba4c3..07d6ef86 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.mm
@@ -73,9 +73,9 @@ base::mac::ObjCCastStrict<FollowedWebChannelItem>(tableViewItem); FollowedWebChannelCell* followedWebChannelCell = base::mac::ObjCCastStrict<FollowedWebChannelCell>(cellToReturn); - CrURL* faviconURL = followedWebChannelItem.followedWebChannel.faviconURL; + CrURL* webPageURL = followedWebChannelItem.followedWebChannel.webPageURL; - [self.faviconDataSource faviconForURL:faviconURL + [self.faviconDataSource faviconForURL:webPageURL completion:^(FaviconAttributes* attributes) { // Only set favicon if the cell hasn't been // reused.
diff --git a/ios/chrome/browser/ui/ntp/feed_management/followed_web_channel_item.mm b/ios/chrome/browser/ui/ntp/feed_management/followed_web_channel_item.mm index 72926c55..9d76621 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/followed_web_channel_item.mm +++ b/ios/chrome/browser/ui/ntp/feed_management/followed_web_channel_item.mm
@@ -7,6 +7,7 @@ #import <UIKit/UIKit.h> #include "base/mac/foundation_util.h" +#import "ios/chrome/browser/net/crurl.h" #import "ios/chrome/browser/ui/follow/followed_web_channel.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util_mac.h" @@ -32,8 +33,8 @@ } - (CrURL*)URL { - return (_followedWebChannel.rssURL) ? _followedWebChannel.rssURL - : _followedWebChannel.webPageURL; + return (_followedWebChannel.rssURL.nsurl) ? _followedWebChannel.rssURL + : _followedWebChannel.webPageURL; } - (NSString*)thirdRowText {
diff --git a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.h b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.h index ca42599..facb52d0 100644 --- a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.h +++ b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.h
@@ -9,6 +9,8 @@ #include "ios/chrome/browser/discover_feed/feed_constants.h" +@protocol FeedControlDelegate; + // DO NOT CHANGE. Values are from enums.xml representing what could be broken in // the NTP view hierarchy. These values are persisted to logs. Entries should // not be renumbered and numeric values should never be reused. @@ -25,6 +27,40 @@ kMaxValue = 6, }; +// Enum class contains values indicating the type of follow request. Ex. +// kFollowRequestFollow means the user has sent a request to follow a website. +enum class FollowRequestType { + kFollowRequestFollow = 0, + kFollowRequestUnfollow = 1, + + // Change this to match max value. + kMaxValue = kFollowRequestUnfollow, +}; + +// Enum class contains values indicating the type of follow confirmation type. +// Ex. kFollowSucceedSnackbarShown means a confirmation is shown after the user +// has successfully followed a website. +enum class FollowConfirmationType { + kFollowSucceedSnackbarShown = 0, + kFollowErrorSnackbarShown = 1, + kUnfollowSucceedSnackbarShown = 2, + kUnfollowErrorSnackbarShown = 3, + + // Change this to match max value. + kMaxValue = kUnfollowErrorSnackbarShown, +}; + +// Enum class contains values indicating the type of snackbar action button. +enum class FollowSnackbarActionType { + kSnackbarActionGoToFeed = 0, + kSnackbarActionUndo = 1, + kSnackbarActionRetryFollow = 2, + kSnackbarActionRetryUnfollow = 3, + + // Change this to match max value. + kMaxValue = kSnackbarActionRetryUnfollow, +}; + namespace base { class Time; } @@ -66,18 +102,6 @@ // management UI. - (void)recordHeaderMenuManageFollowingTapped; -// Record metrics for when the user swipes or taps to unfollow a web channel in -// the management UI. -- (void)recordManagementTappedUnfollow; - -// Record metrics for when the user taps "UNDO" on the successful unfollow -// confirmation snackbar in the management UI. -- (void)recordManagementTappedRefollowAfterUnfollowOnSnackbar; - -// Record metrics for when the user taps "Try Again" on the unfollow error -// confirmation snackbar in the management UI. -- (void)recordManagementTappedUnfollowTryAgainOnSnackbar; - // Record metrics for when the user toggles the feed visibility from the feed // header menu. - (void)recordDiscoverFeedVisibilityChanged:(BOOL)visible; @@ -190,8 +214,38 @@ lastRefreshTime: (base::Time)lastRefreshTime; -// The currently selected feed type in the NTP. -@property(nonatomic, assign) FeedType selectedFeedType; +#pragma mark - Follow + +// Record metrics for when the user request to follow/unfollow a website, +// according to |followRequestedType|. Ex. The user selects the 'Follow' item in +// the overflow menu. +- (void)recordFollowRequestedWithType:(FollowRequestType)followRequestType; + +// Record metrics for when the follow confirmation snckbar is shown, according +// to |followConfirmationType|. +- (void)recordFollowConfirmationShownWithType: + (FollowConfirmationType)followConfirmationType; + +// Record metrics for when the follow confirmation snckbar action is tapped, +// according to |followSnackbarActionType|.Ex. the user tapped "GO TO FEED" +// button on the follow succeed snackbar. +- (void)recordFollowSnackbarTappedWithAction: + (FollowSnackbarActionType)followSnackbarActionType; + +// Record metrics for when the user swipes or taps to unfollow a web channel in +// the management UI. +- (void)recordManagementTappedUnfollow; + +// Record metrics for when the user taps "UNDO" on the successful unfollow +// confirmation snackbar in the management UI. +- (void)recordManagementTappedRefollowAfterUnfollowOnSnackbar; + +// Record metrics for when the user taps "Try Again" on the unfollow error +// confirmation snackbar in the management UI. +- (void)recordManagementTappedUnfollowTryAgainOnSnackbar; + +// Delegate to get the currently selected feed. +@property(nonatomic, weak) id<FeedControlDelegate> feedControlDelegate; // Whether or not the feed is currently being shown on the Start Surface. @property(nonatomic, assign) BOOL isShownOnStartSurface;
diff --git a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm index 3a04790..68e8d09 100644 --- a/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm +++ b/ios/chrome/browser/ui/ntp/feed_metrics_recorder.mm
@@ -13,6 +13,7 @@ #import "base/time/time.h" #import "components/feed/core/v2/public/common_enums.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_metrics.h" +#import "ios/chrome/browser/ui/ntp/feed_control_delegate.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -148,6 +149,18 @@ const char kDiscoverFeedUserActionManageFollowingTapped[] = "ContentSuggestions.Feed.HeaderAction.ManageFollowing"; +// User action names for following operations. +const char kFollowRequested[] = "ContentSuggestions.Follow.FollowRequested"; +const char kUnfollowRequested[] = "ContentSuggestions.Follow.UnfollowRequested"; +const char kSnackbarGoToFeedButtonTapped[] = + "ContentSuggestions.Follow.SnackbarGoToFeedButtonTapped"; +const char kSnackbarUndoButtonTapped[] = + "ContentSuggestions.Follow.SnackbarUndoButtonTapped"; +const char kSnackbarRetryFollowButtonTapped[] = + "ContentSuggestions.Follow.SnackbarRetryFollowButtonTapped"; +const char kSnackbarRetryUnfollowButtonTapped[] = + "ContentSuggestions.Follow.SnackbarRetryUnfollowButtonTapped"; + // User action names for management surface. const char kDiscoverFeedUserActionManagementTappedUnfollow[] = "ContentSuggestions.Feed.Management.TappedUnfollow"; @@ -177,14 +190,22 @@ const char kAllFeedsEngagementTypeHistogram[] = "ContentSuggestions.Feed.AllFeeds.EngagementType"; -// Histogram name for a feed card shown at index. +// Histogram name for a Discover feed card shown at index. const char kDiscoverFeedCardShownAtIndex[] = "NewTabPage.ContentSuggestions.Shown"; -// Histogram name for a feed card tapped at index. +// Histogram name for a Following feed card shown at index. +const char kFollowingFeedCardShownAtIndex[] = + "ContentSuggestions.Feed.WebFeed.Shown"; + +// Histogram name for a Discover feed card tapped at index. const char kDiscoverFeedCardOpenedAtIndex[] = "NewTabPage.ContentSuggestions.Opened"; +// Histogram name for a Following feed card tapped at index. +const char kFollowingFeedCardOpenedAtIndex[] = + "ContentSuggestions.Feed.WebFeed.Opened"; + // Histogram name to capture Feed Notice card impressions. const char kDiscoverFeedNoticeCardFulfilled[] = "ContentSuggestions.Feed.NoticeCardFulfilled2"; @@ -288,7 +309,7 @@ } // Log scrolled into Discover feed. - if (self.selectedFeedType == FeedTypeDiscover && + if ([self.feedControlDelegate selectedFeed] == FeedTypeDiscover && !self.scrolledReportedDiscover) { UMA_HISTOGRAM_ENUMERATION(kDiscoverFeedEngagementTypeHistogram, FeedEngagementType::kFeedScrolled); @@ -296,7 +317,7 @@ } // Log scrolled into Following feed. - if (self.selectedFeedType == FeedTypeFollowing && + if ([self.feedControlDelegate selectedFeed] == FeedTypeFollowing && !self.scrolledReportedFollowing) { UMA_HISTOGRAM_ENUMERATION(kFollowingFeedEngagementTypeHistogram, FeedEngagementType::kFeedScrolled); @@ -364,27 +385,6 @@ base::UserMetricsAction(kDiscoverFeedUserActionManageFollowingTapped)); } -- (void)recordManagementTappedUnfollow { - [self recordDiscoverFeedUserActionHistogram: - FeedUserActionType::kTappedUnfollowOnManagementSurface]; - base::RecordAction( - base::UserMetricsAction(kDiscoverFeedUserActionManagementTappedUnfollow)); -} - -- (void)recordManagementTappedRefollowAfterUnfollowOnSnackbar { - [self recordDiscoverFeedUserActionHistogram: - FeedUserActionType::kTappedRefollowAfterUnfollowOnSnackbar]; - base::RecordAction(base::UserMetricsAction( - kDiscoverFeedUserActionManagementTappedRefollowAfterUnfollowOnSnackbar)); -} - -- (void)recordManagementTappedUnfollowTryAgainOnSnackbar { - [self recordDiscoverFeedUserActionHistogram: - FeedUserActionType::kTappedUnfollowTryAgainOnSnackbar]; - base::RecordAction(base::UserMetricsAction( - kDiscoverFeedUserActionManagementTappedUnfollowTryAgainOnSnackbar)); -} - - (void)recordDiscoverFeedVisibilityChanged:(BOOL)visible { if (visible) { [self recordDiscoverFeedUserActionHistogram:FeedUserActionType:: @@ -496,13 +496,27 @@ } - (void)recordCardShownAtIndex:(int)index { - UMA_HISTOGRAM_EXACT_LINEAR(kDiscoverFeedCardShownAtIndex, index, - kMaxCardsInFeed); + switch ([self.feedControlDelegate selectedFeed]) { + case FeedTypeDiscover: + UMA_HISTOGRAM_EXACT_LINEAR(kDiscoverFeedCardShownAtIndex, index, + kMaxCardsInFeed); + break; + case FeedTypeFollowing: + UMA_HISTOGRAM_EXACT_LINEAR(kFollowingFeedCardShownAtIndex, index, + kMaxCardsInFeed); + } } - (void)recordCardTappedAtIndex:(int)index { - UMA_HISTOGRAM_EXACT_LINEAR(kDiscoverFeedCardOpenedAtIndex, index, - kMaxCardsInFeed); + switch ([self.feedControlDelegate selectedFeed]) { + case FeedTypeDiscover: + UMA_HISTOGRAM_EXACT_LINEAR(kDiscoverFeedCardOpenedAtIndex, index, + kMaxCardsInFeed); + break; + case FeedTypeFollowing: + UMA_HISTOGRAM_EXACT_LINEAR(kFollowingFeedCardOpenedAtIndex, index, + kMaxCardsInFeed); + } } - (void)recordNoticeCardShown:(BOOL)shown { @@ -608,6 +622,75 @@ base::UmaHistogramEnumeration(kFeedUserSettingsOnStart, settings); } +#pragma mark - Follow + +- (void)recordFollowRequestedWithType:(FollowRequestType)followRequestType { + // TODO(crbug.com/1324452): Record histogram. + switch (followRequestType) { + case FollowRequestType::kFollowRequestFollow: + base::RecordAction(base::UserMetricsAction(kFollowRequested)); + break; + case FollowRequestType::kFollowRequestUnfollow: + base::RecordAction(base::UserMetricsAction(kUnfollowRequested)); + break; + } +} + +- (void)recordFollowConfirmationShownWithType: + (FollowConfirmationType)followConfirmationType { + // TODO(crbug.com/1324452): Record histogram. + switch (followConfirmationType) { + case FollowConfirmationType::kFollowSucceedSnackbarShown: + case FollowConfirmationType::kFollowErrorSnackbarShown: + case FollowConfirmationType::kUnfollowSucceedSnackbarShown: + case FollowConfirmationType::kUnfollowErrorSnackbarShown: + break; + } +} + +- (void)recordFollowSnackbarTappedWithAction: + (FollowSnackbarActionType)followSnackbarActionType { + // TODO(crbug.com/1324452): Record histogram. + switch (followSnackbarActionType) { + case FollowSnackbarActionType::kSnackbarActionGoToFeed: + base::RecordAction( + base::UserMetricsAction(kSnackbarGoToFeedButtonTapped)); + break; + case FollowSnackbarActionType::kSnackbarActionUndo: + base::RecordAction(base::UserMetricsAction(kSnackbarUndoButtonTapped)); + break; + case FollowSnackbarActionType::kSnackbarActionRetryFollow: + base::RecordAction( + base::UserMetricsAction(kSnackbarRetryFollowButtonTapped)); + break; + case FollowSnackbarActionType::kSnackbarActionRetryUnfollow: + base::RecordAction( + base::UserMetricsAction(kSnackbarRetryUnfollowButtonTapped)); + break; + } +} + +- (void)recordManagementTappedUnfollow { + [self recordDiscoverFeedUserActionHistogram: + FeedUserActionType::kTappedUnfollowOnManagementSurface]; + base::RecordAction( + base::UserMetricsAction(kDiscoverFeedUserActionManagementTappedUnfollow)); +} + +- (void)recordManagementTappedRefollowAfterUnfollowOnSnackbar { + [self recordDiscoverFeedUserActionHistogram: + FeedUserActionType::kTappedRefollowAfterUnfollowOnSnackbar]; + base::RecordAction(base::UserMetricsAction( + kDiscoverFeedUserActionManagementTappedRefollowAfterUnfollowOnSnackbar)); +} + +- (void)recordManagementTappedUnfollowTryAgainOnSnackbar { + [self recordDiscoverFeedUserActionHistogram: + FeedUserActionType::kTappedUnfollowTryAgainOnSnackbar]; + base::RecordAction(base::UserMetricsAction( + kDiscoverFeedUserActionManagementTappedUnfollowTryAgainOnSnackbar)); +} + #pragma mark - Private // Returns the UserSettingsOnStart value based on the user settings. @@ -687,19 +770,19 @@ FeedEngagementType::kFeedInteracted); // Log interaction for Discover feed. - if (self.selectedFeedType == FeedTypeDiscover) { + if ([self.feedControlDelegate selectedFeed] == FeedTypeDiscover) { UMA_HISTOGRAM_ENUMERATION(kDiscoverFeedEngagementTypeHistogram, FeedEngagementType::kFeedInteracted); } // Log interaction for Following feed. - if (self.selectedFeedType == FeedTypeFollowing) { + if ([self.feedControlDelegate selectedFeed] == FeedTypeFollowing) { UMA_HISTOGRAM_ENUMERATION(kFollowingFeedEngagementTypeHistogram, FeedEngagementType::kFeedInteracted); } } -// Records simple engagement for the current |selectedFeedType|. +// Records simple engagement for the current |selectedFeed|. - (void)recordEngagedSimple { // If neither feed has been engaged with, log "AllFeeds" simple engagement. if (!self.engagedSimpleReportedDiscover && @@ -709,7 +792,7 @@ } // Log simple engagment for Discover feed. - if (self.selectedFeedType == FeedTypeDiscover && + if ([self.feedControlDelegate selectedFeed] == FeedTypeDiscover && !self.engagedSimpleReportedDiscover) { UMA_HISTOGRAM_ENUMERATION(kDiscoverFeedEngagementTypeHistogram, FeedEngagementType::kFeedEngagedSimple); @@ -717,7 +800,7 @@ } // Log simple engagement for Following feed. - if (self.selectedFeedType == FeedTypeFollowing && + if ([self.feedControlDelegate selectedFeed] == FeedTypeFollowing && !self.engagedSimpleReportedFollowing) { UMA_HISTOGRAM_ENUMERATION(kFollowingFeedEngagementTypeHistogram, FeedEngagementType::kFeedEngagedSimple); @@ -725,7 +808,7 @@ } } -// Records engagement for the current |selectedFeedType|. +// Records engagement for the currently selected feed. - (void)recordEngaged { // If neither feed has been engaged with, log "AllFeeds" engagement. if (!self.engagedReportedDiscover && !self.engagedReportedFollowing) { @@ -734,7 +817,7 @@ } // Log engagment for Discover feed. - if (self.selectedFeedType == FeedTypeDiscover && + if ([self.feedControlDelegate selectedFeed] == FeedTypeDiscover && !self.engagedReportedDiscover) { UMA_HISTOGRAM_ENUMERATION(kDiscoverFeedEngagementTypeHistogram, FeedEngagementType::kFeedEngaged); @@ -742,7 +825,7 @@ } // Log engagement for Following feed. - if (self.selectedFeedType == FeedTypeFollowing && + if ([self.feedControlDelegate selectedFeed] == FeedTypeFollowing && !self.engagedReportedFollowing) { UMA_HISTOGRAM_ENUMERATION(kFollowingFeedEngagementTypeHistogram, FeedEngagementType::kFeedEngaged);
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm index 730405f..195a655 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -75,6 +75,7 @@ #import "ios/chrome/browser/voice/voice_search_availability.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" #import "ios/chrome/grit/ios_strings.h" +#import "ios/public/provider/chrome/browser/follow/follow_provider.h" #import "ios/public/provider/chrome/browser/ui_utils/ui_utils_api.h" #import "ios/web/public/navigation/navigation_context.h" #import "ios/web/public/navigation/navigation_item.h" @@ -276,7 +277,7 @@ self, self.discoverFeedService); self.feedMetricsRecorder = self.discoverFeedService->GetFeedMetricsRecorder(); - self.feedMetricsRecorder.selectedFeedType = self.selectedFeed; + self.feedMetricsRecorder.feedControlDelegate = self; if (IsContentSuggestionsHeaderMigrationEnabled()) { self.headerController = @@ -580,8 +581,12 @@ - (void)updateFollowingFeedHasUnseenContent:(BOOL)hasUnseenContent { DCHECK(IsWebChannelsEnabled()); - [self.feedHeaderViewController - updateFollowingSegmentDotForUnseenContent:hasUnseenContent]; + if (ios::GetChromeBrowserProvider() + .GetFollowProvider() + ->DoesFollowingFeedHaveContent()) { + [self.feedHeaderViewController + updateFollowingSegmentDotForUnseenContent:hasUnseenContent]; + } } - (void)ntpDidChangeVisibility:(BOOL)visible { @@ -595,6 +600,7 @@ self.feedHeaderViewController.followingFeedSortType = (FollowingFeedSortType)self.prefService->GetInteger( prefs::kNTPFollowingFeedSortType); + self.feedMetricsRecorder.feedControlDelegate = self; } } } @@ -1160,12 +1166,17 @@ - (FeedHeaderViewController*)feedHeaderViewController { DCHECK(!self.browser->GetBrowserState()->IsOffTheRecord()); if (!_feedHeaderViewController) { + // Only show the dot if the user follows available publishers. + BOOL followingSegmentDotVisible = + ios::GetChromeBrowserProvider() + .GetFollowProvider() + ->DoesFollowingFeedHaveContent() && + self.discoverFeedService->GetFollowingFeedHasUnseenContent(); _feedHeaderViewController = [[FeedHeaderViewController alloc] initWithFollowingFeedSortType:(FollowingFeedSortType) self.prefService->GetInteger( prefs::kNTPFollowingFeedSortType) - followingSegmentDotVisible:self.discoverFeedService - ->GetFollowingFeedHasUnseenContent()]; + followingSegmentDotVisible:followingSegmentDotVisible]; _feedHeaderViewController.feedControlDelegate = self; _feedHeaderViewController.ntpDelegate = self; [_feedHeaderViewController.menuButton @@ -1176,13 +1187,6 @@ return _feedHeaderViewController; } -#pragma mark - Setters - -- (void)setSelectedFeed:(FeedType)selectedFeed { - _selectedFeed = selectedFeed; - self.feedMetricsRecorder.selectedFeedType = selectedFeed; -} - #pragma mark - DiscoverFeedWrapperViewControllerDelegate - (void)updateTheme {
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm index 492992c..8d45b59 100644 --- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm +++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
@@ -477,42 +477,6 @@ [weakSelf openSiteInformation]; }); - if (UseSymbols()) { - self.reloadAction = - CreateOverflowMenuAction(IDS_IOS_TOOLS_MENU_RELOAD, - kArrowClockWiseSymbol, NO, kToolsMenuReload, ^{ - [weakSelf reload]; - }); - } else { - self.reloadAction = CreateOverflowMenuAction(IDS_IOS_TOOLS_MENU_RELOAD, - @"overflow_menu_action_reload", - kToolsMenuReload, ^{ - [weakSelf reload]; - }); - } - - self.stopLoadAction = CreateOverflowMenuAction( - IDS_IOS_TOOLS_MENU_STOP, @"overflow_menu_action_stop", kToolsMenuStop, ^{ - [weakSelf stopLoading]; - }); - - self.openTabAction = CreateOverflowMenuAction(IDS_IOS_TOOLS_MENU_NEW_TAB, - @"overflow_menu_action_new_tab", - kToolsMenuNewTabId, ^{ - [weakSelf openTab]; - }); - self.openIncognitoTabAction = CreateOverflowMenuAction( - IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB, @"overflow_menu_action_incognito", - kToolsMenuNewIncognitoTabId, ^{ - [weakSelf openIncognitoTab]; - }); - - self.openNewWindowAction = CreateOverflowMenuAction( - IDS_IOS_TOOLS_MENU_NEW_WINDOW, @"overflow_menu_action_new_window", - kToolsMenuNewWindowId, ^{ - [weakSelf openNewWindow]; - }); - [self logTranslateAvailability]; if (UseSymbols()) { @@ -545,6 +509,12 @@ [weakSelf openNewWindow]; }); + self.clearBrowsingDataAction = CreateOverflowMenuAction( + IDS_IOS_TOOLS_MENU_CLEAR_BROWSING_DATA, kTrashSymbol, YES, + kToolsMenuClearBrowsingData, ^{ + [weakSelf openClearBrowsingData]; + }); + if (!self.isIncognito && IsWebChannelsEnabled() && GetFollowActionState(self.webState) != FollowActionStateHidden) { DCHECK(UseSymbols()); @@ -665,6 +635,13 @@ [weakSelf openNewWindow]; }); + self.clearBrowsingDataAction = + CreateOverflowMenuAction(IDS_IOS_TOOLS_MENU_CLEAR_BROWSING_DATA, + @"overflow_menu_action_clear_browsing_data", + kToolsMenuClearBrowsingData, ^{ + [weakSelf openClearBrowsingData]; + }); + if (!self.isIncognito && IsWebChannelsEnabled() && GetFollowActionState(self.webState) != FollowActionStateHidden) { NSString* name = l10n_util::GetNSStringF(IDS_IOS_TOOLS_MENU_FOLLOW, @@ -1150,11 +1127,15 @@ - (void)updateFollowMenuItemWithFollowWebPageURLs: (FollowWebPageURLs*)webPageURLs status:(BOOL)status - title:(NSString*)title + domainName:(NSString*)domainName enabled:(BOOL)enable { DCHECK(IsWebChannelsEnabled()); self.followAction.enabled = enable; - self.followAction.name = title; + self.followAction.name = + status ? l10n_util::GetNSStringF(IDS_IOS_TOOLS_MENU_UNFOLLOW, + base::SysNSStringToUTF16(domainName)) + : l10n_util::GetNSStringF(IDS_IOS_TOOLS_MENU_FOLLOW, + base::SysNSStringToUTF16(domainName)); self.followAction.uiImage = [UIImage imageNamed:status ? @"popup_menu_unfollow" : @"popup_menu_follow"]; __weak __typeof(self) weakSelf = self;
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm index 981e2709..567a107 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
@@ -683,13 +683,17 @@ - (void)updateFollowMenuItemWithFollowWebPageURLs: (FollowWebPageURLs*)webPageURLs status:(BOOL)status - title:(NSString*)title + domainName:(NSString*)domainName enabled:(BOOL)enabled { DCHECK(IsWebChannelsEnabled()); self.webPageURLs = webPageURLs; self.followStatus = status; self.followItem.enabled = enabled; - self.followItem.title = title; + self.followItem.title = + status ? l10n_util::GetNSStringF(IDS_IOS_TOOLS_MENU_UNFOLLOW, + base::SysNSStringToUTF16(@"")) + : l10n_util::GetNSStringF(IDS_IOS_TOOLS_MENU_FOLLOW, + base::SysNSStringToUTF16(@"")); self.followItem.image = [[UIImage imageNamed:self.followStatus ? @"popup_menu_unfollow" : @"popup_menu_follow"]
diff --git a/ios/chrome/browser/ui/util/layout_guide_center.swift b/ios/chrome/browser/ui/util/layout_guide_center.swift index dc647a83..e31f87f7 100644 --- a/ios/chrome/browser/ui/util/layout_guide_center.swift +++ b/ios/chrome/browser/ui/util/layout_guide_center.swift
@@ -70,8 +70,8 @@ for layoutGuide in layoutGuidesForName.allObjects { // Skip if there is no owning window. - guard let owningView = layoutGuide.owningView else { break } - guard let owningWindow = owningView.window else { break } + guard let owningView = layoutGuide.owningView else { continue } + guard let owningWindow = owningView.window else { continue } let frameInReferenceWindow = referenceView.convert(referenceView.bounds, to: nil) let frameInOwningWindow = referenceWindow.convert(frameInReferenceWindow, to: owningWindow)
diff --git a/ios/chrome/browser/ui/webui/policy/policy_ui_handler.h b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.h index 7c93d0f..11dbd93 100644 --- a/ios/chrome/browser/ui/webui/policy/policy_ui_handler.h +++ b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.h
@@ -49,9 +49,9 @@ // Returns a dictionary containing the policies supported by Chrome. base::Value GetPolicyNames() const; - // Returns a dictionary containing the current values of the policies + // Returns an array containing the current values of the policies // supported by Chrome. - base::Value GetPolicyValues() const; + base::Value::List GetPolicyValues() const; // Called to handle the "listenPoliciesUpdates" WebUI message. void HandleListenPoliciesUpdates(const base::Value::List& args);
diff --git a/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm index 6c376f979..e3af1422a 100644 --- a/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm +++ b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm
@@ -203,12 +203,12 @@ return names; } -base::Value PolicyUIHandler::GetPolicyValues() const { +base::Value::List PolicyUIHandler::GetPolicyValues() const { auto client = std::make_unique<PolicyConversionsClientIOS>( ChromeBrowserState::FromWebUIIOS(web_ui())); return policy::ArrayPolicyConversions(std::move(client)) .EnableConvertValues(true) - .ToValue(); + .ToValueList(); } void PolicyUIHandler::HandleListenPoliciesUpdates( @@ -223,7 +223,7 @@ void PolicyUIHandler::SendPolicies() { base::Value names = GetPolicyNames(); - base::Value values = GetPolicyValues(); + base::Value values = base::Value(GetPolicyValues()); std::vector<const base::Value*> args; args.push_back(&names); args.push_back(&values);
diff --git a/ios/chrome/browser/ui/webui/translate_internals/ios_translate_internals_handler.h b/ios/chrome/browser/ui/webui/translate_internals/ios_translate_internals_handler.h index f879245..1674609 100644 --- a/ios/chrome/browser/ui/webui/translate_internals/ios_translate_internals_handler.h +++ b/ios/chrome/browser/ui/webui/translate_internals/ios_translate_internals_handler.h
@@ -38,9 +38,6 @@ variations::VariationsService* GetVariationsService() override; void RegisterMessageCallback(const std::string& message, MessageCallback callback) override; - void RegisterDeprecatedMessageCallback( - const std::string& message, - const DeprecatedMessageCallback& callback) override; void CallJavascriptFunction( const std::string& function_name, const std::vector<const base::Value*>& args) override;
diff --git a/ios/chrome/browser/ui/webui/translate_internals/ios_translate_internals_handler.mm b/ios/chrome/browser/ui/webui/translate_internals/ios_translate_internals_handler.mm index 5423907..b36c644 100644 --- a/ios/chrome/browser/ui/webui/translate_internals/ios_translate_internals_handler.mm +++ b/ios/chrome/browser/ui/webui/translate_internals/ios_translate_internals_handler.mm
@@ -38,12 +38,6 @@ web_ui()->RegisterMessageCallback(message, std::move(callback)); } -void IOSTranslateInternalsHandler::RegisterDeprecatedMessageCallback( - const std::string& message, - const DeprecatedMessageCallback& callback) { - web_ui()->RegisterDeprecatedMessageCallback(message, callback); -} - void IOSTranslateInternalsHandler::CallJavascriptFunction( const std::string& function_name, const std::vector<const base::Value*>& args) {
diff --git a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h index f2a5f3dc..12c1d55 100644 --- a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h +++ b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h
@@ -48,7 +48,7 @@ // The text for the tertiary action. Must be set before the view is loaded. @property(nonatomic, copy) NSString* tertiaryActionString; -// The image. Must be set before the view is loaded. +// The image. May be updated after the view is loaded. @property(nonatomic, strong) UIImage* image; // Sets the custom spacing between the top and the image, if there is no
diff --git a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm index f99c760..73068ca 100644 --- a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm +++ b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm
@@ -418,6 +418,11 @@ return topToolbar; } +- (void)setImage:(UIImage*)image { + _image = image; + _imageView.image = image; +} + // Helper to create the image view. - (UIImageView*)createImageView { UIImageView* imageView = [[UIImageView alloc] initWithImage:self.image];
diff --git a/ios/public/provider/chrome/browser/follow/follow_provider.h b/ios/public/provider/chrome/browser/follow/follow_provider.h index 1f4d2ec9..ae6f91c 100644 --- a/ios/public/provider/chrome/browser/follow/follow_provider.h +++ b/ios/public/provider/chrome/browser/follow/follow_provider.h
@@ -53,6 +53,9 @@ // management UI. virtual void RemoveFollowManagementUIUpdater( id<FollowManagementUIUpdater> follow_management_ui_updater); + + // Whether the user follows any publishers that have available content. + virtual bool DoesFollowingFeedHaveContent(); }; #endif // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_FOLLOW_FOLLOW_PROVIDER_H_
diff --git a/ios/public/provider/chrome/browser/follow/follow_provider.mm b/ios/public/provider/chrome/browser/follow/follow_provider.mm index 8906c0a..4ee9511 100644 --- a/ios/public/provider/chrome/browser/follow/follow_provider.mm +++ b/ios/public/provider/chrome/browser/follow/follow_provider.mm
@@ -31,3 +31,7 @@ void FollowProvider::RemoveFollowManagementUIUpdater( id<FollowManagementUIUpdater> follow_management_ui_updater) {} + +bool FollowProvider::DoesFollowingFeedHaveContent() { + return false; +}
diff --git a/ios/showcase/follow/sc_follow_view_controller.mm b/ios/showcase/follow/sc_follow_view_controller.mm index 5e1da3e..59af921 100644 --- a/ios/showcase/follow/sc_follow_view_controller.mm +++ b/ios/showcase/follow/sc_follow_view_controller.mm
@@ -7,7 +7,6 @@ #import "ios/chrome/browser/net/crurl.h" #import "ios/chrome/browser/ui/follow/first_follow_favicon_data_source.h" #import "ios/chrome/browser/ui/follow/first_follow_view_controller.h" -#import "ios/chrome/browser/ui/follow/first_follow_view_delegate.h" #import "ios/chrome/browser/ui/follow/follow_block_types.h" #import "ios/chrome/browser/ui/follow/followed_web_channel.h" #import "ios/chrome/browser/ui/icons/chrome_symbol.h" @@ -64,8 +63,7 @@ self.alerter = [[ProtocolAlerter alloc] initWithProtocols:@[ @protocol(FeedManagementFollowDelegate), - @protocol(FeedManagementNavigationDelegate), - @protocol(FirstFollowViewDelegate) + @protocol(FeedManagementNavigationDelegate) ]]; UIButton* button1 = [[UIButton alloc] init]; @@ -144,8 +142,6 @@ firstFollowViewController.followedWebChannel = ch1; self.alerter.baseViewController = firstFollowViewController; - firstFollowViewController.delegate = - static_cast<id<FirstFollowViewDelegate>>(self.alerter); firstFollowViewController.faviconDataSource = self; if (@available(iOS 15, *)) {
diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc index 39533246..15e3376 100644 --- a/media/base/supported_types.cc +++ b/media/base/supported_types.cc
@@ -41,7 +41,6 @@ public: void UpdateCache(const base::flat_set<media::VideoCodecProfile>& profiles) { base::AutoLock lock(profiles_lock_); - DCHECK_EQ(profiles_.size(), 0u); profiles_ = profiles; } bool IsProfileSupported(media::VideoCodecProfile profile) {
diff --git a/media/gpu/android/video_frame_factory_impl_unittest.cc b/media/gpu/android/video_frame_factory_impl_unittest.cc index ce63719..168f4045 100644 --- a/media/gpu/android/video_frame_factory_impl_unittest.cc +++ b/media/gpu/android/video_frame_factory_impl_unittest.cc
@@ -87,7 +87,7 @@ gfx::Size coded_size{100, 100}; gfx::Rect visible_rect{coded_size}; gfx::Size natural_size{coded_size}; - gfx::ColorSpace color_space{gfx::ColorSpace::CreateSCRGBLinear()}; + gfx::ColorSpace color_space{gfx::ColorSpace::CreateSRGBLinear()}; } video_frame_params_; void RequestVideoFrame() {
diff --git a/media/gpu/windows/d3d11_copying_texture_wrapper_unittest.cc b/media/gpu/windows/d3d11_copying_texture_wrapper_unittest.cc index 3a35a43d..db1a84a 100644 --- a/media/gpu/windows/d3d11_copying_texture_wrapper_unittest.cc +++ b/media/gpu/windows/d3d11_copying_texture_wrapper_unittest.cc
@@ -239,7 +239,7 @@ // TODO: check |gpu_task_runner_|. MailboxHolderArray mailboxes; - gfx::ColorSpace input_color_space = gfx::ColorSpace::CreateSCRGBLinear(); + gfx::ColorSpace input_color_space = gfx::ColorSpace::CreateSRGBLinear(); gfx::ColorSpace output_color_space; EXPECT_EQ(wrapper ->Init(gpu_task_runner_, CreateMockHelperCB(), @@ -292,7 +292,7 @@ MockVideoProcessorProxy* processor_raw = processor.get(); auto wrapper = std::make_unique<CopyingTexture2DWrapper>( gfx::Size(100, 200), ExpectTextureWrapper(), std::move(processor), - nullptr, gfx::ColorSpace::CreateSCRGBLinear()); + nullptr, gfx::ColorSpace::CreateSRGBLinear()); const DXGI_HDR_METADATA_HDR10 dxgi_metadata = gl::HDRMetadataHelperWin::HDRMetadataToDXGI(metadata);
diff --git a/media/renderers/win/media_foundation_stream_wrapper.cc b/media/renderers/win/media_foundation_stream_wrapper.cc index 3704aa1..0d42185 100644 --- a/media/renderers/win/media_foundation_stream_wrapper.cc +++ b/media/renderers/win/media_foundation_stream_wrapper.cc
@@ -326,6 +326,8 @@ if (buffer->end_of_stream()) { if (!enabled_) { DVLOG_FUNC(2) << "Ignoring EOS for disabled stream"; + // token not dropped to reflect an outstanding request that stream wrapper + // should service when the stream is enabled return S_OK; } DVLOG_FUNC(2) << "End of stream"; @@ -348,6 +350,9 @@ RETURN_IF_FAILED(mf_media_event_queue_->QueueEventParamUnk( MEMediaSample, GUID_NULL, S_OK, mf_sample.Get())); } + + pending_sample_request_tokens_.pop(); + return S_OK; } @@ -417,7 +422,6 @@ << ": ServiceSampleRequest failed: " << PrintHr(hr); return; } - pending_sample_request_tokens_.pop(); } } else if (status == DemuxerStream::Status::kConfigChanged) { DVLOG_FUNC(2) << "Stream config changed, AreFormatChangesEnabled="
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc index b30df42b2..677a604 100644 --- a/net/http/transport_security_state_unittest.cc +++ b/net/http/transport_security_state_unittest.cc
@@ -4095,7 +4095,13 @@ network_isolation_key, &unused_failure_log)); } -TEST_F(TransportSecurityStateTest, UpdateKeyPinsListTimestamp) { +// crbug.com/1325054 Broken on Android +#if BUILDFLAG(IS_ANDROID) +#define MAYBE_UpdateKeyPinsListTimestamp DISABLED_UpdateKeyPinsListTimestamp +#else +#define MAYBE_UpdateKeyPinsListTimestamp UpdateKeyPinsListTimestamp +#endif +TEST_F(TransportSecurityStateTest, MAYBE_UpdateKeyPinsListTimestamp) { base::test::ScopedFeatureList scoped_feature_list_; scoped_feature_list_.InitAndEnableFeature( net::features::kStaticKeyPinningEnforcement);
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc index 3185f32..ebc03e1 100644 --- a/net/quic/quic_chromium_client_session_test.cc +++ b/net/quic/quic_chromium_client_session_test.cc
@@ -1883,7 +1883,16 @@ /*require_dns_https_alpn=*/false))); } -TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) { +// crbug.com/1325054 Broken on Android +#if BUILDFLAG(IS_ANDROID) +#define MAYBE_ConnectionNotPooledWithDifferentPin \ + DISABLED_ConnectionNotPooledWithDifferentPin +#else +#define MAYBE_ConnectionNotPooledWithDifferentPin \ + ConnectionNotPooledWithDifferentPin +#endif +TEST_P(QuicChromiumClientSessionTest, + MAYBE_ConnectionNotPooledWithDifferentPin) { base::test::ScopedFeatureList scoped_feature_list_; scoped_feature_list_.InitAndEnableFeature( net::features::kStaticKeyPinningEnforcement);
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index 1151c34..e5da391 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc
@@ -1958,7 +1958,14 @@ EXPECT_TRUE(socket_data.AllWriteDataConsumed()); } -TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) { +// crbug.com/1325054 Broken on Android +#if BUILDFLAG(IS_ANDROID) +#define MAYBE_NoHttpsPoolingWithDifferentPins \ + DISABLED_NoHttpsPoolingWithDifferentPins +#else +#define MAYBE_NoHttpsPoolingWithDifferentPins NoHttpsPoolingWithDifferentPins +#endif +TEST_P(QuicStreamFactoryTest, MAYBE_NoHttpsPoolingWithDifferentPins) { base::test::ScopedFeatureList scoped_feature_list_; scoped_feature_list_.InitAndEnableFeature( net::features::kStaticKeyPinningEnforcement);
diff --git a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_logging_impl.h b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_logging_impl.h index dbc02b0..86cf957 100644 --- a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_logging_impl.h +++ b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_logging_impl.h
@@ -12,6 +12,7 @@ #include "base/notreached.h" #include "build/build_config.h" #include "quiche/common/platform/api/quiche_export.h" +#include "third_party/abseil-cpp/absl/base/optimization.h" #define QUICHE_LOG_IMPL(severity) QUICHE_CHROMIUM_LOG_##severity #define QUICHE_VLOG_IMPL(verbose_level) VLOG(verbose_level) @@ -72,8 +73,8 @@ #define QUICHE_CHROMIUM_DLOG_IF_0 QUICHE_CHROMIUM_DLOG_IF_ERROR #endif -#define QUICHE_PREDICT_FALSE_IMPL(x) x -#define QUICHE_PREDICT_TRUE_IMPL(x) x +#define QUICHE_PREDICT_FALSE_IMPL(x) ABSL_PREDICT_FALSE(x) +#define QUICHE_PREDICT_TRUE_IMPL(x) ABSL_PREDICT_TRUE(x) #define QUICHE_NOTREACHED_IMPL() NOTREACHED()
diff --git a/pdf/BUILD.gn b/pdf/BUILD.gn index d63d93ce..835c379f 100644 --- a/pdf/BUILD.gn +++ b/pdf/BUILD.gn
@@ -333,7 +333,7 @@ } if (is_linux || is_chromeos) { - # TODO(crbug.com/702993): After PPAPI deprecation, there will only be one + # TODO(crbug.com/1302059): After PPAPI deprecation, there will only be one # caller left. Move inside the file with the caller. static_library("font_table_linux") { sources = [ "font_table_linux.cc" ]
diff --git a/pdf/pdf_view_plugin_base.cc b/pdf/pdf_view_plugin_base.cc index 829359f..d1772973 100644 --- a/pdf/pdf_view_plugin_base.cc +++ b/pdf/pdf_view_plugin_base.cc
@@ -575,7 +575,8 @@ {"selectAll", &PdfViewPluginBase::HandleSelectAllMessage}, {"setBackgroundColor", &PdfViewPluginBase::HandleSetBackgroundColorMessage}, - {"setReadOnly", &PdfViewPluginBase::HandleSetReadOnlyMessage}, + {"setPresentationMode", + &PdfViewPluginBase::HandleSetPresentationModeMessage}, {"setTwoUpView", &PdfViewPluginBase::HandleSetTwoUpViewMessage}, {"stopScrolling", &PdfViewPluginBase::HandleStopScrollingMessage}, {"viewport", &PdfViewPluginBase::HandleViewportMessage}, @@ -1228,9 +1229,9 @@ base::checked_cast<SkColor>(message.FindDouble("color").value()); } -void PdfViewPluginBase::HandleSetReadOnlyMessage( +void PdfViewPluginBase::HandleSetPresentationModeMessage( const base::Value::Dict& message) { - engine()->SetReadOnly(message.FindBool("enableReadOnly").value()); + engine()->SetReadOnly(message.FindBool("enablePresentationMode").value()); } void PdfViewPluginBase::HandleSetTwoUpViewMessage(
diff --git a/pdf/pdf_view_plugin_base.h b/pdf/pdf_view_plugin_base.h index 55eea16..4a4abd4 100644 --- a/pdf/pdf_view_plugin_base.h +++ b/pdf/pdf_view_plugin_base.h
@@ -423,7 +423,7 @@ void HandleSaveAttachmentMessage(const base::Value::Dict& message); void HandleSelectAllMessage(const base::Value::Dict& /*message*/); void HandleSetBackgroundColorMessage(const base::Value::Dict& message); - void HandleSetReadOnlyMessage(const base::Value::Dict& message); + void HandleSetPresentationModeMessage(const base::Value::Dict& message); void HandleSetTwoUpViewMessage(const base::Value::Dict& message); void HandleStopScrollingMessage(const base::Value::Dict& /*message*/); void HandleViewportMessage(const base::Value::Dict& message);
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc index 0bf08342c..c9ce9bf 100644 --- a/pdf/pdf_view_web_plugin.cc +++ b/pdf/pdf_view_web_plugin.cc
@@ -520,7 +520,7 @@ blink::WebInputEventResult PdfViewWebPlugin::HandleInputEvent( const blink::WebCoalescedInputEvent& event, ui::Cursor* cursor) { - // TODO(crbug.com/702993): The input events received by the Pepper plugin + // TODO(crbug.com/1302059): The input events received by the Pepper plugin // already have the viewport-to-DIP scale applied. The scaling done here // should be moved into `PdfViewPluginBase::HandleInputEvent()` once the // Pepper plugin is removed.
diff --git a/printing/printing_context.cc b/printing/printing_context.cc index 8a8fcef..acffe19 100644 --- a/printing/printing_context.cc +++ b/printing/printing_context.cc
@@ -91,7 +91,7 @@ return result; } -mojom::ResultCode PrintingContext::UsePdfSettings() { +void PrintingContext::UsePdfSettings() { base::Value::Dict pdf_settings; pdf_settings.Set(kSettingHeaderFooterEnabled, false); pdf_settings.Set(kSettingShouldPrintBackgrounds, false); @@ -112,7 +112,17 @@ pdf_settings.Set(kSettingScaleFactor, 100); pdf_settings.Set(kSettingRasterizePdf, false); pdf_settings.Set(kSettingPagesPerSheet, 1); - return UpdatePrintSettings(std::move(pdf_settings)); + mojom::ResultCode result = UpdatePrintSettings(std::move(pdf_settings)); + // TODO(thestig): Downgrade these to DCHECKs after shipping these CHECKs to + // production without any failures. + CHECK_EQ(result, mojom::ResultCode::kSuccess); + // UsePdfSettings() should never fail and the returned DPI should always be a + // well-known value that is safe to use as a divisor. +#if BUILDFLAG(IS_MAC) + CHECK_EQ(settings_->device_units_per_inch(), kPointsPerInch); +#else + CHECK_EQ(settings_->device_units_per_inch(), kDefaultPdfDpi); +#endif } mojom::ResultCode PrintingContext::UpdatePrintSettings(
diff --git a/printing/printing_context.h b/printing/printing_context.h index 2c8ef23..58fcf619 100644 --- a/printing/printing_context.h +++ b/printing/printing_context.h
@@ -88,8 +88,9 @@ // default device settings. virtual mojom::ResultCode UseDefaultSettings() = 0; - // Updates the context with PDF printer settings. - mojom::ResultCode UsePdfSettings(); + // Updates the context with PDF printer settings. The PDF settings are + // guaranteed to be valid. + void UsePdfSettings(); // Returns paper size to be used for PDF or Cloud Print in device units. virtual gfx::Size GetPdfPaperSizeDeviceUnits() = 0;
diff --git a/remoting/codec/webrtc_video_encoder_gpu.cc b/remoting/codec/webrtc_video_encoder_gpu.cc index 44952401..1c98ac9 100644 --- a/remoting/codec/webrtc_video_encoder_gpu.cc +++ b/remoting/codec/webrtc_video_encoder_gpu.cc
@@ -38,6 +38,7 @@ #if BUILDFLAG(IS_WIN) #include "base/win/scoped_com_initializer.h" +#include "media/gpu/windows/media_foundation_video_encode_accelerator_win.h" #endif namespace { @@ -411,6 +412,9 @@ // H.264 and run the encoder on a different thread, we use a locally scoped // object for now. base::win::ScopedCOMInitializer scoped_com_initializer; + + // Ensure the required MF DLLs are loaded before we call into the VEA below. + media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization(); #endif media::VideoEncodeAccelerator::SupportedProfiles profiles =
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn index 89a56b1a..91896c3 100644 --- a/remoting/protocol/BUILD.gn +++ b/remoting/protocol/BUILD.gn
@@ -259,8 +259,8 @@ defines = [] - # Must match condition in //remoting/codec/BUILD.gn - if (is_win || is_linux || is_chromeos) { + # Must be a subset of the platforms built in //remoting/codec/BUILD.gn + if (is_win) { defines += [ "USE_H264_ENCODER" ] deps += [ "//media",
diff --git a/remoting/protocol/webrtc_video_encoder_factory.cc b/remoting/protocol/webrtc_video_encoder_factory.cc index 8e37c67..fc93a4d 100644 --- a/remoting/protocol/webrtc_video_encoder_factory.cc +++ b/remoting/protocol/webrtc_video_encoder_factory.cc
@@ -11,8 +11,11 @@ #include "third_party/webrtc/api/video_codecs/sdp_video_format.h" #include "third_party/webrtc/api/video_codecs/vp9_profile.h" -namespace remoting { -namespace protocol { +#if defined(USE_H264_ENCODER) +#include "remoting/codec/webrtc_video_encoder_gpu.h" +#endif + +namespace remoting::protocol { WebrtcVideoEncoderFactory::WebrtcVideoEncoderFactory() : main_task_runner_(base::ThreadTaskRunnerHandle::Get()) { @@ -21,7 +24,12 @@ formats_.push_back( webrtc::SdpVideoFormat("VP9", {{webrtc::kVP9FmtpProfileId, "1"}})); #if defined(USE_H264_ENCODER) - formats_.push_back(webrtc::SdpVideoFormat("H264")); + // This call will query the underlying media classes to determine whether + // hardware encoding is supported or not. We use a default resolution and + // framerate so the call doesn't fail due to invalid params. + if (WebrtcVideoEncoderGpu::IsSupportedByH264({{1920, 1080}, 30})) { + formats_.push_back(webrtc::SdpVideoFormat("H264")); + } #endif } @@ -45,5 +53,4 @@ video_channel_state_observer_ = video_channel_state_observer; } -} // namespace protocol -} // namespace remoting +} // namespace remoting::protocol
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 21d0e68..899fa1769 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5919,21 +5919,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5058.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5059.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5058.0", - "revision": "version:103.0.5058.0" + "location": "lacros_version_skew_tests_v103.0.5059.0", + "revision": "version:103.0.5059.0" } ], "dimension_sets": [ @@ -5945,7 +5945,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 103.0.5058.0" + "variant_id": "Lacros version skew testing ash 103.0.5059.0" }, { "args": [ @@ -6065,21 +6065,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5058.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5059.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5058.0", - "revision": "version:103.0.5058.0" + "location": "lacros_version_skew_tests_v103.0.5059.0", + "revision": "version:103.0.5059.0" } ], "dimension_sets": [ @@ -6091,7 +6091,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 103.0.5058.0" + "variant_id": "Lacros version skew testing ash 103.0.5059.0" }, { "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 729e88b1..37b8afc2 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -87922,28 +87922,28 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5058.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5059.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5058.0", - "revision": "version:103.0.5058.0" + "location": "lacros_version_skew_tests_v103.0.5059.0", + "revision": "version:103.0.5059.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 103.0.5058.0" + "variant_id": "Lacros version skew testing ash 103.0.5059.0" }, { "args": [ @@ -88043,28 +88043,28 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5058.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5059.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5058.0", - "revision": "version:103.0.5058.0" + "location": "lacros_version_skew_tests_v103.0.5059.0", + "revision": "version:103.0.5059.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 103.0.5058.0" + "variant_id": "Lacros version skew testing ash 103.0.5059.0" }, { "isolate_profile_data": true, @@ -89439,20 +89439,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5058.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5059.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5058.0", - "revision": "version:103.0.5058.0" + "location": "lacros_version_skew_tests_v103.0.5059.0", + "revision": "version:103.0.5059.0" } ], "dimension_sets": [ @@ -89465,7 +89465,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 103.0.5058.0" + "variant_id": "Lacros version skew testing ash 103.0.5059.0" }, { "args": [ @@ -89585,20 +89585,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5058.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5059.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5058.0", - "revision": "version:103.0.5058.0" + "location": "lacros_version_skew_tests_v103.0.5059.0", + "revision": "version:103.0.5059.0" } ], "dimension_sets": [ @@ -89611,7 +89611,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 103.0.5058.0" + "variant_id": "Lacros version skew testing ash 103.0.5059.0" }, { "merge": { @@ -91144,20 +91144,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5058.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5059.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5058.0", - "revision": "version:103.0.5058.0" + "location": "lacros_version_skew_tests_v103.0.5059.0", + "revision": "version:103.0.5059.0" } ], "dimension_sets": [ @@ -91170,7 +91170,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 103.0.5058.0" + "variant_id": "Lacros version skew testing ash 103.0.5059.0" }, { "args": [ @@ -91290,20 +91290,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5058.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5059.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5058.0", - "revision": "version:103.0.5058.0" + "location": "lacros_version_skew_tests_v103.0.5059.0", + "revision": "version:103.0.5059.0" } ], "dimension_sets": [ @@ -91316,7 +91316,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 103.0.5058.0" + "variant_id": "Lacros version skew testing ash 103.0.5059.0" }, { "merge": { @@ -92051,20 +92051,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5058.0", + "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5059.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v103.0.5058.0", - "revision": "version:103.0.5058.0" + "location": "lacros_version_skew_tests_v103.0.5059.0", + "revision": "version:103.0.5059.0" } ], "dimension_sets": [ @@ -92077,7 +92077,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 103.0.5058.0" + "variant_id": "Lacros version skew testing ash 103.0.5059.0" } ] },
diff --git a/testing/buildbot/chromium.swangle.json b/testing/buildbot/chromium.swangle.json index 3e2f5b2..429dce0 100644 --- a/testing/buildbot/chromium.swangle.json +++ b/testing/buildbot/chromium.swangle.json
@@ -42,432 +42,6 @@ } ] }, - "linux-swangle-tot-angle-x64": { - "gtest_tests": [ - { - "args": [ - "angle_deqp_egl_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_egl_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_egl_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles2_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles2_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles2_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_rotate180_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles31_rotate180_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_rotate180_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_rotate270_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles31_rotate270_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_rotate270_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_rotate90_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles31_rotate90_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_rotate90_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 - }, - "test": "angle_deqp_gles31_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_rotate180_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles3_rotate180_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_rotate180_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_rotate270_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles3_rotate270_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_rotate270_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_rotate90_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles3_rotate90_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_rotate90_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 - }, - "test": "angle_deqp_gles3_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_khr_gles2_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_khr_gles2_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_khr_gles2_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_khr_gles31_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_khr_gles31_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_khr_gles31_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_khr_gles3_tests", - "--use-angle=swiftshader", - "--bot-mode", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_khr_gles3_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_khr_gles3_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_end2end_tests", - "--bot-mode", - "--gtest_filter=*Vulkan_SwiftShader*", - "--xvfb" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Ubuntu-18.04", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_end2end_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_end2end_tests/", - "use_isolated_scripts_api": true - } - ] - }, "linux-swangle-tot-swiftshader-x64": { "gtest_tests": [ { @@ -1400,802 +974,6 @@ } ] }, - "win-swangle-tot-angle-x64": { - "gtest_tests": [ - { - "args": [ - "angle_deqp_egl_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_egl_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_egl_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles2_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles2_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles2_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_rotate180_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles31_rotate180_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_rotate180_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_rotate270_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles31_rotate270_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_rotate270_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_rotate90_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles31_rotate90_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_rotate90_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 - }, - "test": "angle_deqp_gles31_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_rotate180_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles3_rotate180_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_rotate180_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_rotate270_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles3_rotate270_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_rotate270_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_rotate90_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles3_rotate90_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_rotate90_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 - }, - "test": "angle_deqp_gles3_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_khr_gles2_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_khr_gles2_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_khr_gles2_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_khr_gles31_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_khr_gles31_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_khr_gles31_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_khr_gles3_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_khr_gles3_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_khr_gles3_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_end2end_tests", - "--bot-mode", - "--gtest_filter=*Vulkan_SwiftShader*" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_end2end_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_end2end_tests/", - "use_isolated_scripts_api": true - } - ] - }, - "win-swangle-tot-angle-x86": { - "gtest_tests": [ - { - "args": [ - "angle_deqp_egl_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_egl_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_egl_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles2_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles2_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles2_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_rotate180_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles31_rotate180_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_rotate180_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_rotate270_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles31_rotate270_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_rotate270_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_rotate90_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles31_rotate90_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_rotate90_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles31_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 - }, - "test": "angle_deqp_gles31_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles31_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_rotate180_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles3_rotate180_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_rotate180_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_rotate270_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles3_rotate270_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_rotate270_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_rotate90_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles3_rotate90_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_rotate90_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_gles3_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 - }, - "test": "angle_deqp_gles3_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_gles3_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_khr_gles2_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_khr_gles2_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_khr_gles2_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_khr_gles31_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_khr_gles31_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_khr_gles31_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_deqp_khr_gles3_tests", - "--use-angle=swiftshader", - "--bot-mode" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_khr_gles3_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_deqp_khr_gles3_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "angle_end2end_tests", - "--bot-mode", - "--gtest_filter=*Vulkan_SwiftShader*" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "gpu": "none", - "os": "Windows-10", - "pool": "chromium.tests.gpu" - } - ], - "hard_timeout": 900, - "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_end2end_tests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_end2end_tests/", - "use_isolated_scripts_api": true - } - ] - }, "win-swangle-tot-swiftshader-x64": { "gtest_tests": [ {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index c84dcb62..bd93cbf0 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,15 +22,15 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5058.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5059.0/test_ash_chrome', ], - 'identifier': 'Lacros version skew testing ash 103.0.5058.0', + 'identifier': 'Lacros version skew testing ash 103.0.5059.0', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v103.0.5058.0', - 'revision': 'version:103.0.5058.0', + 'location': 'lacros_version_skew_tests_v103.0.5059.0', + 'revision': 'version:103.0.5059.0', }, ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 20999977..a5df9b00 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -5606,20 +5606,6 @@ 'gpu_telemetry_tests': 'gpu_swangle_telemetry_tests', }, }, - 'linux-swangle-tot-angle-x64' : { - 'os_type': 'linux', - 'mixins': [ - 'gpu-swarming-pool', - 'isolate_profile_data', - 'linux-bionic', - 'no_gpu', - 'timeout_15m', - 'x86-64', - ], - 'test_suites': { - 'gtest_tests': 'swangle_gtests', - }, - }, 'linux-swangle-tot-swiftshader-x64' : { 'os_type': 'linux', 'mixins': [ @@ -5668,26 +5654,6 @@ 'gpu_telemetry_tests': 'gpu_swangle_telemetry_tests', }, }, - 'win-swangle-tot-angle-x64' : { - 'os_type': 'win', - 'mixins': [ - 'win10_gce_gpu_pool', - 'timeout_15m', - ], - 'test_suites': { - 'gtest_tests': 'swangle_gtests', - }, - }, - 'win-swangle-tot-angle-x86' : { - 'os_type': 'win', - 'mixins': [ - 'win10_gce_gpu_pool', - 'timeout_15m', - ], - 'test_suites': { - 'gtest_tests': 'swangle_gtests', - }, - }, 'win-swangle-tot-swiftshader-x64' : { 'os_type': 'win', 'mixins': [
diff --git a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json index 1fdceff..d8f71d1 100644 --- a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json +++ b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json
@@ -22,7 +22,7 @@ }, "css_transitions_inline_style": { "ci_095": 6.862, - "avg": 19.535, + "avg": 23.008, "cpu_wall_time_ratio": 0.326 }, "aquarium_20k_fast_call": {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 60de6e2..7b3e0ab1 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1135,53 +1135,6 @@ ] } ], - "AutofillPatternProvider": [ - { - "platforms": [ - "android", - "android_webview", - "chromeos", - "chromeos_lacros", - "ios", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled_2022-01-05", - "params": { - "use_language_specific_patterns": "true", - "use_patterns_retrieved_with_the_component_udpater": "false" - }, - "enable_features": [ - "AutofillPageLanguageDetection", - "AutofillParsingPatternProvider" - ] - }, - { - "name": "Enabled_Only_Pattern_Provider_2022-01-05", - "params": { - "use_language_specific_patterns": "false", - "use_patterns_retrieved_with_the_component_udpater": "false" - }, - "enable_features": [ - "AutofillPageLanguageDetection", - "AutofillParsingPatternProvider" - ] - }, - { - "name": "Enabled_Only_Page_Language_Detection_2022-01-05", - "enable_features": [ - "AutofillPageLanguageDetection" - ], - "disable_features": [ - "AutofillParsingPatternProvider" - ] - } - ] - } - ], "AutofillPreventOverridingPrefilledFieldValue": [ { "platforms": [
diff --git a/third_party/androidx/fetch_all_androidx.py b/third_party/androidx/fetch_all_androidx.py index 57f8172..09145619 100755 --- a/third_party/androidx/fetch_all_androidx.py +++ b/third_party/androidx/fetch_all_androidx.py
@@ -39,8 +39,14 @@ # When androidx roller is breaking, and a fix is not immenent, use this to pin a # broken library to an old known-working version. +# * The first element of each tuple is the path to the artifact of the latest +# version of the library. It could change if the version is rev'ed in a new +# snapshot. +# * The second element is a URL to replace the file with. Find the URL for older +# versions of libraries by looking in the BUILD_INFO for the older version +# (e.g.: https://androidx.dev/snapshots/builds/8545498/artifacts/BUILD_INFO) _OVERRIDES = [ - # Example (find URL by looking in BUILD_INFO): + # Example: #('androidx_core_core/core-1.9.0-SNAPSHOT.aar', # 'https://androidx.dev/snapshots/builds/8545498/artifacts/repository/' # 'androidx/core/core/1.8.0-SNAPSHOT/core-1.8.0-20220505.122105-1.aar'),
diff --git a/third_party/blink/common/font_unique_name_lookup/font_table_matcher_unittest.cc b/third_party/blink/common/font_unique_name_lookup/font_table_matcher_unittest.cc index ffcaffd1..8d3d244 100644 --- a/third_party/blink/common/font_unique_name_lookup/font_table_matcher_unittest.cc +++ b/third_party/blink/common/font_unique_name_lookup/font_table_matcher_unittest.cc
@@ -44,8 +44,8 @@ kDummyAndroidBuildFingerPrint); PopulateFontUniqueNameEntry( &font_unique_name_table, kTestFilePath1, 0, - {u8"FONT NAME UPPERCASE", u8"எழுத்துரு பெயர்", u8"字體名稱", - u8"FONT-NAME-UPPERCASE", u8"எழுத்துரு-பெயர்", u8"字體名稱"}); + {"FONT NAME UPPERCASE", "எழுத்துரு பெயர்", "字體名稱", + "FONT-NAME-UPPERCASE", "எழுத்துரு-பெயர்", "字體名稱"}); base::ReadOnlySharedMemoryMapping mapping = FontTableMatcher::MemoryMappingFromFontUniqueNameTable( std::move(font_unique_name_table)); @@ -72,8 +72,7 @@ TEST_F(FontTableMatcherTest, MatchTamilChinese) { ASSERT_EQ(matcher_->AvailableFonts(), 1u); - for (std::string font_name : - {u8"எழுத்துரு பெயர்", u8"எழுத்துரு-பெயர்", u8"字體名稱"}) { + for (std::string font_name : {"எழுத்துரு பெயர்", "எழுத்துரு-பெயர்", "字體名稱"}) { absl::optional<FontTableMatcher::MatchResult> result = matcher_->MatchName(font_name); ASSERT_TRUE(result.has_value());
diff --git a/third_party/blink/public/common/mobile_metrics/mobile_friendliness.h b/third_party/blink/public/common/mobile_metrics/mobile_friendliness.h index 76fc1681..efef79c 100644 --- a/third_party/blink/public/common/mobile_metrics/mobile_friendliness.h +++ b/third_party/blink/public/common/mobile_metrics/mobile_friendliness.h
@@ -12,10 +12,6 @@ // This structure contains extracted mobile friendliness metrics from the page. // Used for UKM logging. struct BLINK_COMMON_EXPORT MobileFriendliness { - MobileFriendliness() = default; - MobileFriendliness(const MobileFriendliness&) = default; - MobileFriendliness& operator=(const MobileFriendliness&) = default; - bool operator==(const MobileFriendliness& other) const; bool operator!=(const MobileFriendliness& other) const { return !(*this == other);
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index e2a15fe..fb4c86f 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -10120,6 +10120,13 @@ # Enable the WebAuthn domain and start intercepting credential storage and # retrieval with a virtual authenticator. command enable + parameters + # Whether to enable the WebAuthn user interface. Enabling the UI is + # recommended for debugging and demo purposes, as it is closer to the real + # experience. Disabling the UI is recommended for automated testing. + # Supported at the embedder's discretion if UI is available. + # Defaults to false. + optional boolean enableUI # Disable the WebAuthn domain. command disable
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 0dde750..31d468f 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3542,6 +3542,9 @@ kGestureScrollUpdate = 4221, kGestureScrollEnd = 4222, kArrayBufferTooBigForWebAPI = 4223, + kFedCmRevoke = 4224, + kFedCmLogout = 4225, + kFedCmLogoutRps = 4226, // 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/renderer/core/css/media_query_evaluator_test.cc b/third_party/blink/renderer/core/css/media_query_evaluator_test.cc index 00056d6..c847518 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator_test.cc +++ b/third_party/blink/renderer/core/css/media_query_evaluator_test.cc
@@ -690,7 +690,7 @@ } { data.device_supports_hdr = - gfx::DisplayColorSpaces(gfx::ColorSpace::CreateSCRGBLinear()) + gfx::DisplayColorSpaces(gfx::ColorSpace::CreateSRGBLinear()) .SupportsHDR(); MediaValues* media_values = MakeGarbageCollected<MediaValuesCached>(data); MediaQueryEvaluator media_query_evaluator(media_values);
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.h b/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.h index 07ea24c..3b3b522 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.h +++ b/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.h
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/platform/graphics/document_transition_shared_element_id.h" #include "third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" +#include "third_party/blink/renderer/platform/heap/heap_traits.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" namespace blink {
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index fb0904d..e8be302 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -3753,7 +3753,8 @@ // Since we do not allow registering the beforeunload event handlers in // fenced frames, it should not be fired by fencedframes. - DCHECK(!GetFrame()->IsInFencedFrameTree() || !GetEventTargetData() || + DCHECK(!GetFrame() || !GetFrame()->IsInFencedFrameTree() || + !GetEventTargetData() || !GetEventTargetData()->event_listener_map.Contains( event_type_names::kBeforeunload)); @@ -3849,7 +3850,8 @@ // Since we do not allow registering the unload event handlers in // fenced frames, it should not be fired by fencedframes. - DCHECK(!GetFrame()->IsInFencedFrameTree() || !GetEventTargetData() || + DCHECK(!GetFrame() || !GetFrame()->IsInFencedFrameTree() || + !GetEventTargetData() || !GetEventTargetData()->event_listener_map.Contains( event_type_names::kUnload));
diff --git a/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc b/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc index 7ea14ed2..b0b9b11 100644 --- a/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc +++ b/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc
@@ -82,7 +82,7 @@ .SetSanitizeMarkup(true) .Build()); EXPECT_TRUE(command.Apply()) << "the delete command should have succeeded"; - EXPECT_EQ(u8"<p contenteditable>a<b>\u00A0|</b>\u00A0<ruby></ruby></p>", + EXPECT_EQ("<p contenteditable>a<b>\u00A0|</b>\u00A0<ruby></ruby></p>", GetSelectionTextFromBody()); }
diff --git a/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc b/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc index 697f836..3700af06 100644 --- a/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc +++ b/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc
@@ -181,7 +181,7 @@ EXPECT_TRUE(command.Apply()); // Smart paste inserts a space before pasted text. - EXPECT_EQ(u8"<div contenteditable>abc<div>def XYZ|</div></div>", + EXPECT_EQ("<div contenteditable>abc<div>def XYZ|</div></div>", GetSelectionTextFromBody()); }
diff --git a/third_party/blink/renderer/core/editing/finder/find_buffer.h b/third_party/blink/renderer/core/editing/finder/find_buffer.h index bd33adc..a9ba249d 100644 --- a/third_party/blink/renderer/core/editing/finder/find_buffer.h +++ b/third_party/blink/renderer/core/editing/finder/find_buffer.h
@@ -88,11 +88,11 @@ TextSearcherICU* text_searcher, const String& search_text); - bool operator==(const Iterator& other) { + bool operator==(const Iterator& other) const { return has_match_ == other.has_match_; } - bool operator!=(const Iterator& other) { + bool operator!=(const Iterator& other) const { return has_match_ != other.has_match_; }
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc index 71d09f0..fecaef0 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
@@ -3480,57 +3480,57 @@ TEST_F(InputMethodControllerTest, SetCompositionInTibetan) { GetFrame().Selection().SetSelectionAndEndTyping( - SetSelectionTextToBody(u8"<div id='sample' contenteditable>|</div>")); + SetSelectionTextToBody("<div id='sample' contenteditable>|</div>")); Element* const div = GetDocument().getElementById("sample"); div->Focus(); Vector<ImeTextSpan> ime_text_spans; Controller().SetComposition(String(Vector<UChar>{0xF56}), ime_text_spans, 1, 1); - EXPECT_EQ(u8"<div contenteditable id=\"sample\">\u0F56|</div>", + EXPECT_EQ("<div contenteditable id=\"sample\">\u0F56|</div>", GetSelectionTextFromBody()); Controller().CommitText(String(Vector<UChar>{0xF56}), ime_text_spans, 0); - EXPECT_EQ(u8"<div contenteditable id=\"sample\">\u0F56|</div>", + EXPECT_EQ("<div contenteditable id=\"sample\">\u0F56|</div>", GetSelectionTextFromBody()); Controller().SetComposition(String(Vector<UChar>{0xFB7}), ime_text_spans, 1, 1); - EXPECT_EQ(u8"<div contenteditable id=\"sample\">\u0F56\u0FB7|</div>", + EXPECT_EQ("<div contenteditable id=\"sample\">\u0F56\u0FB7|</div>", GetSelectionTextFromBody()); // Attempt to replace part of grapheme cluster "\u0FB7" in composition Controller().CommitText(String(Vector<UChar>{0xFB7}), ime_text_spans, 0); - EXPECT_EQ(u8"<div contenteditable id=\"sample\">\u0F56\u0FB7|</div>", + EXPECT_EQ("<div contenteditable id=\"sample\">\u0F56\u0FB7|</div>", GetSelectionTextFromBody()); Controller().SetComposition(String(Vector<UChar>{0xF74}), ime_text_spans, 1, 1); - EXPECT_EQ(u8"<div contenteditable id=\"sample\">\u0F56\u0FB7\u0F74|</div>", + EXPECT_EQ("<div contenteditable id=\"sample\">\u0F56\u0FB7\u0F74|</div>", GetSelectionTextFromBody()); } TEST_F(InputMethodControllerTest, SetCompositionInDevanagari) { - GetFrame().Selection().SetSelectionAndEndTyping(SetSelectionTextToBody( - u8"<div id='sample' contenteditable>\u0958|</div>")); + GetFrame().Selection().SetSelectionAndEndTyping( + SetSelectionTextToBody("<div id='sample' contenteditable>\u0958|</div>")); Element* const div = GetDocument().getElementById("sample"); div->Focus(); Vector<ImeTextSpan> ime_text_spans; Controller().SetComposition(String(Vector<UChar>{0x94D}), ime_text_spans, 1, 1); - EXPECT_EQ(u8"<div contenteditable id=\"sample\">\u0958\u094D|</div>", + EXPECT_EQ("<div contenteditable id=\"sample\">\u0958\u094D|</div>", GetSelectionTextFromBody()); Controller().CommitText(String(Vector<UChar>{0x94D, 0x930}), ime_text_spans, 0); - EXPECT_EQ(u8"<div contenteditable id=\"sample\">\u0958\u094D\u0930|</div>", + EXPECT_EQ("<div contenteditable id=\"sample\">\u0958\u094D\u0930|</div>", GetSelectionTextFromBody()); } TEST_F(InputMethodControllerTest, SetCompositionTamil) { GetFrame().Selection().SetSelectionAndEndTyping( - SetSelectionTextToBody(u8"<div id='sample' contenteditable>|</div>")); + SetSelectionTextToBody("<div id='sample' contenteditable>|</div>")); Element* const div = GetDocument().getElementById("sample"); div->Focus(); @@ -3543,7 +3543,7 @@ // Add character U+0BC7: 'TAMIL VOWEL SIGN EE' Controller().CommitText(String(Vector<UChar>{0xBB5, 0xBC7}), ime_text_spans, 1); - EXPECT_EQ(u8"<div contenteditable id=\"sample\">\u00A0\u0BB5\u0BC7|</div>", + EXPECT_EQ("<div contenteditable id=\"sample\">\u00A0\u0BB5\u0BC7|</div>", GetSelectionTextFromBody()); }
diff --git a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu_test.cc b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu_test.cc index 6b01bc6..e47ddfeb 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu_test.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu_test.cc
@@ -101,7 +101,7 @@ TEST(TextSearcherICUTest, FindControlCharacter) { TextSearcherICU searcher; - const String& pattern = MakeUTF16(u8"\u0080"); + const String& pattern = MakeUTF16("\u0080"); searcher.SetPattern(pattern, 0); const String& text = MakeUTF16("some text");
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker.h b/third_party/blink/renderer/core/editing/markers/document_marker.h index 4303c602..4712a5d 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker.h +++ b/third_party/blink/renderer/core/editing/markers/document_marker.h
@@ -68,10 +68,10 @@ : remaining_types_(marker_types) {} MarkerTypesIterator(const MarkerTypesIterator& other) = default; - bool operator==(const MarkerTypesIterator& other) { + bool operator==(const MarkerTypesIterator& other) const { return remaining_types_ == other.remaining_types_; } - bool operator!=(const MarkerTypesIterator& other) { + bool operator!=(const MarkerTypesIterator& other) const { return !operator==(other); }
diff --git a/third_party/blink/renderer/core/editing/visible_units_line_test.cc b/third_party/blink/renderer/core/editing/visible_units_line_test.cc index b5062606..1abb198 100644 --- a/third_party/blink/renderer/core/editing/visible_units_line_test.cc +++ b/third_party/blink/renderer/core/editing/visible_units_line_test.cc
@@ -1052,7 +1052,7 @@ "p { font: 10px/1 Ahem; }" "p { width: 4ch; }"); const SelectionInDOMTree& selection = - SetSelectionTextToBody(u8"<p id=t>abcd^\u200B|wxyz</p>"); + SetSelectionTextToBody("<p id=t>abcd^\u200B|wxyz</p>"); const Position& after_zws = selection.Extent(); const PositionWithAffinity after_zws_down =
diff --git a/third_party/blink/renderer/core/editing/visible_units_test.cc b/third_party/blink/renderer/core/editing/visible_units_test.cc index 11f14e38..12c6590d 100644 --- a/third_party/blink/renderer/core/editing/visible_units_test.cc +++ b/third_party/blink/renderer/core/editing/visible_units_test.cc
@@ -842,47 +842,46 @@ TEST_F(VisibleUnitsTest, SnapBackwardWithZeroWidthSpace) { // Note: We should skip <wbr> otherwise caret stops before/after <wbr>. - EXPECT_EQ(u8"<p>ab|<wbr></p>", TestSnapBackward(u8"<p>ab<wbr>|</p>")); - EXPECT_EQ(u8"<p>ab\u200B|</p>", TestSnapBackward(u8"<p>ab\u200B|</p>")); - EXPECT_EQ(u8"<p>ab<!-- -->\u200B|</p>", - TestSnapBackward(u8"<p>ab<!-- -->\u200B|</p>")); + EXPECT_EQ("<p>ab|<wbr></p>", TestSnapBackward("<p>ab<wbr>|</p>")); + EXPECT_EQ("<p>ab\u200B|</p>", TestSnapBackward("<p>ab\u200B|</p>")); + EXPECT_EQ("<p>ab<!-- -->\u200B|</p>", + TestSnapBackward("<p>ab<!-- -->\u200B|</p>")); - EXPECT_EQ(u8"<p>ab|<wbr><wbr></p>", - TestSnapBackward(u8"<p>ab<wbr><wbr>|</p>")); - EXPECT_EQ(u8"<p>ab\u200B\u200B|</p>", - TestSnapBackward(u8"<p>ab\u200B\u200B|</p>")); + EXPECT_EQ("<p>ab|<wbr><wbr></p>", TestSnapBackward("<p>ab<wbr><wbr>|</p>")); + EXPECT_EQ("<p>ab\u200B\u200B|</p>", + TestSnapBackward("<p>ab\u200B\u200B|</p>")); - EXPECT_EQ(u8"<p>ab|<wbr>cd</p>", TestSnapBackward(u8"<p>ab<wbr>|cd</p>")); - EXPECT_EQ(u8"<p>ab\u200B|cd</p>", TestSnapBackward(u8"<p>ab\u200B|cd</p>")); + EXPECT_EQ("<p>ab|<wbr>cd</p>", TestSnapBackward("<p>ab<wbr>|cd</p>")); + EXPECT_EQ("<p>ab\u200B|cd</p>", TestSnapBackward("<p>ab\u200B|cd</p>")); - EXPECT_EQ(u8"<p>ab|<wbr><wbr>cd</p>", - TestSnapBackward(u8"<p>ab<wbr><wbr>|cd</p>")); - EXPECT_EQ(u8"<p>ab\u200B\u200B|cd</p>", - TestSnapBackward(u8"<p>ab\u200B\u200B|cd</p>")); + EXPECT_EQ("<p>ab|<wbr><wbr>cd</p>", + TestSnapBackward("<p>ab<wbr><wbr>|cd</p>")); + EXPECT_EQ("<p>ab\u200B\u200B|cd</p>", + TestSnapBackward("<p>ab\u200B\u200B|cd</p>")); } // http://crbug.com/1134470 TEST_F(VisibleUnitsTest, SnapForwardWithZeroWidthSpace) { // Note: We should skip <wbr> otherwise caret stops before/after <wbr>. - EXPECT_EQ(u8"<p>ab<wbr></p>", TestSnapForward(u8"<p>ab|<wbr></p>")) + EXPECT_EQ("<p>ab<wbr></p>", TestSnapForward("<p>ab|<wbr></p>")) << "We get <wbr>@0"; - EXPECT_EQ(u8"<p>ab|\u200B</p>", TestSnapForward(u8"<p>ab|\u200B</p>")); - EXPECT_EQ(u8"<p>ab<!-- -->|\u200B</p>", - TestSnapForward(u8"<p>ab<!-- -->|\u200B</p>")); + EXPECT_EQ("<p>ab|\u200B</p>", TestSnapForward("<p>ab|\u200B</p>")); + EXPECT_EQ("<p>ab<!-- -->|\u200B</p>", + TestSnapForward("<p>ab<!-- -->|\u200B</p>")); - EXPECT_EQ(u8"<p>ab<wbr><wbr></p>", TestSnapForward(u8"<p>ab|<wbr><wbr></p>")) + EXPECT_EQ("<p>ab<wbr><wbr></p>", TestSnapForward("<p>ab|<wbr><wbr></p>")) << "We get <wbr>@0"; - EXPECT_EQ(u8"<p>ab|\u200B\u200B</p>", - TestSnapForward(u8"<p>ab|\u200B\u200B</p>")); + EXPECT_EQ("<p>ab|\u200B\u200B</p>", + TestSnapForward("<p>ab|\u200B\u200B</p>")); - EXPECT_EQ(u8"<p>ab<wbr>|cd</p>", TestSnapForward(u8"<p>ab|<wbr>cd</p>")); - EXPECT_EQ(u8"<p>ab|\u200Bcd</p>", TestSnapForward(u8"<p>ab|\u200Bcd</p>")); + EXPECT_EQ("<p>ab<wbr>|cd</p>", TestSnapForward("<p>ab|<wbr>cd</p>")); + EXPECT_EQ("<p>ab|\u200Bcd</p>", TestSnapForward("<p>ab|\u200Bcd</p>")); - EXPECT_EQ(u8"<p>ab<wbr><wbr>|cd</p>", - TestSnapForward(u8"<p>ab|<wbr><wbr>cd</p>")); - EXPECT_EQ(u8"<p>ab|\u200B\u200Bcd</p>", - TestSnapForward(u8"<p>ab|\u200B\u200Bcd</p>")); + EXPECT_EQ("<p>ab<wbr><wbr>|cd</p>", + TestSnapForward("<p>ab|<wbr><wbr>cd</p>")); + EXPECT_EQ("<p>ab|\u200B\u200Bcd</p>", + TestSnapForward("<p>ab|\u200B\u200Bcd</p>")); } } // namespace visible_units_test
diff --git a/third_party/blink/renderer/core/frame/reporting_observer.h b/third_party/blink/renderer/core/frame/reporting_observer.h index 47fff2a..e3ce607 100644 --- a/third_party/blink/renderer/core/frame/reporting_observer.h +++ b/third_party/blink/renderer/core/frame/reporting_observer.h
@@ -17,6 +17,7 @@ class ExecutionContext; class Report; +class V8ReportingObserverCallback; class CORE_EXPORT ReportingObserver final : public ScriptWrappable,
diff --git a/third_party/blink/renderer/core/inspector/inspected_frames.cc b/third_party/blink/renderer/core/inspector/inspected_frames.cc index 2231c544..107c2e7 100644 --- a/third_party/blink/renderer/core/inspector/inspected_frames.cc +++ b/third_party/blink/renderer/core/inspector/inspected_frames.cc
@@ -60,11 +60,11 @@ return Iterator(root_, old); } -bool InspectedFrames::Iterator::operator==(const Iterator& other) { +bool InspectedFrames::Iterator::operator==(const Iterator& other) const { return current_ == other.current_ && root_ == other.root_; } -bool InspectedFrames::Iterator::operator!=(const Iterator& other) { +bool InspectedFrames::Iterator::operator!=(const Iterator& other) const { return !(*this == other); }
diff --git a/third_party/blink/renderer/core/inspector/inspected_frames.h b/third_party/blink/renderer/core/inspector/inspected_frames.h index b6541df..8fc79aa3 100644 --- a/third_party/blink/renderer/core/inspector/inspected_frames.h +++ b/third_party/blink/renderer/core/inspector/inspected_frames.h
@@ -24,8 +24,8 @@ public: Iterator operator++(int); Iterator& operator++(); - bool operator==(const Iterator& other); - bool operator!=(const Iterator& other); + bool operator==(const Iterator& other) const; + bool operator!=(const Iterator& other) const; LocalFrame* operator*() { return current_; } LocalFrame* operator->() { return current_; }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc index a7fe404..6c4b33218 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc
@@ -69,8 +69,8 @@ text.appendData(u"\u05D0\u05D1\u05BC\u05D2"); EXPECT_EQ( - u8"*{'\u05D0\u05D1\u05BC\u05D2\u05D0\u05D1\u05BC\u05D2', " - u8"ShapeResult=0+8 #glyphs=6}\n", + "*{'\u05D0\u05D1\u05BC\u05D2\u05D0\u05D1\u05BC\u05D2', " + "ShapeResult=0+8 #glyphs=6}\n", GetItemsAsString(*text.GetLayoutObject(), 6)); } @@ -127,17 +127,17 @@ Text& text = To<Text>(*GetElementById("target")->firstChild()); UpdateAllLifecyclePhasesForTest(); text.appendData(u"\u200D"); - EXPECT_EQ(u8"*{'\U0001F937\u200D', ShapeResult=0+3 #glyphs=2}\n", + EXPECT_EQ("*{'\U0001F937\u200D', ShapeResult=0+3 #glyphs=2}\n", GetItemsAsString(*text.GetLayoutObject(), 2)); UpdateAllLifecyclePhasesForTest(); text.appendData(u"\u2640"); - EXPECT_EQ(u8"*{'\U0001F937\u200D\u2640', ShapeResult=0+4 #glyphs=1}\n", + EXPECT_EQ("*{'\U0001F937\u200D\u2640', ShapeResult=0+4 #glyphs=1}\n", GetItemsAsString(*text.GetLayoutObject(), 1)); UpdateAllLifecyclePhasesForTest(); text.appendData(u"\uFE0F"); - EXPECT_EQ(u8"*{'\U0001F937\u200D\u2640\uFE0F', ShapeResult=0+5 #glyphs=1}\n", + EXPECT_EQ("*{'\U0001F937\u200D\u2640\uFE0F', ShapeResult=0+5 #glyphs=1}\n", GetItemsAsString(*text.GetLayoutObject(), 1)); }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc index 10c9f14..90012cd 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
@@ -217,7 +217,7 @@ "</div>"); NGInlineNodeForTest node = CreateInlineNode(); node.CollectInlines(); - EXPECT_EQ(u8"abc\uFFFCghi\uFFFCmno", node.Text()) + EXPECT_EQ("abc\uFFFCghi\uFFFCmno", node.Text()) << "floats are appeared as an object replacement character"; HeapVector<NGInlineItem>& items = node.Items(); ASSERT_EQ(5u, items.size()); @@ -235,7 +235,7 @@ "</div>"); NGInlineNodeForTest node = CreateInlineNode(); node.CollectInlines(); - EXPECT_EQ(u8"abc\uFFFCjkl", node.Text()) + EXPECT_EQ("abc\uFFFCjkl", node.Text()) << "inline-block is appeared as an object replacement character"; HeapVector<NGInlineItem>& items = node.Items(); ASSERT_EQ(3u, items.size()); @@ -345,7 +345,7 @@ NGInlineNodeForTest node = CreateInlineNode( To<LayoutNGTextCombine>(layout_object_->SlowFirstChild())); node.CollectInlines(); - EXPECT_EQ(u8"\u2022", node.Text()); + EXPECT_EQ("\u2022", node.Text()); HeapVector<NGInlineItem>& items = node.Items(); ASSERT_EQ(1u, items.size()); TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 1u); @@ -376,7 +376,7 @@ NGInlineNodeForTest node = CreateInlineNode(To<LayoutNGBlockFlow>(layout_object_.Get())); node.CollectInlines(); - EXPECT_EQ(u8"a\u200Bz", node.Text()); + EXPECT_EQ("a\u200Bz", node.Text()); HeapVector<NGInlineItem>& items = node.Items(); ASSERT_EQ(3u, items.size()); TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 1u);
diff --git a/third_party/blink/renderer/core/style/basic_shapes.cc b/third_party/blink/renderer/core/style/basic_shapes.cc index 43ea0b3f..01a1ad3 100644 --- a/third_party/blink/renderer/core/style/basic_shapes.cc +++ b/third_party/blink/renderer/core/style/basic_shapes.cc
@@ -36,9 +36,7 @@ namespace blink { -bool BasicShapeCircle::operator==(const BasicShape& o) const { - if (!IsSameType(o)) - return false; +bool BasicShapeCircle::IsEqualAssumingSameType(const BasicShape& o) const { const BasicShapeCircle& other = To<BasicShapeCircle>(o); return center_x_ == other.center_x_ && center_y_ == other.center_y_ && radius_ == other.radius_; @@ -75,9 +73,7 @@ path.AddEllipse(center + bounding_box.OffsetFromOrigin(), radius, radius); } -bool BasicShapeEllipse::operator==(const BasicShape& o) const { - if (!IsSameType(o)) - return false; +bool BasicShapeEllipse::IsEqualAssumingSameType(const BasicShape& o) const { const BasicShapeEllipse& other = To<BasicShapeEllipse>(o); return center_x_ == other.center_x_ && center_y_ == other.center_y_ && radius_x_ == other.radius_x_ && radius_y_ == other.radius_y_; @@ -136,9 +132,7 @@ path.CloseSubpath(); } -bool BasicShapePolygon::operator==(const BasicShape& o) const { - if (!IsSameType(o)) - return false; +bool BasicShapePolygon::IsEqualAssumingSameType(const BasicShape& o) const { const BasicShapePolygon& other = To<BasicShapePolygon>(o); return wind_rule_ == other.wind_rule_ && values_ == other.values_; } @@ -169,9 +163,7 @@ path.AddRoundedRect(final_rect); } -bool BasicShapeInset::operator==(const BasicShape& o) const { - if (!IsSameType(o)) - return false; +bool BasicShapeInset::IsEqualAssumingSameType(const BasicShape& o) const { const BasicShapeInset& other = To<BasicShapeInset>(o); return right_ == other.right_ && top_ == other.top_ && bottom_ == other.bottom_ && left_ == other.left_ &&
diff --git a/third_party/blink/renderer/core/style/basic_shapes.h b/third_party/blink/renderer/core/style/basic_shapes.h index fac695b9..c14cf31f 100644 --- a/third_party/blink/renderer/core/style/basic_shapes.h +++ b/third_party/blink/renderer/core/style/basic_shapes.h
@@ -70,12 +70,16 @@ virtual void GetPath(Path&, const gfx::RectF&, float zoom) = 0; virtual WindRule GetWindRule() const { return RULE_NONZERO; } - virtual bool operator==(const BasicShape&) const = 0; + bool operator==(const BasicShape& o) const { + return IsSameType(o) && IsEqualAssumingSameType(o); + } virtual ShapeType GetType() const = 0; protected: BasicShape() = default; + + virtual bool IsEqualAssumingSameType(const BasicShape&) const = 0; }; class BasicShapeCenterCoordinate { @@ -149,10 +153,12 @@ void SetRadius(BasicShapeRadius radius) { radius_ = radius; } void GetPath(Path&, const gfx::RectF&, float) override; - bool operator==(const BasicShape&) const override; ShapeType GetType() const override { return kBasicShapeCircleType; } + protected: + bool IsEqualAssumingSameType(const BasicShape&) const override; + private: BasicShapeCircle() = default; @@ -188,10 +194,12 @@ void SetRadiusY(BasicShapeRadius radius_y) { radius_y_ = radius_y; } void GetPath(Path&, const gfx::RectF&, float) override; - bool operator==(const BasicShape&) const override; ShapeType GetType() const override { return kBasicShapeEllipseType; } + protected: + bool IsEqualAssumingSameType(const BasicShape&) const override; + private: BasicShapeEllipse() = default; @@ -223,12 +231,14 @@ } void GetPath(Path&, const gfx::RectF&, float) override; - bool operator==(const BasicShape&) const override; WindRule GetWindRule() const override { return wind_rule_; } ShapeType GetType() const override { return kBasicShapePolygonType; } + protected: + bool IsEqualAssumingSameType(const BasicShape&) const override; + private: BasicShapePolygon() : wind_rule_(RULE_NONZERO) {} @@ -276,10 +286,12 @@ } void GetPath(Path&, const gfx::RectF&, float) override; - bool operator==(const BasicShape&) const override; ShapeType GetType() const override { return kBasicShapeInsetType; } + protected: + bool IsEqualAssumingSameType(const BasicShape&) const override; + private: BasicShapeInset() = default;
diff --git a/third_party/blink/renderer/core/style/filter_operation.cc b/third_party/blink/renderer/core/style/filter_operation.cc index 3ad466c..7a840db 100644 --- a/third_party/blink/renderer/core/style/filter_operation.cc +++ b/third_party/blink/renderer/core/style/filter_operation.cc
@@ -61,9 +61,8 @@ resource_->RemoveClient(client); } -bool ReferenceFilterOperation::operator==(const FilterOperation& o) const { - if (!IsSameType(o)) - return false; +bool ReferenceFilterOperation::IsEqualAssumingSameType( + const FilterOperation& o) const { const auto& other = To<ReferenceFilterOperation>(o); return url_ == other.url_ && resource_ == other.resource_; } @@ -84,9 +83,8 @@ return reflection_.MapRect(rect); } -bool BoxReflectFilterOperation::operator==(const FilterOperation& o) const { - if (!IsSameType(o)) - return false; +bool BoxReflectFilterOperation::IsEqualAssumingSameType( + const FilterOperation& o) const { const auto& other = static_cast<const BoxReflectFilterOperation&>(o); return reflection_ == other.reflection_; }
diff --git a/third_party/blink/renderer/core/style/filter_operation.h b/third_party/blink/renderer/core/style/filter_operation.h index 7899cd05..a622006b 100644 --- a/third_party/blink/renderer/core/style/filter_operation.h +++ b/third_party/blink/renderer/core/style/filter_operation.h
@@ -102,7 +102,9 @@ virtual ~FilterOperation() = default; virtual void Trace(Visitor* visitor) const {} - virtual bool operator==(const FilterOperation&) const = 0; + bool operator==(const FilterOperation& o) const { + return IsSameType(o) && IsEqualAssumingSameType(o); + } bool operator!=(const FilterOperation& o) const { return !(*this == o); } OperationType GetType() const { return type_; } @@ -124,6 +126,8 @@ protected: FilterOperation(OperationType type) : type_(type) {} + virtual bool IsEqualAssumingSameType(const FilterOperation&) const = 0; + OperationType type_; private: @@ -151,9 +155,10 @@ void Trace(Visitor*) const override; - private: - bool operator==(const FilterOperation&) const override; + protected: + bool IsEqualAssumingSameType(const FilterOperation&) const override; + private: AtomicString url_; Member<SVGResource> resource_; Member<Filter> filter_; @@ -176,15 +181,14 @@ double Amount() const { return amount_; } - private: - bool operator==(const FilterOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const FilterOperation& o) const override { const BasicColorMatrixFilterOperation* other = static_cast<const BasicColorMatrixFilterOperation*>(&o); return amount_ == other->amount_; } + private: double amount_; }; @@ -196,15 +200,14 @@ const Vector<float>& Values() const { return values_; } - private: - bool operator==(const FilterOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const FilterOperation& o) const override { const ColorMatrixFilterOperation* other = static_cast<const ColorMatrixFilterOperation*>(&o); return values_ == other->values_; } + private: Vector<float> values_; }; @@ -244,15 +247,14 @@ bool AffectsOpacity() const override { return type_ == kOpacity; } - private: - bool operator==(const FilterOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const FilterOperation& o) const override { const BasicComponentTransferFilterOperation* other = static_cast<const BasicComponentTransferFilterOperation*>(&o); return amount_ == other->amount_; } + private: double amount_; }; @@ -283,15 +285,14 @@ bool MovesPixels() const override { return true; } gfx::RectF MapRect(const gfx::RectF&) const override; - private: - bool operator==(const FilterOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const FilterOperation& o) const override { const BlurFilterOperation* other = static_cast<const BlurFilterOperation*>(&o); return std_deviation_ == other->std_deviation_; } + private: Length std_deviation_; }; @@ -313,15 +314,14 @@ bool MovesPixels() const override { return true; } gfx::RectF MapRect(const gfx::RectF&) const override; - private: - bool operator==(const FilterOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const FilterOperation& o) const override { const DropShadowFilterOperation* other = static_cast<const DropShadowFilterOperation*>(&o); return shadow_ == other->shadow_; } + private: ShadowData shadow_; }; @@ -343,9 +343,10 @@ bool MovesPixels() const override { return true; } gfx::RectF MapRect(const gfx::RectF&) const override; - private: - bool operator==(const FilterOperation&) const override; + protected: + bool IsEqualAssumingSameType(const FilterOperation&) const override; + private: BoxReflection reflection_; }; @@ -382,10 +383,8 @@ bool PreserveAlpha() const { return preserve_alpha_; } const Vector<float>& KernelMatrix() const { return kernel_matrix_; } - private: - bool operator==(const FilterOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const FilterOperation& o) const override { const ConvolveMatrixFilterOperation* other = static_cast<const ConvolveMatrixFilterOperation*>(&o); return (kernel_size_ == other->kernel_size_ && @@ -396,6 +395,7 @@ kernel_matrix_ == other->kernel_matrix_); } + private: gfx::Size kernel_size_; float divisor_; float bias_; @@ -429,10 +429,8 @@ ComponentTransferFunction BlueFunc() const { return blue_func_; } ComponentTransferFunction AlphaFunc() const { return alpha_func_; } - private: - bool operator==(const FilterOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const FilterOperation& o) const override { const ComponentTransferFilterOperation* other = static_cast<const ComponentTransferFilterOperation*>(&o); return ( @@ -440,6 +438,7 @@ blue_func_ == other->blue_func_ && alpha_func_ == other->alpha_func_); } + private: ComponentTransferFunction red_func_; ComponentTransferFunction green_func_; ComponentTransferFunction blue_func_; @@ -476,10 +475,8 @@ float Seed() const { return seed_; } bool StitchTiles() const { return stitch_tiles_; } - private: - bool operator==(const FilterOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const FilterOperation& o) const override { const TurbulenceFilterOperation* other = static_cast<const TurbulenceFilterOperation*>(&o); return (type_ == other->type_ && @@ -489,6 +486,7 @@ stitch_tiles_ == other->stitch_tiles_); } + private: TurbulenceType type_; float base_frequency_x_; float base_frequency_y_;
diff --git a/third_party/blink/renderer/core/style/style_path.cc b/third_party/blink/renderer/core/style/style_path.cc index 4e102f66..b726574 100644 --- a/third_party/blink/renderer/core/style/style_path.cc +++ b/third_party/blink/renderer/core/style/style_path.cc
@@ -62,9 +62,7 @@ const_cast<StylePath*>(this), kTransformToAbsolute); } -bool StylePath::operator==(const BasicShape& o) const { - if (!IsSameType(o)) - return false; +bool StylePath::IsEqualAssumingSameType(const BasicShape& o) const { const StylePath& other = To<StylePath>(o); return wind_rule_ == other.wind_rule_ && *byte_stream_ == *other.byte_stream_; }
diff --git a/third_party/blink/renderer/core/style/style_path.h b/third_party/blink/renderer/core/style/style_path.h index 7e62554..30d01cf 100644 --- a/third_party/blink/renderer/core/style/style_path.h +++ b/third_party/blink/renderer/core/style/style_path.h
@@ -35,10 +35,11 @@ void GetPath(Path&, const gfx::RectF&, float zoom) override; WindRule GetWindRule() const override { return wind_rule_; } - bool operator==(const BasicShape&) const override; - ShapeType GetType() const override { return kStylePathType; } + protected: + bool IsEqualAssumingSameType(const BasicShape&) const override; + private: explicit StylePath(std::unique_ptr<SVGPathByteStream>, WindRule wind_rule);
diff --git a/third_party/blink/renderer/core/style/style_ray.cc b/third_party/blink/renderer/core/style/style_ray.cc index 0ab58df..72e1c3c 100644 --- a/third_party/blink/renderer/core/style/style_ray.cc +++ b/third_party/blink/renderer/core/style/style_ray.cc
@@ -17,9 +17,7 @@ StyleRay::StyleRay(float angle, RaySize size, bool contain) : angle_(angle), size_(size), contain_(contain) {} -bool StyleRay::operator==(const BasicShape& o) const { - if (!IsSameType(o)) - return false; +bool StyleRay::IsEqualAssumingSameType(const BasicShape& o) const { const StyleRay& other = To<StyleRay>(o); return angle_ == other.angle_ && size_ == other.size_ && contain_ == other.contain_;
diff --git a/third_party/blink/renderer/core/style/style_ray.h b/third_party/blink/renderer/core/style/style_ray.h index 94f729a..3927d30 100644 --- a/third_party/blink/renderer/core/style/style_ray.h +++ b/third_party/blink/renderer/core/style/style_ray.h
@@ -28,10 +28,12 @@ bool Contain() const { return contain_; } void GetPath(Path&, const gfx::RectF&, float) override; - bool operator==(const BasicShape&) const override; ShapeType GetType() const override { return kStyleRayType; } + protected: + bool IsEqualAssumingSameType(const BasicShape&) const override; + private: StyleRay(float angle, RaySize, bool contain);
diff --git a/third_party/blink/renderer/modules/credentialmanagement/federated_credential.cc b/third_party/blink/renderer/modules/credentialmanagement/federated_credential.cc index f8c313a4..b2fc60eda 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/federated_credential.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/federated_credential.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/credentialmanagement/federated_credential.h" +#include "base/metrics/histogram_macros.h" #include "third_party/blink/public/mojom/webid/federated_auth_request.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_credential_creation_options.h" @@ -33,6 +34,15 @@ constexpr char kFederatedCredentialType[] = "federated"; +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class FedCmCspStatus { + kSuccess = 0, + kFailedPathButPassedOrigin = 1, + kFailedOrigin = 2, + kMaxValue = kFailedOrigin +}; + // Abort an ongoing FederatedCredential login() operation. void AbortFederatedCredentialRequest(ScriptState* script_state) { if (!script_state->ContextIsValid()) @@ -172,10 +182,30 @@ ScriptPromiseResolver* resolver, const KURL& provider_url) { if (policy->AllowConnectToSource(provider_url, provider_url, - RedirectStatus::kNoRedirect)) { + RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting)) { + UMA_HISTOGRAM_ENUMERATION("Blink.FedCm.Status.Csp", + FedCmCspStatus::kSuccess); return false; } + // kFollowedRedirect means that the path will not be checked, which is + // what we want -- at least one high-profile site has specific paths + // in its existing connect-src policy which do not work with FedCM, breaking + // the "no RP changes required" promise of FedCM. + // (note that we disable redirects for FedCM requests on the browser side) + // TODO(cbiesinger): Once the two known websites are fixed, make this + // codepath metrics-only and move kSuppressReporting here. crbug.com/1320724 + if (policy->AllowConnectToSource(provider_url, provider_url, + RedirectStatus::kFollowedRedirect)) { + UMA_HISTOGRAM_ENUMERATION("Blink.FedCm.Status.Csp", + FedCmCspStatus::kFailedPathButPassedOrigin); + return false; + } + + UMA_HISTOGRAM_ENUMERATION("Blink.FedCm.Status.Csp", + FedCmCspStatus::kFailedOrigin); + WTF::String error = "Refused to connect to '" + provider_url.ElidedString() + "' because it violates the document's Content Security Policy.";
diff --git a/third_party/blink/renderer/modules/credentialmanagement/federated_credential.idl b/third_party/blink/renderer/modules/credentialmanagement/federated_credential.idl index 64bc68a..f9772538 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/federated_credential.idl +++ b/third_party/blink/renderer/modules/credentialmanagement/federated_credential.idl
@@ -27,14 +27,14 @@ Promise<FederatedTokens> login(optional FederatedAccountLoginRequest request = {}); // https://fedidcg.github.io/FedCM/#browser-api-rp-sign-out - [RuntimeEnabled=FedCm, CallWith=ScriptState] Promise<void> logout(); + [RuntimeEnabled=FedCm, CallWith=ScriptState, MeasureAs=FedCmLogout] Promise<void> logout(); // https://fedidcg.github.io/FedCM/#browser-api-revocation - [RuntimeEnabled=FedCm, CallWith=ScriptState, RaisesException] + [RuntimeEnabled=FedCm, CallWith=ScriptState, RaisesException, MeasureAs=FedCmRevoke] Promise<void> revoke(USVString hint); // Allows IDPs to logout the user out of all of the logged in RPs. - [RuntimeEnabled=FedCmIdpSignout, CallWith=ScriptState] + [RuntimeEnabled=FedCmIdpSignout, CallWith=ScriptState, MeasureAs=FedCmLogoutRps] static Promise<void> logoutRps(optional sequence<FederatedCredentialLogoutRpsRequest> logout_requests = []); // TODO(mkwst): We don't really support this yet; it always returns ''.
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc index 394bec7..a48c2c6 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
@@ -153,8 +153,7 @@ // Render Thread. THREAD_CHECKER(main_render_thread_checker_); const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; - // Can be null in testing. - scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner_; base::WeakPtr<MediaStreamVideoTrack> media_stream_video_track_; @@ -177,17 +176,13 @@ base::WeakPtr<MediaStreamVideoTrack> media_stream_video_track, bool enabled) : io_task_runner_(std::move(io_task_runner)), + // TODO(crbug.com/1223353, crbug.com/624696): Move to WebFrameScheduler. + main_render_task_runner_(Thread::MainThread()->GetTaskRunner()), media_stream_video_track_(media_stream_video_track), enabled_(enabled), emit_frame_drop_events_(true), await_next_key_frame_(false) { DCHECK(io_task_runner_.get()); - - WebLocalFrame* web_frame = WebLocalFrame::FrameForCurrentContext(); - if (web_frame) { - main_render_task_runner_ = - web_frame->GetTaskRunner(TaskType::kInternalMedia); - } } MediaStreamVideoTrack::FrameDeliverer::~FrameDeliverer() { @@ -328,7 +323,7 @@ std::vector<scoped_refptr<media::VideoFrame>> scaled_video_frames, base::TimeTicks estimated_capture_time) { DCHECK(io_task_runner_->BelongsToCurrentThread()); - if (!enabled_ && main_render_task_runner_ && emit_frame_drop_events_) { + if (!enabled_ && emit_frame_drop_events_) { emit_frame_drop_events_ = false; // TODO(crbug.com/964947): A weak ptr instance of MediaStreamVideoTrack is @@ -358,7 +353,7 @@ // frames will only be requested when the source has halted delivery (e.g., a // screen capturer stops sending frames because the screen is not being // updated). - if (main_render_task_runner_ && is_refreshing_for_min_frame_rate_) { + if (is_refreshing_for_min_frame_rate_) { PostCrossThreadTask( *main_render_task_runner_, FROM_HERE, CrossThreadBindOnce(&MediaStreamVideoTrack::ResetRefreshTimer,
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string.cc b/third_party/blink/renderer/platform/bindings/parkable_string.cc index eea622ef9..0345ba48 100644 --- a/third_party/blink/renderer/platform/bindings/parkable_string.cc +++ b/third_party/blink/renderer/platform/bindings/parkable_string.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "third_party/blink/renderer/platform/bindings/parkable_string.h" -#include "base/time/time.h" // parkable_string.h is a widely included header and its size impacts build // time. Try not to raise this limit unless necessary. See @@ -20,6 +19,7 @@ #include "base/process/memory.h" #include "base/synchronization/lock.h" #include "base/task/single_thread_task_runner.h" +#include "base/time/time.h" #include "base/timer/elapsed_timer.h" #include "base/trace_event/typed_macros.h" #include "third_party/blink/public/common/features.h"
diff --git a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc index 93ddb758..b5f9002 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc
@@ -216,19 +216,19 @@ std::vector<std::string> test_strings = { // A family followed by a couple with heart emoji sequence, // the latter including a variation selector. - u8"\U0001f468\u200D\U0001f469\u200D\U0001f467\u200D\U0001f466\U0001f469" - u8"\u200D\u2764\uFE0F\u200D\U0001f48b\u200D\U0001f468", + "\U0001f468\u200D\U0001f469\u200D\U0001f467\u200D\U0001f466\U0001f469" + "\u200D\u2764\uFE0F\u200D\U0001f48b\u200D\U0001f468", // Pirate flag - u8"\U0001F3F4\u200D\u2620\uFE0F", + "\U0001F3F4\u200D\u2620\uFE0F", // Pilot, judge sequence - u8"\U0001f468\U0001f3fb\u200D\u2696\uFE0F\U0001f468\U0001f3fb\u200D\u2708" - u8"\uFE0F", + "\U0001f468\U0001f3fb\u200D\u2696\uFE0F\U0001f468\U0001f3fb\u200D\u2708" + "\uFE0F", // Woman, Kiss, Man sequence - u8"\U0001f469\u200D\u2764\uFE0F\u200D\U0001f48b\u200D\U0001f468", + "\U0001f469\u200D\u2764\uFE0F\u200D\U0001f48b\u200D\U0001f468", // Signs of horns with skin tone modifier - u8"\U0001f918\U0001f3fb", + "\U0001f918\U0001f3fb", // Man, dark skin tone, red hair - u8"\U0001f468\U0001f3ff\u200D\U0001f9b0"}; + "\U0001f468\U0001f3ff\u200D\U0001f9b0"}; for (auto test_string : test_strings) { String emoji_string = String::FromUTF8(test_string);
diff --git a/third_party/blink/renderer/platform/fonts/shaping/run_segmenter_test.cc b/third_party/blink/renderer/platform/fonts/shaping/run_segmenter_test.cc index 4e04613..e5a5fe90 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/run_segmenter_test.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/run_segmenter_test.cc
@@ -195,7 +195,7 @@ FontFallbackPriority::kText}, {"👩👩", USCRIPT_LATIN, OrientationIterator::kOrientationKeep, FontFallbackPriority::kEmojiEmoji}, - {u8"\U0000200Defg", USCRIPT_LATIN, + {"\U0000200Defg", USCRIPT_LATIN, OrientationIterator::kOrientationKeep, FontFallbackPriority::kText}}); } @@ -244,8 +244,8 @@ TEST_F(RunSegmenterTest, NonEmojiPresentationSymbols) { CheckRunsHorizontal( - {{u8"\U00002626\U0000262a\U00002638\U0000271d\U00002721\U00002627" - u8"\U00002628\U00002629\U0000262b\U0000262c\U00002670" + {{"\U00002626\U0000262a\U00002638\U0000271d\U00002721\U00002627" + "\U00002628\U00002629\U0000262b\U0000262c\U00002670" "\U00002671\U0000271f\U00002720", USCRIPT_COMMON, OrientationIterator::kOrientationKeep, FontFallbackPriority::kText}});
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc index 2161a72b..f6e5287 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc
@@ -264,6 +264,9 @@ STACK_ALLOCATED(); public: + GlyphCallbackContext(ShapeResultBloberizer* bloberizer, + const StringView& text) + : bloberizer(bloberizer), text(text) {} GlyphCallbackContext(const GlyphCallbackContext&) = delete; GlyphCallbackContext& operator=(const GlyphCallbackContext&) = delete; @@ -328,6 +331,14 @@ STACK_ALLOCATED(); public: + ClusterCallbackContext(ShapeResultBloberizer* bloberizer, + const StringView& text, + const GlyphData& emphasis_data, + gfx::PointF glyph_center) + : bloberizer(bloberizer), + text(text), + emphasis_data(emphasis_data), + glyph_center(std::move(glyph_center)) {} ClusterCallbackContext(const ClusterCallbackContext&) = delete; ClusterCallbackContext& operator=(const ClusterCallbackContext&) = delete;
diff --git a/third_party/blink/renderer/platform/fonts/symbols_iterator_test.cc b/third_party/blink/renderer/platform/fonts/symbols_iterator_test.cc index cf4937b..105fed0 100644 --- a/third_party/blink/renderer/platform/fonts/symbols_iterator_test.cc +++ b/third_party/blink/renderer/platform/fonts/symbols_iterator_test.cc
@@ -87,15 +87,15 @@ } TEST_F(SymbolsIteratorTest, IgnoreVSInMath) { - CheckRuns({{u8"⊆⊇⊈\U0000FE0E⊙⊚⊚", FontFallbackPriority::kText}}); + CheckRuns({{"⊆⊇⊈\U0000FE0E⊙⊚⊚", FontFallbackPriority::kText}}); } TEST_F(SymbolsIteratorTest, IgnoreVS15InText) { - CheckRuns({{u8"abcdef\U0000FE0Eghji", FontFallbackPriority::kText}}); + CheckRuns({{"abcdef\U0000FE0Eghji", FontFallbackPriority::kText}}); } TEST_F(SymbolsIteratorTest, IgnoreVS16InText) { - CheckRuns({{u8"abcdef\U0000FE0Fghji", FontFallbackPriority::kText}}); + CheckRuns({{"abcdef\U0000FE0Fghji", FontFallbackPriority::kText}}); } TEST_F(SymbolsIteratorTest, AllHexValuesText) { @@ -119,21 +119,20 @@ } TEST_F(SymbolsIteratorTest, EmojiVS15AndVS16) { - CheckRuns({{u8"\U0001F642", FontFallbackPriority::kEmojiEmoji}, - {u8"\U0001F642\U0000FE0E", FontFallbackPriority::kText}, - {u8"\U0001F642\U0000FE0F", FontFallbackPriority::kEmojiEmoji}}); + CheckRuns({{"\U0001F642", FontFallbackPriority::kEmojiEmoji}, + {"\U0001F642\U0000FE0E", FontFallbackPriority::kText}, + {"\U0001F642\U0000FE0F", FontFallbackPriority::kEmojiEmoji}}); } TEST_F(SymbolsIteratorTest, MultipleMisplacedVS) { CheckRuns({ - {u8"\U0000FE0E\U0000FE0F", FontFallbackPriority::kText}, - {u8"\U0001F642\U0000FE0F", FontFallbackPriority::kEmojiEmoji}, - {u8"\U0001F642\U0000FE0E", FontFallbackPriority::kText}, - {u8"\U0001F642\U0000FE0F", FontFallbackPriority::kEmojiEmoji}, - {u8"\U0000FE0E\U0000FE0F", FontFallbackPriority::kText}, - {u8"\U0001F642\U0000FE0F", FontFallbackPriority::kEmojiEmoji}, - {u8"\U0001F642\U0000FE0E\U0000FE0E\U0000FE0F", - FontFallbackPriority::kText}, + {"\U0000FE0E\U0000FE0F", FontFallbackPriority::kText}, + {"\U0001F642\U0000FE0F", FontFallbackPriority::kEmojiEmoji}, + {"\U0001F642\U0000FE0E", FontFallbackPriority::kText}, + {"\U0001F642\U0000FE0F", FontFallbackPriority::kEmojiEmoji}, + {"\U0000FE0E\U0000FE0F", FontFallbackPriority::kText}, + {"\U0001F642\U0000FE0F", FontFallbackPriority::kEmojiEmoji}, + {"\U0001F642\U0000FE0E\U0000FE0E\U0000FE0F", FontFallbackPriority::kText}, }); } @@ -172,8 +171,8 @@ {{"👩👩👧👦👩❤️💋👨", FontFallbackPriority::kEmojiEmoji}, {"abcd", FontFallbackPriority::kText}, - {u8"\U0001F469\U0000200D\U0001F469", FontFallbackPriority::kEmojiEmoji}, - {u8"\U0000200Defgh", FontFallbackPriority::kText}}); + {"\U0001F469\U0000200D\U0001F469", FontFallbackPriority::kEmojiEmoji}, + {"\U0000200Defgh", FontFallbackPriority::kText}}); } TEST_F(SymbolsIteratorTest, AllEmojiZWSSequences) { @@ -226,19 +225,19 @@ } TEST_F(SymbolsIteratorTest, ExtraZWJPrefix) { - CheckRuns({{u8"\U0000200D", FontFallbackPriority::kText}, - {u8"\U0001F469\U0000200D\U00002764\U0000FE0F\U0000200D\U0001F48B" - u8"\U0000200D\U0001F468", + CheckRuns({{"\U0000200D", FontFallbackPriority::kText}, + {"\U0001F469\U0000200D\U00002764\U0000FE0F\U0000200D\U0001F48B" + "\U0000200D\U0001F468", FontFallbackPriority::kEmojiEmoji}}); } TEST_F(SymbolsIteratorTest, StrayZWJAndVS) { - CheckRuns({{u8"\U0000200D\U0000FE0E\U0000FE0E\U0000FE0E\U0000200D\U0000200D", + CheckRuns({{"\U0000200D\U0000FE0E\U0000FE0E\U0000FE0E\U0000200D\U0000200D", FontFallbackPriority::kText}, - {u8"\U0001F469\U0000200D\U00002764\U0000FE0F\U0000200D\U0001F48B" - u8"\U0000200D\U0001F468", + {"\U0001F469\U0000200D\U00002764\U0000FE0F\U0000200D\U0001F48B" + "\U0000200D\U0001F468", FontFallbackPriority::kEmojiEmoji}, - {u8"\U0000200D\U0000FE0E\U0000FE0E\U0000FE0E\U0000200D\U0000200D", + {"\U0000200D\U0000FE0E\U0000FE0E\U0000FE0E\U0000200D\U0000200D", FontFallbackPriority::kText}}); } @@ -263,123 +262,123 @@ // one test ensures that the new emoji form an unbroken emoji-type sequence. TEST_F(SymbolsIteratorTest, Emoji5AdditionsExceptFlags) { CheckRuns( - {{u8"\U0001F9D4\U0001F3FB\U0001F9D4\U0001F3FC\U0001F9D4\U0001F3FD" - u8"\U0001F9D4\U0001F3FE\U0001F9D4\U0001F3FF\U0001F931\U0001F931" - u8"\U0001F3FB\U0001F931\U0001F3FC\U0001F931\U0001F3FD\U0001F931" - u8"\U0001F3FE\U0001F931\U0001F3FF\U0001F9D9\U0001F9D9\U0001F3FB" - u8"\U0001F9D9\U0001F3FC\U0001F9D9\U0001F3FD\U0001F9D9\U0001F3FE" - u8"\U0001F9D9\U0001F3FF\U0001F9D9\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9D9\U0001F3FB\U0000200D\U00002640\U0000FE0F\U0001F9D9" - u8"\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9D9\U0001F3FD" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9D9\U0001F3FE\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9D9\U0001F3FF\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9D9\U0000200D\U00002642\U0000FE0F\U0001F9D9" - u8"\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9D9\U0001F3FC" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9D9\U0001F3FD\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9D9\U0001F3FE\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9D9\U0001F3FF\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9DA\U0001F9DA\U0001F3FB\U0001F9DA\U0001F3FC\U0001F9DA" - u8"\U0001F3FD\U0001F9DA\U0001F3FE\U0001F9DA\U0001F3FF\U0001F9DA" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9DA\U0001F3FB\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9DA\U0001F3FC\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9DA\U0001F3FD\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9DA\U0001F3FE\U0000200D\U00002640\U0000FE0F\U0001F9DA" - u8"\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9DA\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9DA\U0001F3FB\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9DA\U0001F3FC\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9DA\U0001F3FD\U0000200D\U00002642\U0000FE0F\U0001F9DA" - u8"\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9DA\U0001F3FF" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9DB\U0001F9DB\U0001F3FB" - u8"\U0001F9DB\U0001F3FC\U0001F9DB\U0001F3FD\U0001F9DB\U0001F3FE" - u8"\U0001F9DB\U0001F3FF\U0001F9DB\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9DB\U0001F3FB\U0000200D\U00002640\U0000FE0F\U0001F9DB" - u8"\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9DB\U0001F3FD" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9DB\U0001F3FE\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9DB\U0001F3FF\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9DB\U0000200D\U00002642\U0000FE0F\U0001F9DB" - u8"\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9DB\U0001F3FC" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9DB\U0001F3FD\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9DB\U0001F3FE\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9DB\U0001F3FF\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9DC\U0001F9DC\U0001F3FB\U0001F9DC\U0001F3FC\U0001F9DC" - u8"\U0001F3FD\U0001F9DC\U0001F3FE\U0001F9DC\U0001F3FF\U0001F9DC" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9DC\U0001F3FB\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9DC\U0001F3FC\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9DC\U0001F3FD\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9DC\U0001F3FE\U0000200D\U00002640\U0000FE0F\U0001F9DC" - u8"\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9DC\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9DC\U0001F3FB\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9DC\U0001F3FC\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9DC\U0001F3FD\U0000200D\U00002642\U0000FE0F\U0001F9DC" - u8"\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9DC\U0001F3FF" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9DD\U0001F9DD\U0001F3FB" - u8"\U0001F9DD\U0001F3FC\U0001F9DD\U0001F3FD\U0001F9DD\U0001F3FE" - u8"\U0001F9DD\U0001F3FF\U0001F9DD\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9DD\U0001F3FB\U0000200D\U00002640\U0000FE0F\U0001F9DD" - u8"\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9DD\U0001F3FD" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9DD\U0001F3FE\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9DD\U0001F3FF\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9DD\U0000200D\U00002642\U0000FE0F\U0001F9DD" - u8"\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9DD\U0001F3FC" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9DD\U0001F3FD\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9DD\U0001F3FE\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9DD\U0001F3FF\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9DE\U0001F9DE\U0000200D\U00002640\U0000FE0F\U0001F9DE" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9DF\U0001F9DF\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9DF\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9D6\U0001F9D6\U0001F3FB\U0001F9D6\U0001F3FC\U0001F9D6" - u8"\U0001F3FD\U0001F9D6\U0001F3FE\U0001F9D6\U0001F3FF\U0001F9D6" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9D6\U0001F3FB\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9D6\U0001F3FC\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9D6\U0001F3FD\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9D6\U0001F3FE\U0000200D\U00002640\U0000FE0F\U0001F9D6" - u8"\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9D6\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9D6\U0001F3FB\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9D6\U0001F3FC\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9D6\U0001F3FD\U0000200D\U00002642\U0000FE0F\U0001F9D6" - u8"\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9D6\U0001F3FF" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9D7\U0001F9D7\U0001F3FB" - u8"\U0001F9D7\U0001F3FC\U0001F9D7\U0001F3FD\U0001F9D7\U0001F3FE" - u8"\U0001F9D7\U0001F3FF\U0001F9D7\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9D7\U0001F3FB\U0000200D\U00002640\U0000FE0F\U0001F9D7" - u8"\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9D7\U0001F3FD" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9D7\U0001F3FE\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9D7\U0001F3FF\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9D7\U0000200D\U00002642\U0000FE0F\U0001F9D7" - u8"\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9D7\U0001F3FC" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9D7\U0001F3FD\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9D7\U0001F3FE\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9D7\U0001F3FF\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9D8\U0001F9D8\U0001F3FB\U0001F9D8\U0001F3FC\U0001F9D8" - u8"\U0001F3FD\U0001F9D8\U0001F3FE\U0001F9D8\U0001F3FF\U0001F9D8" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9D8\U0001F3FB\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9D8\U0001F3FC\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9D8\U0001F3FD\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9D8\U0001F3FE\U0000200D\U00002640\U0000FE0F\U0001F9D8" - u8"\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9D8\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9D8\U0001F3FB\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9D8\U0001F3FC\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9D8\U0001F3FD\U0000200D\U00002642\U0000FE0F\U0001F9D8" - u8"\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9D8\U0001F3FF" - u8"\U0000200D\U00002642\U0000FE0F\U0001F91F\U0001F91F\U0001F3FB" - u8"\U0001F91F\U0001F3FC\U0001F91F\U0001F3FD\U0001F91F\U0001F3FE" - u8"\U0001F91F\U0001F3FF\U0001F932\U0001F932\U0001F3FB\U0001F932" - u8"\U0001F3FC\U0001F932\U0001F3FD\U0001F932\U0001F3FE\U0001F932" - u8"\U0001F3FF\U0001F9E0\U0001F9E1\U0001F9E3\U0001F9E4\U0001F9E5" - u8"\U0001F9E6\U0001F9E2\U0001F993\U0001F992\U0001F994\U0001F995" - u8"\U0001F996\U0001F997\U0001F965\U0001F966\U0001F968\U0001F969" - u8"\U0001F96A\U0001F963\U0001F96B\U0001F95F\U0001F960\U0001F961" - u8"\U0001F967\U0001F964\U0001F962\U0001F6F8\U0001F6F7\U0001F94C", + {{"\U0001F9D4\U0001F3FB\U0001F9D4\U0001F3FC\U0001F9D4\U0001F3FD" + "\U0001F9D4\U0001F3FE\U0001F9D4\U0001F3FF\U0001F931\U0001F931" + "\U0001F3FB\U0001F931\U0001F3FC\U0001F931\U0001F3FD\U0001F931" + "\U0001F3FE\U0001F931\U0001F3FF\U0001F9D9\U0001F9D9\U0001F3FB" + "\U0001F9D9\U0001F3FC\U0001F9D9\U0001F3FD\U0001F9D9\U0001F3FE" + "\U0001F9D9\U0001F3FF\U0001F9D9\U0000200D\U00002640\U0000FE0F" + "\U0001F9D9\U0001F3FB\U0000200D\U00002640\U0000FE0F\U0001F9D9" + "\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9D9\U0001F3FD" + "\U0000200D\U00002640\U0000FE0F\U0001F9D9\U0001F3FE\U0000200D" + "\U00002640\U0000FE0F\U0001F9D9\U0001F3FF\U0000200D\U00002640" + "\U0000FE0F\U0001F9D9\U0000200D\U00002642\U0000FE0F\U0001F9D9" + "\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9D9\U0001F3FC" + "\U0000200D\U00002642\U0000FE0F\U0001F9D9\U0001F3FD\U0000200D" + "\U00002642\U0000FE0F\U0001F9D9\U0001F3FE\U0000200D\U00002642" + "\U0000FE0F\U0001F9D9\U0001F3FF\U0000200D\U00002642\U0000FE0F" + "\U0001F9DA\U0001F9DA\U0001F3FB\U0001F9DA\U0001F3FC\U0001F9DA" + "\U0001F3FD\U0001F9DA\U0001F3FE\U0001F9DA\U0001F3FF\U0001F9DA" + "\U0000200D\U00002640\U0000FE0F\U0001F9DA\U0001F3FB\U0000200D" + "\U00002640\U0000FE0F\U0001F9DA\U0001F3FC\U0000200D\U00002640" + "\U0000FE0F\U0001F9DA\U0001F3FD\U0000200D\U00002640\U0000FE0F" + "\U0001F9DA\U0001F3FE\U0000200D\U00002640\U0000FE0F\U0001F9DA" + "\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9DA\U0000200D" + "\U00002642\U0000FE0F\U0001F9DA\U0001F3FB\U0000200D\U00002642" + "\U0000FE0F\U0001F9DA\U0001F3FC\U0000200D\U00002642\U0000FE0F" + "\U0001F9DA\U0001F3FD\U0000200D\U00002642\U0000FE0F\U0001F9DA" + "\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9DA\U0001F3FF" + "\U0000200D\U00002642\U0000FE0F\U0001F9DB\U0001F9DB\U0001F3FB" + "\U0001F9DB\U0001F3FC\U0001F9DB\U0001F3FD\U0001F9DB\U0001F3FE" + "\U0001F9DB\U0001F3FF\U0001F9DB\U0000200D\U00002640\U0000FE0F" + "\U0001F9DB\U0001F3FB\U0000200D\U00002640\U0000FE0F\U0001F9DB" + "\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9DB\U0001F3FD" + "\U0000200D\U00002640\U0000FE0F\U0001F9DB\U0001F3FE\U0000200D" + "\U00002640\U0000FE0F\U0001F9DB\U0001F3FF\U0000200D\U00002640" + "\U0000FE0F\U0001F9DB\U0000200D\U00002642\U0000FE0F\U0001F9DB" + "\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9DB\U0001F3FC" + "\U0000200D\U00002642\U0000FE0F\U0001F9DB\U0001F3FD\U0000200D" + "\U00002642\U0000FE0F\U0001F9DB\U0001F3FE\U0000200D\U00002642" + "\U0000FE0F\U0001F9DB\U0001F3FF\U0000200D\U00002642\U0000FE0F" + "\U0001F9DC\U0001F9DC\U0001F3FB\U0001F9DC\U0001F3FC\U0001F9DC" + "\U0001F3FD\U0001F9DC\U0001F3FE\U0001F9DC\U0001F3FF\U0001F9DC" + "\U0000200D\U00002640\U0000FE0F\U0001F9DC\U0001F3FB\U0000200D" + "\U00002640\U0000FE0F\U0001F9DC\U0001F3FC\U0000200D\U00002640" + "\U0000FE0F\U0001F9DC\U0001F3FD\U0000200D\U00002640\U0000FE0F" + "\U0001F9DC\U0001F3FE\U0000200D\U00002640\U0000FE0F\U0001F9DC" + "\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9DC\U0000200D" + "\U00002642\U0000FE0F\U0001F9DC\U0001F3FB\U0000200D\U00002642" + "\U0000FE0F\U0001F9DC\U0001F3FC\U0000200D\U00002642\U0000FE0F" + "\U0001F9DC\U0001F3FD\U0000200D\U00002642\U0000FE0F\U0001F9DC" + "\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9DC\U0001F3FF" + "\U0000200D\U00002642\U0000FE0F\U0001F9DD\U0001F9DD\U0001F3FB" + "\U0001F9DD\U0001F3FC\U0001F9DD\U0001F3FD\U0001F9DD\U0001F3FE" + "\U0001F9DD\U0001F3FF\U0001F9DD\U0000200D\U00002640\U0000FE0F" + "\U0001F9DD\U0001F3FB\U0000200D\U00002640\U0000FE0F\U0001F9DD" + "\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9DD\U0001F3FD" + "\U0000200D\U00002640\U0000FE0F\U0001F9DD\U0001F3FE\U0000200D" + "\U00002640\U0000FE0F\U0001F9DD\U0001F3FF\U0000200D\U00002640" + "\U0000FE0F\U0001F9DD\U0000200D\U00002642\U0000FE0F\U0001F9DD" + "\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9DD\U0001F3FC" + "\U0000200D\U00002642\U0000FE0F\U0001F9DD\U0001F3FD\U0000200D" + "\U00002642\U0000FE0F\U0001F9DD\U0001F3FE\U0000200D\U00002642" + "\U0000FE0F\U0001F9DD\U0001F3FF\U0000200D\U00002642\U0000FE0F" + "\U0001F9DE\U0001F9DE\U0000200D\U00002640\U0000FE0F\U0001F9DE" + "\U0000200D\U00002642\U0000FE0F\U0001F9DF\U0001F9DF\U0000200D" + "\U00002640\U0000FE0F\U0001F9DF\U0000200D\U00002642\U0000FE0F" + "\U0001F9D6\U0001F9D6\U0001F3FB\U0001F9D6\U0001F3FC\U0001F9D6" + "\U0001F3FD\U0001F9D6\U0001F3FE\U0001F9D6\U0001F3FF\U0001F9D6" + "\U0000200D\U00002640\U0000FE0F\U0001F9D6\U0001F3FB\U0000200D" + "\U00002640\U0000FE0F\U0001F9D6\U0001F3FC\U0000200D\U00002640" + "\U0000FE0F\U0001F9D6\U0001F3FD\U0000200D\U00002640\U0000FE0F" + "\U0001F9D6\U0001F3FE\U0000200D\U00002640\U0000FE0F\U0001F9D6" + "\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9D6\U0000200D" + "\U00002642\U0000FE0F\U0001F9D6\U0001F3FB\U0000200D\U00002642" + "\U0000FE0F\U0001F9D6\U0001F3FC\U0000200D\U00002642\U0000FE0F" + "\U0001F9D6\U0001F3FD\U0000200D\U00002642\U0000FE0F\U0001F9D6" + "\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9D6\U0001F3FF" + "\U0000200D\U00002642\U0000FE0F\U0001F9D7\U0001F9D7\U0001F3FB" + "\U0001F9D7\U0001F3FC\U0001F9D7\U0001F3FD\U0001F9D7\U0001F3FE" + "\U0001F9D7\U0001F3FF\U0001F9D7\U0000200D\U00002640\U0000FE0F" + "\U0001F9D7\U0001F3FB\U0000200D\U00002640\U0000FE0F\U0001F9D7" + "\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9D7\U0001F3FD" + "\U0000200D\U00002640\U0000FE0F\U0001F9D7\U0001F3FE\U0000200D" + "\U00002640\U0000FE0F\U0001F9D7\U0001F3FF\U0000200D\U00002640" + "\U0000FE0F\U0001F9D7\U0000200D\U00002642\U0000FE0F\U0001F9D7" + "\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9D7\U0001F3FC" + "\U0000200D\U00002642\U0000FE0F\U0001F9D7\U0001F3FD\U0000200D" + "\U00002642\U0000FE0F\U0001F9D7\U0001F3FE\U0000200D\U00002642" + "\U0000FE0F\U0001F9D7\U0001F3FF\U0000200D\U00002642\U0000FE0F" + "\U0001F9D8\U0001F9D8\U0001F3FB\U0001F9D8\U0001F3FC\U0001F9D8" + "\U0001F3FD\U0001F9D8\U0001F3FE\U0001F9D8\U0001F3FF\U0001F9D8" + "\U0000200D\U00002640\U0000FE0F\U0001F9D8\U0001F3FB\U0000200D" + "\U00002640\U0000FE0F\U0001F9D8\U0001F3FC\U0000200D\U00002640" + "\U0000FE0F\U0001F9D8\U0001F3FD\U0000200D\U00002640\U0000FE0F" + "\U0001F9D8\U0001F3FE\U0000200D\U00002640\U0000FE0F\U0001F9D8" + "\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9D8\U0000200D" + "\U00002642\U0000FE0F\U0001F9D8\U0001F3FB\U0000200D\U00002642" + "\U0000FE0F\U0001F9D8\U0001F3FC\U0000200D\U00002642\U0000FE0F" + "\U0001F9D8\U0001F3FD\U0000200D\U00002642\U0000FE0F\U0001F9D8" + "\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9D8\U0001F3FF" + "\U0000200D\U00002642\U0000FE0F\U0001F91F\U0001F91F\U0001F3FB" + "\U0001F91F\U0001F3FC\U0001F91F\U0001F3FD\U0001F91F\U0001F3FE" + "\U0001F91F\U0001F3FF\U0001F932\U0001F932\U0001F3FB\U0001F932" + "\U0001F3FC\U0001F932\U0001F3FD\U0001F932\U0001F3FE\U0001F932" + "\U0001F3FF\U0001F9E0\U0001F9E1\U0001F9E3\U0001F9E4\U0001F9E5" + "\U0001F9E6\U0001F9E2\U0001F993\U0001F992\U0001F994\U0001F995" + "\U0001F996\U0001F997\U0001F965\U0001F966\U0001F968\U0001F969" + "\U0001F96A\U0001F963\U0001F96B\U0001F95F\U0001F960\U0001F961" + "\U0001F967\U0001F964\U0001F962\U0001F6F8\U0001F6F7\U0001F94C", FontFallbackPriority::kEmojiEmoji}}); } TEST_F(SymbolsIteratorTest, EmojiSubdivisionFlags) { - CheckRuns({{u8"\U0001F3F4\U000E0067\U000E0062\U000E0077\U000E006C\U000E0073" - u8"\U000E007F\U0001F3F4\U000E0067\U000E0062\U000E0073\U000E0063" - u8"\U000E0074\U000E007F\U0001F3F4", + CheckRuns({{"\U0001F3F4\U000E0067\U000E0062\U000E0077\U000E006C\U000E0073" + "\U000E007F\U0001F3F4\U000E0067\U000E0062\U000E0073\U000E0063" + "\U000E0074\U000E007F\U0001F3F4", FontFallbackPriority::kEmojiEmoji}, // Tag sequences on their own do not mean they're emoji. - {u8"\U000E0067\U000E0062", FontFallbackPriority::kText}}); + {"\U000E0067\U000E0062", FontFallbackPriority::kText}}); } // Extracted from http://unicode.org/emoji/charts/emoji-released.html for Emoji @@ -387,75 +386,75 @@ // presentation. TEST_F(SymbolsIteratorTest, Emoji11Additions) { CheckRuns( - {{u8"\U0001F970\U0001F975\U0001F976\U0001F973\U0001F974\U0001F97A" - u8"\U0001F468\U0000200D\U0001F9B0\U0001F468\U0001F3FB\U0000200D" - u8"\U0001F9B0\U0001F468\U0001F3FC\U0000200D\U0001F9B0\U0001F468" - u8"\U0001F3FD\U0000200D\U0001F9B0\U0001F468\U0001F3FE\U0000200D" - u8"\U0001F9B0\U0001F468\U0001F3FF\U0000200D\U0001F9B0\U0001F468" - u8"\U0000200D\U0001F9B1\U0001F468\U0001F3FB\U0000200D\U0001F9B1" - u8"\U0001F468\U0001F3FC\U0000200D\U0001F9B1\U0001F468\U0001F3FD" - u8"\U0000200D\U0001F9B1\U0001F468\U0001F3FE\U0000200D\U0001F9B1" - u8"\U0001F468\U0001F3FF\U0000200D\U0001F9B1\U0001F468\U0000200D" - u8"\U0001F9B3\U0001F468\U0001F3FB\U0000200D\U0001F9B3\U0001F468" - u8"\U0001F3FC\U0000200D\U0001F9B3\U0001F468\U0001F3FD\U0000200D" - u8"\U0001F9B3\U0001F468\U0001F3FE\U0000200D\U0001F9B3\U0001F468" - u8"\U0001F3FF\U0000200D\U0001F9B3\U0001F468\U0000200D\U0001F9B2" - u8"\U0001F468\U0001F3FB\U0000200D\U0001F9B2\U0001F468\U0001F3FC" - u8"\U0000200D\U0001F9B2\U0001F468\U0001F3FD\U0000200D\U0001F9B2" - u8"\U0001F468\U0001F3FE\U0000200D\U0001F9B2\U0001F468\U0001F3FF" - u8"\U0000200D\U0001F9B2\U0001F469\U0000200D\U0001F9B0\U0001F469" - u8"\U0001F3FB\U0000200D\U0001F9B0\U0001F469\U0001F3FC\U0000200D" - u8"\U0001F9B0\U0001F469\U0001F3FD\U0000200D\U0001F9B0\U0001F469" - u8"\U0001F3FE\U0000200D\U0001F9B0\U0001F469\U0001F3FF\U0000200D" - u8"\U0001F9B0\U0001F469\U0000200D\U0001F9B1\U0001F469\U0001F3FB" - u8"\U0000200D\U0001F9B1\U0001F469\U0001F3FC\U0000200D\U0001F9B1" - u8"\U0001F469\U0001F3FD\U0000200D\U0001F9B1\U0001F469\U0001F3FE" - u8"\U0000200D\U0001F9B1\U0001F469\U0001F3FF\U0000200D\U0001F9B1" - u8"\U0001F469\U0000200D\U0001F9B3\U0001F469\U0001F3FB\U0000200D" - u8"\U0001F9B3\U0001F469\U0001F3FC\U0000200D\U0001F9B3\U0001F469" - u8"\U0001F3FD\U0000200D\U0001F9B3\U0001F469\U0001F3FE\U0000200D" - u8"\U0001F9B3\U0001F469\U0001F3FF\U0000200D\U0001F9B3\U0001F469" - u8"\U0000200D\U0001F9B2\U0001F469\U0001F3FB\U0000200D\U0001F9B2" - u8"\U0001F469\U0001F3FC\U0000200D\U0001F9B2\U0001F469\U0001F3FD" - u8"\U0000200D\U0001F9B2\U0001F469\U0001F3FE\U0000200D\U0001F9B2" - u8"\U0001F469\U0001F3FF\U0000200D\U0001F9B2\U0001F9B8\U0001F9B8" - u8"\U0001F3FB\U0001F9B8\U0001F3FC\U0001F9B8\U0001F3FD\U0001F9B8" - u8"\U0001F3FE\U0001F9B8\U0001F3FF\U0001F9B8\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9B8\U0001F3FB\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9B8\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9B8" - u8"\U0001F3FD\U0000200D\U00002640\U0000FE0F\U0001F9B8\U0001F3FE" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9B8\U0001F3FF\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9B8\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9B8\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9B8" - u8"\U0001F3FC\U0000200D\U00002642\U0000FE0F\U0001F9B8\U0001F3FD" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9B8\U0001F3FE\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9B8\U0001F3FF\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9B9\U0001F9B9\U0001F3FB\U0001F9B9\U0001F3FC" - u8"\U0001F9B9\U0001F3FD\U0001F9B9\U0001F3FE\U0001F9B9\U0001F3FF" - u8"\U0001F9B9\U0000200D\U00002640\U0000FE0F\U0001F9B9\U0001F3FB" - u8"\U0000200D\U00002640\U0000FE0F\U0001F9B9\U0001F3FC\U0000200D" - u8"\U00002640\U0000FE0F\U0001F9B9\U0001F3FD\U0000200D\U00002640" - u8"\U0000FE0F\U0001F9B9\U0001F3FE\U0000200D\U00002640\U0000FE0F" - u8"\U0001F9B9\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9B9" - u8"\U0000200D\U00002642\U0000FE0F\U0001F9B9\U0001F3FB\U0000200D" - u8"\U00002642\U0000FE0F\U0001F9B9\U0001F3FC\U0000200D\U00002642" - u8"\U0000FE0F\U0001F9B9\U0001F3FD\U0000200D\U00002642\U0000FE0F" - u8"\U0001F9B9\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9B9" - u8"\U0001F3FF\U0000200D\U00002642\U0000FE0F\U0001F9B5\U0001F9B5" - u8"\U0001F3FB\U0001F9B5\U0001F3FC\U0001F9B5\U0001F3FD\U0001F9B5" - u8"\U0001F3FE\U0001F9B5\U0001F3FF\U0001F9B6\U0001F9B6\U0001F3FB" - u8"\U0001F9B6\U0001F3FC\U0001F9B6\U0001F3FD\U0001F9B6\U0001F3FE" - u8"\U0001F9B6\U0001F3FF\U0001F9B4\U0001F9B7\U0001F9B0\U0001F9B1" - u8"\U0001F9B3\U0001F9B2\U0001F97D\U0001F97C\U0001F97E\U0001F97F" - u8"\U0001F99D\U0001F999\U0001F99B\U0001F998\U0001F9A1\U0001F9A2" - u8"\U0001F99A\U0001F99C\U0001F99E\U0001F99F\U0001F9A0\U0001F96D" - u8"\U0001F96C\U0001F96F\U0001F9C2\U0001F96E\U0001F9C1\U0001F9ED" - u8"\U0001F9F1\U0001F6F9\U0001F9F3\U0001F9E8\U0001F9E7\U0001F94E" - u8"\U0001F94F\U0001F94D\U0001F9FF\U0001F9E9\U0001F9F8\U0001F9F5" - u8"\U0001F9F6\U0001F9EE\U0001F9FE\U0001F9F0\U0001F9F2\U0001F9EA" - u8"\U0001F9EB\U0001F9EC\U0001F9F4\U0001F9F7\U0001F9F9\U0001F9FA" - u8"\U0001F9FB\U0001F9FC\U0001F9FD\U0001F9EF\U0001F3F4\U0000200D" - u8"\U00002620\U0000FE0F", + {{"\U0001F970\U0001F975\U0001F976\U0001F973\U0001F974\U0001F97A" + "\U0001F468\U0000200D\U0001F9B0\U0001F468\U0001F3FB\U0000200D" + "\U0001F9B0\U0001F468\U0001F3FC\U0000200D\U0001F9B0\U0001F468" + "\U0001F3FD\U0000200D\U0001F9B0\U0001F468\U0001F3FE\U0000200D" + "\U0001F9B0\U0001F468\U0001F3FF\U0000200D\U0001F9B0\U0001F468" + "\U0000200D\U0001F9B1\U0001F468\U0001F3FB\U0000200D\U0001F9B1" + "\U0001F468\U0001F3FC\U0000200D\U0001F9B1\U0001F468\U0001F3FD" + "\U0000200D\U0001F9B1\U0001F468\U0001F3FE\U0000200D\U0001F9B1" + "\U0001F468\U0001F3FF\U0000200D\U0001F9B1\U0001F468\U0000200D" + "\U0001F9B3\U0001F468\U0001F3FB\U0000200D\U0001F9B3\U0001F468" + "\U0001F3FC\U0000200D\U0001F9B3\U0001F468\U0001F3FD\U0000200D" + "\U0001F9B3\U0001F468\U0001F3FE\U0000200D\U0001F9B3\U0001F468" + "\U0001F3FF\U0000200D\U0001F9B3\U0001F468\U0000200D\U0001F9B2" + "\U0001F468\U0001F3FB\U0000200D\U0001F9B2\U0001F468\U0001F3FC" + "\U0000200D\U0001F9B2\U0001F468\U0001F3FD\U0000200D\U0001F9B2" + "\U0001F468\U0001F3FE\U0000200D\U0001F9B2\U0001F468\U0001F3FF" + "\U0000200D\U0001F9B2\U0001F469\U0000200D\U0001F9B0\U0001F469" + "\U0001F3FB\U0000200D\U0001F9B0\U0001F469\U0001F3FC\U0000200D" + "\U0001F9B0\U0001F469\U0001F3FD\U0000200D\U0001F9B0\U0001F469" + "\U0001F3FE\U0000200D\U0001F9B0\U0001F469\U0001F3FF\U0000200D" + "\U0001F9B0\U0001F469\U0000200D\U0001F9B1\U0001F469\U0001F3FB" + "\U0000200D\U0001F9B1\U0001F469\U0001F3FC\U0000200D\U0001F9B1" + "\U0001F469\U0001F3FD\U0000200D\U0001F9B1\U0001F469\U0001F3FE" + "\U0000200D\U0001F9B1\U0001F469\U0001F3FF\U0000200D\U0001F9B1" + "\U0001F469\U0000200D\U0001F9B3\U0001F469\U0001F3FB\U0000200D" + "\U0001F9B3\U0001F469\U0001F3FC\U0000200D\U0001F9B3\U0001F469" + "\U0001F3FD\U0000200D\U0001F9B3\U0001F469\U0001F3FE\U0000200D" + "\U0001F9B3\U0001F469\U0001F3FF\U0000200D\U0001F9B3\U0001F469" + "\U0000200D\U0001F9B2\U0001F469\U0001F3FB\U0000200D\U0001F9B2" + "\U0001F469\U0001F3FC\U0000200D\U0001F9B2\U0001F469\U0001F3FD" + "\U0000200D\U0001F9B2\U0001F469\U0001F3FE\U0000200D\U0001F9B2" + "\U0001F469\U0001F3FF\U0000200D\U0001F9B2\U0001F9B8\U0001F9B8" + "\U0001F3FB\U0001F9B8\U0001F3FC\U0001F9B8\U0001F3FD\U0001F9B8" + "\U0001F3FE\U0001F9B8\U0001F3FF\U0001F9B8\U0000200D\U00002640" + "\U0000FE0F\U0001F9B8\U0001F3FB\U0000200D\U00002640\U0000FE0F" + "\U0001F9B8\U0001F3FC\U0000200D\U00002640\U0000FE0F\U0001F9B8" + "\U0001F3FD\U0000200D\U00002640\U0000FE0F\U0001F9B8\U0001F3FE" + "\U0000200D\U00002640\U0000FE0F\U0001F9B8\U0001F3FF\U0000200D" + "\U00002640\U0000FE0F\U0001F9B8\U0000200D\U00002642\U0000FE0F" + "\U0001F9B8\U0001F3FB\U0000200D\U00002642\U0000FE0F\U0001F9B8" + "\U0001F3FC\U0000200D\U00002642\U0000FE0F\U0001F9B8\U0001F3FD" + "\U0000200D\U00002642\U0000FE0F\U0001F9B8\U0001F3FE\U0000200D" + "\U00002642\U0000FE0F\U0001F9B8\U0001F3FF\U0000200D\U00002642" + "\U0000FE0F\U0001F9B9\U0001F9B9\U0001F3FB\U0001F9B9\U0001F3FC" + "\U0001F9B9\U0001F3FD\U0001F9B9\U0001F3FE\U0001F9B9\U0001F3FF" + "\U0001F9B9\U0000200D\U00002640\U0000FE0F\U0001F9B9\U0001F3FB" + "\U0000200D\U00002640\U0000FE0F\U0001F9B9\U0001F3FC\U0000200D" + "\U00002640\U0000FE0F\U0001F9B9\U0001F3FD\U0000200D\U00002640" + "\U0000FE0F\U0001F9B9\U0001F3FE\U0000200D\U00002640\U0000FE0F" + "\U0001F9B9\U0001F3FF\U0000200D\U00002640\U0000FE0F\U0001F9B9" + "\U0000200D\U00002642\U0000FE0F\U0001F9B9\U0001F3FB\U0000200D" + "\U00002642\U0000FE0F\U0001F9B9\U0001F3FC\U0000200D\U00002642" + "\U0000FE0F\U0001F9B9\U0001F3FD\U0000200D\U00002642\U0000FE0F" + "\U0001F9B9\U0001F3FE\U0000200D\U00002642\U0000FE0F\U0001F9B9" + "\U0001F3FF\U0000200D\U00002642\U0000FE0F\U0001F9B5\U0001F9B5" + "\U0001F3FB\U0001F9B5\U0001F3FC\U0001F9B5\U0001F3FD\U0001F9B5" + "\U0001F3FE\U0001F9B5\U0001F3FF\U0001F9B6\U0001F9B6\U0001F3FB" + "\U0001F9B6\U0001F3FC\U0001F9B6\U0001F3FD\U0001F9B6\U0001F3FE" + "\U0001F9B6\U0001F3FF\U0001F9B4\U0001F9B7\U0001F9B0\U0001F9B1" + "\U0001F9B3\U0001F9B2\U0001F97D\U0001F97C\U0001F97E\U0001F97F" + "\U0001F99D\U0001F999\U0001F99B\U0001F998\U0001F9A1\U0001F9A2" + "\U0001F99A\U0001F99C\U0001F99E\U0001F99F\U0001F9A0\U0001F96D" + "\U0001F96C\U0001F96F\U0001F9C2\U0001F96E\U0001F9C1\U0001F9ED" + "\U0001F9F1\U0001F6F9\U0001F9F3\U0001F9E8\U0001F9E7\U0001F94E" + "\U0001F94F\U0001F94D\U0001F9FF\U0001F9E9\U0001F9F8\U0001F9F5" + "\U0001F9F6\U0001F9EE\U0001F9FE\U0001F9F0\U0001F9F2\U0001F9EA" + "\U0001F9EB\U0001F9EC\U0001F9F4\U0001F9F7\U0001F9F9\U0001F9FA" + "\U0001F9FB\U0001F9FC\U0001F9FD\U0001F9EF\U0001F3F4\U0000200D" + "\U00002620\U0000FE0F", FontFallbackPriority::kEmojiEmoji}}); }
diff --git a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc index 648f25d..75d7af9 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
@@ -34,7 +34,7 @@ return gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020, gfx::ColorSpace::TransferID::PQ); case PredefinedColorSpace::kSRGBLinear: - return gfx::ColorSpace::CreateSCRGBLinear(); + return gfx::ColorSpace::CreateSRGBLinear(); } NOTREACHED(); }
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h index 994fc8bb..25773d4 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h
@@ -357,12 +357,16 @@ bool Initialize(const gfx::Size&, bool use_multisampling); struct RegisteredBitmap { - scoped_refptr<cc::CrossThreadSharedBitmap> bitmap; - cc::SharedBitmapIdRegistration registration; + RegisteredBitmap(scoped_refptr<cc::CrossThreadSharedBitmap> bitmap, + cc::SharedBitmapIdRegistration registration) + : bitmap(std::move(bitmap)), registration(std::move(registration)) {} // Explicitly move-only. RegisteredBitmap(RegisteredBitmap&&) = default; RegisteredBitmap& operator=(RegisteredBitmap&&) = default; + + scoped_refptr<cc::CrossThreadSharedBitmap> bitmap; + cc::SharedBitmapIdRegistration registration; }; // Shared memory bitmaps that were released by the compositor and can be used // again by this DrawingBuffer.
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h index 41ce2ea..d48c9f2 100644 --- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h +++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h
@@ -131,12 +131,12 @@ return Matrix().ToSkM44().asM33(); } - bool operator==(const Translation2DOrMatrix& other) { + bool operator==(const Translation2DOrMatrix& other) const { return translation_2d_ == other.translation_2d_ && matrix_ == other.matrix_; } - bool operator!=(const Translation2DOrMatrix& other) { + bool operator!=(const Translation2DOrMatrix& other) const { return !(*this == other); }
diff --git a/third_party/blink/renderer/platform/text/platform_locale_test.cc b/third_party/blink/renderer/platform/text/platform_locale_test.cc index 1e8e041..43d24e6 100644 --- a/third_party/blink/renderer/platform/text/platform_locale_test.cc +++ b/third_party/blink/renderer/platform/text/platform_locale_test.cc
@@ -14,8 +14,8 @@ // uses Extened Arabic-Indic digits. std::unique_ptr<Locale> locale = Locale::Create("fa"); String result = locale->StripInvalidNumberCharacters( - String::FromUTF8(u8"abc\u06F0ghi"), "0123456789"); + String::FromUTF8("abc\u06F0ghi"), "0123456789"); // EXTENDED ARABIC-INDIC DIGIT ZERO U+06F0 - EXPECT_EQ(String::FromUTF8(u8"\u06F0"), result); + EXPECT_EQ(String::FromUTF8("\u06F0"), result); } }
diff --git a/third_party/blink/renderer/platform/text/text_break_iterator_test.cc b/third_party/blink/renderer/platform/text/text_break_iterator_test.cc index c5f2ee5..81f9bdf50 100644 --- a/third_party/blink/renderer/platform/text/text_break_iterator_test.cc +++ b/third_party/blink/renderer/platform/text/text_break_iterator_test.cc
@@ -170,7 +170,7 @@ } TEST_F(TextBreakIteratorTest, KeepEmojiZWJFamilyIsolate) { - SetTestString(u8"\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466"); + SetTestString("\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466"); MatchLineBreaks(LineBreakType::kNormal, {11}); MatchLineBreaks(LineBreakType::kBreakAll, {11}); MatchLineBreaks(LineBreakType::kBreakCharacter, {11}); @@ -178,7 +178,7 @@ } TEST_F(TextBreakIteratorTest, KeepEmojiModifierSequenceIsolate) { - SetTestString(u8"\u261D\U0001F3FB"); + SetTestString("\u261D\U0001F3FB"); MatchLineBreaks(LineBreakType::kNormal, {3}); MatchLineBreaks(LineBreakType::kBreakAll, {3}); MatchLineBreaks(LineBreakType::kBreakCharacter, {3}); @@ -187,7 +187,7 @@ TEST_F(TextBreakIteratorTest, KeepEmojiZWJSequence) { SetTestString( - u8"abc \U0001F469\u200D\U0001F469\u200D\U0001F467\u200D\U0001F467 def"); + "abc \U0001F469\u200D\U0001F469\u200D\U0001F467\u200D\U0001F467 def"); MatchLineBreaks(LineBreakType::kNormal, {3, 15, 19}); MatchLineBreaks(LineBreakType::kBreakAll, {1, 2, 3, 15, 17, 18, 19}); MatchLineBreaks(LineBreakType::kBreakCharacter, @@ -196,7 +196,7 @@ } TEST_F(TextBreakIteratorTest, KeepEmojiModifierSequence) { - SetTestString(u8"abc \u261D\U0001F3FB def"); + SetTestString("abc \u261D\U0001F3FB def"); MatchLineBreaks(LineBreakType::kNormal, {3, 7, 11}); MatchLineBreaks(LineBreakType::kBreakAll, {1, 2, 3, 7, 9, 10, 11}); MatchLineBreaks(LineBreakType::kBreakCharacter,
diff --git a/third_party/blink/renderer/platform/text/text_run_iterator.h b/third_party/blink/renderer/platform/text/text_run_iterator.h index c23a96af..bfd8f0c9 100644 --- a/third_party/blink/renderer/platform/text/text_run_iterator.h +++ b/third_party/blink/renderer/platform/text/text_run_iterator.h
@@ -57,11 +57,13 @@ } bool AtParagraphSeparator() const { return Current() == '\n'; } - bool operator==(const TextRunIterator& other) { + bool operator==(const TextRunIterator& other) const { return offset_ == other.offset_ && text_run_ == other.text_run_; } - bool operator!=(const TextRunIterator& other) { return !operator==(other); } + bool operator!=(const TextRunIterator& other) const { + return !operator==(other); + } private: const TextRun* text_run_;
diff --git a/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.cc b/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.cc index a28a557..a6059a1 100644 --- a/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.cc +++ b/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.cc
@@ -32,10 +32,8 @@ namespace blink { -bool InterpolatedTransformOperation::operator==( +bool InterpolatedTransformOperation::IsEqualAssumingSameType( const TransformOperation& o) const { - if (!IsSameType(o)) - return false; const InterpolatedTransformOperation* t = static_cast<const InterpolatedTransformOperation*>(&o); return progress_ == t->progress_ && from_ == t->from_ && to_ == t->to_;
diff --git a/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h b/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h index 163695e..1370a774 100644 --- a/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h +++ b/third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h
@@ -51,10 +51,12 @@ new InterpolatedTransformOperation(from, to, starting_index, progress)); } + protected: + bool IsEqualAssumingSameType(const TransformOperation&) const override; + private: OperationType GetType() const override { return kInterpolated; } - bool operator==(const TransformOperation&) const override; void Apply(TransformationMatrix&, const gfx::SizeF& border_box_size) const override;
diff --git a/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h b/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h index a0c2357..79a2313 100644 --- a/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h +++ b/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h
@@ -45,17 +45,16 @@ return type == kMatrix3D; } - private: - OperationType GetType() const override { return kMatrix3D; } - - bool operator==(const TransformOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const TransformOperation& o) const override { const Matrix3DTransformOperation* m = static_cast<const Matrix3DTransformOperation*>(&o); return matrix_ == m->matrix_; } + private: + OperationType GetType() const override { return kMatrix3D; } + void Apply(TransformationMatrix& transform, const gfx::SizeF&) const override { transform.Multiply(TransformationMatrix(matrix_));
diff --git a/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h b/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h index 9ff6a420..95666fb 100644 --- a/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h +++ b/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h
@@ -56,19 +56,17 @@ return type == kMatrix; } - private: - OperationType GetType() const override { return kMatrix; } - - bool operator==(const TransformOperation& o) const override { - if (!IsSameType(o)) - return false; - + protected: + bool IsEqualAssumingSameType(const TransformOperation& o) const override { const MatrixTransformOperation* m = static_cast<const MatrixTransformOperation*>(&o); return a_ == m->a_ && b_ == m->b_ && c_ == m->c_ && d_ == m->d_ && e_ == m->e_ && f_ == m->f_; } + private: + OperationType GetType() const override { return kMatrix; } + void Apply(TransformationMatrix& transform, const gfx::SizeF&) const override { TransformationMatrix matrix(a_, b_, c_, d_, e_, f_);
diff --git a/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h b/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h index 396c984..a91964c 100644 --- a/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h +++ b/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
@@ -59,17 +59,16 @@ return type == kPerspective; } - private: - OperationType GetType() const override { return kPerspective; } - - bool operator==(const TransformOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const TransformOperation& o) const override { const PerspectiveTransformOperation* p = static_cast<const PerspectiveTransformOperation*>(&o); return p_ == p->p_; } + private: + OperationType GetType() const override { return kPerspective; } + void Apply(TransformationMatrix& transform, const gfx::SizeF&) const override { if (Perspective()) {
diff --git a/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc b/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc index 97806ea..d9eb65f5 100644 --- a/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc +++ b/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc
@@ -39,10 +39,8 @@ } } // namespace -bool RotateTransformOperation::operator==( +bool RotateTransformOperation::IsEqualAssumingSameType( const TransformOperation& other) const { - if (!IsSameType(other)) - return false; const auto& other_rotation = To<RotateTransformOperation>(other).rotation_; return rotation_.axis == other_rotation.axis && rotation_.angle == other_rotation.angle; @@ -112,10 +110,8 @@ transform.Translate(-origin_x_, -origin_y_); } -bool RotateAroundOriginTransformOperation::operator==( +bool RotateAroundOriginTransformOperation::IsEqualAssumingSameType( const TransformOperation& other) const { - if (!IsSameType(other)) - return false; const auto& other_rotate = To<RotateAroundOriginTransformOperation>(other); const Rotation& other_rotation = other_rotate.rotation_; return rotation_.axis == other_rotation.axis &&
diff --git a/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h b/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h index c5adeaf2..685ccf2 100644 --- a/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h +++ b/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h
@@ -54,10 +54,6 @@ return base::AdoptRef(new RotateTransformOperation(rotation, type)); } - bool operator==(const RotateTransformOperation& other) const { - return *this == static_cast<const TransformOperation&>(other); - } - double X() const { return rotation_.axis.x(); } double Y() const { return rotation_.axis.y(); } double Z() const { return rotation_.axis.z(); } @@ -84,7 +80,7 @@ } protected: - bool operator==(const TransformOperation&) const override; + bool IsEqualAssumingSameType(const TransformOperation&) const override; bool HasNonTrivial3DComponent() const override { return Angle() && (X() || Y()); @@ -131,13 +127,14 @@ } OperationType PrimitiveType() const override { return kRotateAroundOrigin; } + protected: + bool IsEqualAssumingSameType(const TransformOperation&) const override; + private: RotateAroundOriginTransformOperation(double angle, double origin_x, double origin_y); - bool operator==(const TransformOperation&) const override; - scoped_refptr<TransformOperation> Blend( const TransformOperation* from, double progress,
diff --git a/third_party/blink/renderer/platform/transforms/scale_transform_operation.h b/third_party/blink/renderer/platform/transforms/scale_transform_operation.h index bc3c549..e4a4c08 100644 --- a/third_party/blink/renderer/platform/transforms/scale_transform_operation.h +++ b/third_party/blink/renderer/platform/transforms/scale_transform_operation.h
@@ -46,10 +46,6 @@ return base::AdoptRef(new ScaleTransformOperation(sx, sy, sz, type)); } - bool operator==(const ScaleTransformOperation& other) const { - return *this == static_cast<const TransformOperation&>(other); - } - double X() const { return x_; } double Y() const { return y_; } double Z() const { return z_; } @@ -73,15 +69,14 @@ OperationType GetType() const override { return type_; } OperationType PrimitiveType() const final { return kScale3D; } - private: - bool operator==(const TransformOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const TransformOperation& o) const override { const ScaleTransformOperation* s = static_cast<const ScaleTransformOperation*>(&o); return x_ == s->x_ && y_ == s->y_ && z_ == s->z_; } + private: bool HasNonTrivial3DComponent() const override { return z_ != 1.0; } void CommonPrimitiveForInterpolation(
diff --git a/third_party/blink/renderer/platform/transforms/skew_transform_operation.h b/third_party/blink/renderer/platform/transforms/skew_transform_operation.h index de198de..8c02098 100644 --- a/third_party/blink/renderer/platform/transforms/skew_transform_operation.h +++ b/third_party/blink/renderer/platform/transforms/skew_transform_operation.h
@@ -46,17 +46,16 @@ return type == kSkewX || type == kSkewY || type == kSkew; } - private: - OperationType GetType() const override { return type_; } - - bool operator==(const TransformOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const TransformOperation& o) const override { const SkewTransformOperation* s = static_cast<const SkewTransformOperation*>(&o); return angle_x_ == s->angle_x_ && angle_y_ == s->angle_y_; } + private: + OperationType GetType() const override { return type_; } + void Apply(TransformationMatrix& transform, const gfx::SizeF&) const override { transform.Skew(angle_x_, angle_y_);
diff --git a/third_party/blink/renderer/platform/transforms/transform_operation.h b/third_party/blink/renderer/platform/transforms/transform_operation.h index c365a84..21f1bd20 100644 --- a/third_party/blink/renderer/platform/transforms/transform_operation.h +++ b/third_party/blink/renderer/platform/transforms/transform_operation.h
@@ -68,7 +68,9 @@ TransformOperation& operator=(const TransformOperation&) = delete; virtual ~TransformOperation() = default; - virtual bool operator==(const TransformOperation&) const = 0; + bool operator==(const TransformOperation& o) const { + return IsSameType(o) && IsEqualAssumingSameType(o); + } bool operator!=(const TransformOperation& o) const { return !(*this == o); } virtual void Apply(TransformationMatrix&, @@ -123,6 +125,9 @@ BoxSizeDependency b) { return static_cast<BoxSizeDependency>(a | b); } + + protected: + virtual bool IsEqualAssumingSameType(const TransformOperation&) const = 0; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/transforms/translate_transform_operation.h b/third_party/blink/renderer/platform/transforms/translate_transform_operation.h index b0880395..5d84c08e 100644 --- a/third_party/blink/renderer/platform/transforms/translate_transform_operation.h +++ b/third_party/blink/renderer/platform/transforms/translate_transform_operation.h
@@ -48,10 +48,6 @@ return base::AdoptRef(new TranslateTransformOperation(tx, ty, tz, type)); } - bool operator==(const TranslateTransformOperation& other) const { - return *this == static_cast<const TransformOperation&>(other); - } - BoxSizeDependency BoxSizeDependencies() const override { return CombineDependencies( (x_.IsPercentOrCalc() ? kDependsWidth : kDependsNone), @@ -84,15 +80,14 @@ OperationType GetType() const override { return type_; } OperationType PrimitiveType() const final { return kTranslate3D; } - private: - bool operator==(const TransformOperation& o) const override { - if (!IsSameType(o)) - return false; + protected: + bool IsEqualAssumingSameType(const TransformOperation& o) const override { const TranslateTransformOperation* t = static_cast<const TranslateTransformOperation*>(&o); return x_ == t->x_ && y_ == t->y_ && z_ == t->z_; } + private: scoped_refptr<TransformOperation> Accumulate( const TransformOperation& other) override; scoped_refptr<TransformOperation> Blend(
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm.https.html.headers b/third_party/blink/web_tests/external/wpt/credential-management/fedcm.https.html.headers index e907cdd..408f7825 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/fedcm.https.html.headers +++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm.https.html.headers
@@ -1 +1 @@ -Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src https://idp.test +Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src https://idp.test/never/used/path
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/table/border-spacing.html b/third_party/blink/web_tests/external/wpt/css/css-break/table/border-spacing.html new file mode 100644 index 0000000..fc5e87e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/table/border-spacing.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=534751"> +<style> + .cell > div { background:white; } +</style> +<p>No red should be seen below.</p> +<div id="multicol" style="columns:2; column-fill:auto; height:70px; width:200px; line-height:20px;"> + <div style="position:relative; display:table; border-spacing:10px;"> + <div class="cell" style="display:table-cell; width:30px; background:red;"> + <div id="child1">1<br></div> + <div id="child2">2<br></div> + <div id="child3">3<br></div> + <div id="child4">4<br></div> + <div id="child5">5<br></div> + </div> + </div> +</div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + test(() => { + assert_equals(document.getElementById("child1").offsetTop, 10); + assert_equals(document.getElementById("child1").offsetHeight, 20); + assert_equals(document.getElementById("child2").offsetTop, 30); + assert_equals(document.getElementById("child2").offsetHeight, 20); + assert_equals(document.getElementById("child3").offsetTop, 50); + assert_equals(document.getElementById("child3").offsetHeight, 20); + assert_equals(document.getElementById("child4").offsetTop, 70); + assert_equals(document.getElementById("child4").offsetHeight, 20); + assert_equals(document.getElementById("child5").offsetTop, 90); + assert_equals(document.getElementById("child5").offsetHeight, 20); + }, "Table with border spacing"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/render-blocking/non-render-blocking-scripts.optional.html b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking/non-render-blocking-scripts.optional.html new file mode 100644 index 0000000..a4c32ea --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking/non-render-blocking-scripts.optional.html
@@ -0,0 +1,61 @@ +<!DOCTYPE html> +<title>Tests when script is not implicitly potentially render-blocking</title> +<link rel="help" href="https://github.com/whatwg/html/pull/7894"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/test-render-blocking.js"></script> + +<!-- + The test is marked "optional" because even when the document is not + render-blocked, the user agent is still free to take other factors, which are + not limited by the spec, into consideration and therefore decide not to + render. However, it is still more desirable if rendering starts + immediately/soon. +--> + +<script class="test" data="parser-inserted async script" async + src="support/dummy-1.js?pipe=trickle(d1)&async"></script> +<script class="test" data="parser-inserted defer script" defer + src="support/dummy-1.js?pipe=trickle(d1)&defer"></script> +<script class="test" data="parser-inserted module script" type="module" + src="support/dummy-1.mjs?pipe=trickle(d1)"></script> +<script class="test" data="parser-inserted async module script" type="module" + async src="support/dummy-1.mjs?pipe=trickle(d1)&async"></script> + +<script> +function addTestScriptElement(title, attributes) { + let element = document.createElement('script'); + element.className = 'test'; + element.setAttribute('data', title); + Object.assign(element, attributes); + document.head.appendChild(element); +} + +addTestScriptElement('script-inserted script', {src: 'support/dummy-1.js?pipe=trickle(d1)&dynamic'}); +addTestScriptElement('script-inserted sync script', {async: false, src: 'support/dummy-1.js?pipe=trickle(d1)&dynamicSync'}); +addTestScriptElement('script-inserted module script', {type: 'module', src: 'support/dummy-1.mjs?pipe=trickle(d1)&dynamic'}); +</script> + +<div id="dummy">Some text</div> + +<script> +const testElements = [...document.querySelectorAll('.test')]; +const loadObservers = testElements.map(element => new LoadObserver(element)); + +promise_setup(async () => { + // Test cases are run after rendering is unblocked. + await new Promise(resolve => requestAnimationFrame(resolve)); +}); + +for (let index = 0; index < testElements.length; ++index) { + promise_test( + async () => assert_false(loadObservers[index].finished), + testElements[index].getAttribute('data') + ' is not implicitly render-blocking'); +} + +for (let index = 0; index < testElements.length; ++index) { + promise_test( + () => loadObservers[index].load, + testElements[index].getAttribute('data') + ' should eventually be loaded and evaluated'); +} +</script>
diff --git a/third_party/blink/web_tests/fragmentation/table-with-border-spacing.html b/third_party/blink/web_tests/fragmentation/table-with-border-spacing.html deleted file mode 100644 index 1b3f242..0000000 --- a/third_party/blink/web_tests/fragmentation/table-with-border-spacing.html +++ /dev/null
@@ -1,32 +0,0 @@ -<!DOCTYPE html> -<style> - .cell > div { background:white; } -</style> -<p>No red should be seen below.</p> -<div id="multicol" style="columns:2; column-fill:auto; height:70px; width:200px; line-height:20px;"> - <div style="position:relative; display:table; border-spacing:10px;"> - <div class="cell" style="display:table-cell; width:30px; background:red;"> - <div id="child1">1<br></div> - <div id="child2">2<br></div> - <div id="child3">3<br></div> - <div id="child4">4<br></div> - <div id="child5">5<br></div> - </div> - </div> -</div> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script> - test(() => { - assert_equals(document.getElementById("child1").offsetTop, 10); - assert_equals(document.getElementById("child1").offsetHeight, 20); - assert_equals(document.getElementById("child2").offsetTop, 30); - assert_equals(document.getElementById("child2").offsetHeight, 20); - assert_equals(document.getElementById("child3").offsetTop, 50); - assert_equals(document.getElementById("child3").offsetHeight, 20); - assert_equals(document.getElementById("child4").offsetTop, 70); - assert_equals(document.getElementById("child4").offsetHeight, 20); - assert_equals(document.getElementById("child5").offsetTop, 90); - assert_equals(document.getElementById("child5").offsetHeight, 20); - }, "Table with border spacing"); -</script>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/ready-state-change-crash.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/ready-state-change-crash.https.html new file mode 100644 index 0000000..c272c9d --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/ready-state-change-crash.https.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +Test passes if it does not crash. +<body> +<div id="a"></div> +<div id="b"> + <iframe id="f" src="about:blank"></iframe> +</div> + +<script> +if (window.testRunner) + testRunner.dumpAsText(); + +var listenerActive = false; +var inner_doc = document.getElementById('f').contentDocument; +inner_doc.open(); + +inner_doc.addEventListener('readystatechange', () => { + document.getElementById('a').appendChild(document.getElementById('b')); +}); + +inner_doc.close(); +</script> +</body> +</html>
diff --git a/third_party/polymer/v3_0/chromium.patch b/third_party/polymer/v3_0/chromium.patch index b084e0f6..b5a0653 100644 --- a/third_party/polymer/v3_0/chromium.patch +++ b/third_party/polymer/v3_0/chromium.patch
@@ -171,45 +171,6 @@ /** * @struct -diff --git a/components-chromium/paper-tooltip/paper-tooltip.js b/components-chromium/paper-tooltip/paper-tooltip.js -index 853eee199025..303d1bbdfc78 100644 ---- a/components-chromium/paper-tooltip/paper-tooltip.js -+++ b/components-chromium/paper-tooltip/paper-tooltip.js -@@ -311,12 +311,16 @@ Polymer({ - - /** - * Returns the target element that this tooltip is anchored to. It is -- * either the element given by the `for` attribute, or the immediate parent -- * of the tooltip. -+ * either the element given by the `for` attribute, the element manually -+ * specified through the `target` attribute, or the immediate parent of -+ * the tooltip. - * - * @type {Node} - */ - get target() { -+ if (this._manualTarget) -+ return this._manualTarget; -+ - var parentNode = dom(this).parentNode; - // If the parentNode is a document fragment, then we need to use the host. - var ownerRoot = dom(this).getOwnerRoot(); -@@ -331,6 +335,15 @@ Polymer({ - return target; - }, - -+ /** -+ * Sets the target element that this tooltip will be anchored to. -+ * @param {Node} target -+ */ -+ set target(target) { -+ this._manualTarget = target; -+ this._findTarget(); -+ }, -+ - /** - * @return {void} - */ diff --git a/components-chromium/paper-styles/color.js b/components-chromium/paper-styles/color.js index 6af2fa359336..c56a6737e1d8 100644 --- a/components-chromium/paper-styles/color.js @@ -433,72 +394,3 @@ --paper-grey-50: #fafafa; --paper-grey-100: #f5f5f5; --paper-grey-200: #eeeeee; -diff --git a/components-chromium/paper-tooltip/paper-tooltip.js b/components-chromium/paper-tooltip/paper-tooltip.js -index 303d1bbdfc787..4adc8ea38d760 100644 ---- a/components-chromium/paper-tooltip/paper-tooltip.js -+++ b/components-chromium/paper-tooltip/paper-tooltip.js -@@ -442,13 +442,16 @@ Polymer({ - * @return {void} - */ - updatePosition: function() { -- if (!this._target || !this.offsetParent) -+ if (!this._target) -+ return; -+ var offsetParent = this._composedOffsetParent(); -+ if (!offsetParent) - return; - var offset = this.offset; - // If a marginTop has been provided by the user (pre 1.0.3), use it. - if (this.marginTop != 14 && this.offset == 14) - offset = this.marginTop; -- var parentRect = this.offsetParent.getBoundingClientRect(); -+ var parentRect = offsetParent.getBoundingClientRect(); - var targetRect = this._target.getBoundingClientRect(); - var thisRect = this.getBoundingClientRect(); - var horizontalCenterOffset = (targetRect.width - thisRect.width) / 2; -@@ -594,5 +597,45 @@ Polymer({ - } - this.unlisten(this.$.tooltip, 'animationend', '_onAnimationEnd'); - this.unlisten(this, 'mouseenter', 'hide'); -+ }, -+ -+ /** -+ * Polyfills the old offsetParent behavior from before the spec was changed: -+ * https://github.com/w3c/csswg-drafts/issues/159 -+ */ -+ _composedOffsetParent: function() { -+ // Do an initial walk to check for display:none ancestors. -+ for (let ancestor = this; ancestor; ancestor = flatTreeParent(ancestor)) { -+ if (!(ancestor instanceof Element)) -+ continue; -+ if (getComputedStyle(ancestor).display === 'none') -+ return null; -+ } -+ -+ for (let ancestor = flatTreeParent(this); ancestor; ancestor = flatTreeParent(ancestor)) { -+ if (!(ancestor instanceof Element)) -+ continue; -+ const style = getComputedStyle(ancestor); -+ if (style.display === 'contents') { -+ // display:contents nodes aren't in the layout tree so they should be skipped. -+ continue; -+ } -+ if (style.position !== 'static') { -+ return ancestor; -+ } -+ if (ancestor.tagName === 'BODY') -+ return ancestor; -+ } -+ return null; -+ -+ function flatTreeParent(element) { -+ if (element.assignedSlot) { -+ return element.assignedSlot; -+ } -+ if (element.parentNode instanceof ShadowRoot) { -+ return element.parentNode.host; -+ } -+ return element.parentNode; -+ } - } - });
diff --git a/third_party/polymer/v3_0/components-chromium/paper-tooltip/paper-tooltip.js b/third_party/polymer/v3_0/components-chromium/paper-tooltip/paper-tooltip.js index 4adc8ea..e5b650d 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-tooltip/paper-tooltip.js +++ b/third_party/polymer/v3_0/components-chromium/paper-tooltip/paper-tooltip.js
@@ -74,7 +74,6 @@ color: var(--paper-tooltip-text-color, white); padding: 8px; border-radius: 2px; - @apply --paper-tooltip; } @keyframes keyFrameScaleUp { @@ -222,7 +221,7 @@ } </style> - <div id="tooltip" class="hidden"> + <div id="tooltip" class="hidden" part="tooltip"> <slot></slot> </div> `,
diff --git a/third_party/polymer/v3_0/paper_tooltip.patch b/third_party/polymer/v3_0/paper_tooltip.patch new file mode 100644 index 0000000..5d6f2cc2 --- /dev/null +++ b/third_party/polymer/v3_0/paper_tooltip.patch
@@ -0,0 +1,121 @@ +diff --git a/components-chromium/paper-tooltip/paper-tooltip.js b/components-chromium/paper-tooltip/paper-tooltip.js +index 853eee1990258..e5b650de76462 100644 +--- a/components-chromium/paper-tooltip/paper-tooltip.js ++++ b/components-chromium/paper-tooltip/paper-tooltip.js +@@ -74,7 +74,6 @@ Polymer({ + color: var(--paper-tooltip-text-color, white); + padding: 8px; + border-radius: 2px; +- @apply --paper-tooltip; + } + + @keyframes keyFrameScaleUp { +@@ -222,7 +221,7 @@ Polymer({ + } + </style> + +- <div id="tooltip" class="hidden"> ++ <div id="tooltip" class="hidden" part="tooltip"> + <slot></slot> + </div> + `, +@@ -311,12 +310,16 @@ Polymer({ + + /** + * Returns the target element that this tooltip is anchored to. It is +- * either the element given by the `for` attribute, or the immediate parent +- * of the tooltip. ++ * either the element given by the `for` attribute, the element manually ++ * specified through the `target` attribute, or the immediate parent of ++ * the tooltip. + * + * @type {Node} + */ + get target() { ++ if (this._manualTarget) ++ return this._manualTarget; ++ + var parentNode = dom(this).parentNode; + // If the parentNode is a document fragment, then we need to use the host. + var ownerRoot = dom(this).getOwnerRoot(); +@@ -331,6 +334,15 @@ Polymer({ + return target; + }, + ++ /** ++ * Sets the target element that this tooltip will be anchored to. ++ * @param {Node} target ++ */ ++ set target(target) { ++ this._manualTarget = target; ++ this._findTarget(); ++ }, ++ + /** + * @return {void} + */ +@@ -429,13 +441,16 @@ Polymer({ + * @return {void} + */ + updatePosition: function() { +- if (!this._target || !this.offsetParent) ++ if (!this._target) ++ return; ++ var offsetParent = this._composedOffsetParent(); ++ if (!offsetParent) + return; + var offset = this.offset; + // If a marginTop has been provided by the user (pre 1.0.3), use it. + if (this.marginTop != 14 && this.offset == 14) + offset = this.marginTop; +- var parentRect = this.offsetParent.getBoundingClientRect(); ++ var parentRect = offsetParent.getBoundingClientRect(); + var targetRect = this._target.getBoundingClientRect(); + var thisRect = this.getBoundingClientRect(); + var horizontalCenterOffset = (targetRect.width - thisRect.width) / 2; +@@ -581,5 +596,45 @@ Polymer({ + } + this.unlisten(this.$.tooltip, 'animationend', '_onAnimationEnd'); + this.unlisten(this, 'mouseenter', 'hide'); ++ }, ++ ++ /** ++ * Polyfills the old offsetParent behavior from before the spec was changed: ++ * https://github.com/w3c/csswg-drafts/issues/159 ++ */ ++ _composedOffsetParent: function() { ++ // Do an initial walk to check for display:none ancestors. ++ for (let ancestor = this; ancestor; ancestor = flatTreeParent(ancestor)) { ++ if (!(ancestor instanceof Element)) ++ continue; ++ if (getComputedStyle(ancestor).display === 'none') ++ return null; ++ } ++ ++ for (let ancestor = flatTreeParent(this); ancestor; ancestor = flatTreeParent(ancestor)) { ++ if (!(ancestor instanceof Element)) ++ continue; ++ const style = getComputedStyle(ancestor); ++ if (style.display === 'contents') { ++ // display:contents nodes aren't in the layout tree so they should be skipped. ++ continue; ++ } ++ if (style.position !== 'static') { ++ return ancestor; ++ } ++ if (ancestor.tagName === 'BODY') ++ return ancestor; ++ } ++ return null; ++ ++ function flatTreeParent(element) { ++ if (element.assignedSlot) { ++ return element.assignedSlot; ++ } ++ if (element.parentNode instanceof ShadowRoot) { ++ return element.parentNode.host; ++ } ++ return element.parentNode; ++ } + } + });
diff --git a/third_party/polymer/v3_0/reproduce.sh b/third_party/polymer/v3_0/reproduce.sh index 3cf47f72..7b529a4b 100755 --- a/third_party/polymer/v3_0/reproduce.sh +++ b/third_party/polymer/v3_0/reproduce.sh
@@ -51,6 +51,7 @@ # Apply additional chrome specific patches. patch -p1 --forward -r - < chromium.patch +patch -p1 --forward -r - < paper_tooltip.patch echo 'Minifying Polymer 3, since it comes non-minified from NPM.' python minify_polymer.py
diff --git a/third_party/protobuf/README.chromium b/third_party/protobuf/README.chromium index a9627a0f..abb7c5f 100644 --- a/third_party/protobuf/README.chromium +++ b/third_party/protobuf/README.chromium
@@ -91,3 +91,9 @@ Adds hooks to allow running callback before and after protobuf initialisation. These hooks allows to fix priority inversion by injecting code that boost the thread priority while loading protobufs (https://crbug.com/1218253). + +- 0025-remove-std-iterator.patch + + Imports + https://github.com/protocolbuffers/protobuf/commit/ed8b2e6f62afee17e2f8249be3b9b69eb0666532 + to remove uses of std::iterator.
diff --git a/third_party/protobuf/patches/0025-remove-std-iterator.patch b/third_party/protobuf/patches/0025-remove-std-iterator.patch new file mode 100644 index 0000000..007d8a0 --- /dev/null +++ b/third_party/protobuf/patches/0025-remove-std-iterator.patch
@@ -0,0 +1,97 @@ +diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h +index af8eb00ef84ca..bb41fbaeb52ed 100644 +--- a/src/google/protobuf/reflection.h ++++ b/src/google/protobuf/reflection.h +@@ -392,13 +392,18 @@ class PROTOBUF_EXPORT RepeatedFieldAccessor { + + // Implement (Mutable)RepeatedFieldRef::iterator + template <typename T> +-class RepeatedFieldRefIterator +- : public std::iterator<std::forward_iterator_tag, T> { ++class RepeatedFieldRefIterator { + typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType; + typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType; + typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType; + + public: ++ using iterator_category = std::forward_iterator_tag; ++ using value_type = T; ++ using pointer = T*; ++ using reference = T&; ++ using difference_type = std::ptrdiff_t; ++ + // Constructor for non-message fields. + RepeatedFieldRefIterator(const void* data, + const RepeatedFieldAccessor* accessor, bool begin) +diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h +index c1c4774685ed3..f9e120218fe54 100644 +--- a/src/google/protobuf/repeated_field.h ++++ b/src/google/protobuf/repeated_field.h +@@ -2667,9 +2667,14 @@ RepeatedPtrField<Element>::pointer_end() const { + namespace internal { + // A back inserter for RepeatedField objects. + template <typename T> +-class RepeatedFieldBackInsertIterator +- : public std::iterator<std::output_iterator_tag, T> { ++class RepeatedFieldBackInsertIterator { + public: ++ using iterator_category = std::output_iterator_tag; ++ using value_type = T; ++ using pointer = void; ++ using reference = void; ++ using difference_type = std::ptrdiff_t; ++ + explicit RepeatedFieldBackInsertIterator( + RepeatedField<T>* const mutable_field) + : field_(mutable_field) {} +@@ -2689,9 +2694,14 @@ class RepeatedFieldBackInsertIterator + + // A back inserter for RepeatedPtrField objects. + template <typename T> +-class RepeatedPtrFieldBackInsertIterator +- : public std::iterator<std::output_iterator_tag, T> { ++class RepeatedPtrFieldBackInsertIterator { + public: ++ using iterator_category = std::output_iterator_tag; ++ using value_type = T; ++ using pointer = void; ++ using reference = void; ++ using difference_type = std::ptrdiff_t; ++ + RepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T>* const mutable_field) + : field_(mutable_field) {} + RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) { +@@ -2720,9 +2730,14 @@ class RepeatedPtrFieldBackInsertIterator + // A back inserter for RepeatedPtrFields that inserts by transferring ownership + // of a pointer. + template <typename T> +-class AllocatedRepeatedPtrFieldBackInsertIterator +- : public std::iterator<std::output_iterator_tag, T> { ++class AllocatedRepeatedPtrFieldBackInsertIterator { + public: ++ using iterator_category = std::output_iterator_tag; ++ using value_type = T; ++ using pointer = void; ++ using reference = void; ++ using difference_type = std::ptrdiff_t; ++ + explicit AllocatedRepeatedPtrFieldBackInsertIterator( + RepeatedPtrField<T>* const mutable_field) + : field_(mutable_field) {} +@@ -2744,9 +2759,14 @@ class AllocatedRepeatedPtrFieldBackInsertIterator + // Almost identical to AllocatedRepeatedPtrFieldBackInsertIterator. This one + // uses the UnsafeArenaAddAllocated instead. + template <typename T> +-class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator +- : public std::iterator<std::output_iterator_tag, T> { ++class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator { + public: ++ using iterator_category = std::output_iterator_tag; ++ using value_type = T; ++ using pointer = void; ++ using reference = void; ++ using difference_type = std::ptrdiff_t; ++ + explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator( + RepeatedPtrField<T>* const mutable_field) + : field_(mutable_field) {}
diff --git a/third_party/protobuf/src/google/protobuf/port_def.inc b/third_party/protobuf/src/google/protobuf/port_def.inc index 4283ed0..7b9044d 100644 --- a/third_party/protobuf/src/google/protobuf/port_def.inc +++ b/third_party/protobuf/src/google/protobuf/port_def.inc
@@ -277,18 +277,18 @@ #endif #if defined(__has_cpp_attribute) -#define HAS_ATTRIBUTE(attr) __has_cpp_attribute(attr) +#define PROTOBUF_HAS_ATTRIBUTE(attr) __has_cpp_attribute(attr) #else -#define HAS_ATTRIBUTE(attr) 0 +#define PROTOBUF_HAS_ATTRIBUTE(attr) 0 #endif -#if HAS_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) +#if PROTOBUF_HAS_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) #define PROTOBUF_UNUSED __attribute__((__unused__)) #else #define PROTOBUF_UNUSED #endif -#undef HAS_ATTRIBUTE +#undef PROTOBUF_HAS_ATTRIBUTE #ifdef _MSC_VER #define PROTOBUF_LONGLONG(x) x##I64
diff --git a/third_party/protobuf/src/google/protobuf/reflection.h b/third_party/protobuf/src/google/protobuf/reflection.h index af8eb00e..bb41fba 100644 --- a/third_party/protobuf/src/google/protobuf/reflection.h +++ b/third_party/protobuf/src/google/protobuf/reflection.h
@@ -392,13 +392,18 @@ // Implement (Mutable)RepeatedFieldRef::iterator template <typename T> -class RepeatedFieldRefIterator - : public std::iterator<std::forward_iterator_tag, T> { +class RepeatedFieldRefIterator { typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType; typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType; typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType; public: + using iterator_category = std::forward_iterator_tag; + using value_type = T; + using pointer = T*; + using reference = T&; + using difference_type = std::ptrdiff_t; + // Constructor for non-message fields. RepeatedFieldRefIterator(const void* data, const RepeatedFieldAccessor* accessor, bool begin)
diff --git a/third_party/protobuf/src/google/protobuf/repeated_field.h b/third_party/protobuf/src/google/protobuf/repeated_field.h index c1c4774..f9e1202 100644 --- a/third_party/protobuf/src/google/protobuf/repeated_field.h +++ b/third_party/protobuf/src/google/protobuf/repeated_field.h
@@ -2667,9 +2667,14 @@ namespace internal { // A back inserter for RepeatedField objects. template <typename T> -class RepeatedFieldBackInsertIterator - : public std::iterator<std::output_iterator_tag, T> { +class RepeatedFieldBackInsertIterator { public: + using iterator_category = std::output_iterator_tag; + using value_type = T; + using pointer = void; + using reference = void; + using difference_type = std::ptrdiff_t; + explicit RepeatedFieldBackInsertIterator( RepeatedField<T>* const mutable_field) : field_(mutable_field) {} @@ -2689,9 +2694,14 @@ // A back inserter for RepeatedPtrField objects. template <typename T> -class RepeatedPtrFieldBackInsertIterator - : public std::iterator<std::output_iterator_tag, T> { +class RepeatedPtrFieldBackInsertIterator { public: + using iterator_category = std::output_iterator_tag; + using value_type = T; + using pointer = void; + using reference = void; + using difference_type = std::ptrdiff_t; + RepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T>* const mutable_field) : field_(mutable_field) {} RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) { @@ -2720,9 +2730,14 @@ // A back inserter for RepeatedPtrFields that inserts by transferring ownership // of a pointer. template <typename T> -class AllocatedRepeatedPtrFieldBackInsertIterator - : public std::iterator<std::output_iterator_tag, T> { +class AllocatedRepeatedPtrFieldBackInsertIterator { public: + using iterator_category = std::output_iterator_tag; + using value_type = T; + using pointer = void; + using reference = void; + using difference_type = std::ptrdiff_t; + explicit AllocatedRepeatedPtrFieldBackInsertIterator( RepeatedPtrField<T>* const mutable_field) : field_(mutable_field) {} @@ -2744,9 +2759,14 @@ // Almost identical to AllocatedRepeatedPtrFieldBackInsertIterator. This one // uses the UnsafeArenaAddAllocated instead. template <typename T> -class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator - : public std::iterator<std::output_iterator_tag, T> { +class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator { public: + using iterator_category = std::output_iterator_tag; + using value_type = T; + using pointer = void; + using reference = void; + using difference_type = std::ptrdiff_t; + explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator( RepeatedPtrField<T>* const mutable_field) : field_(mutable_field) {}
diff --git a/third_party/zlib/contrib/tests/fuzzers/OWNERS b/third_party/zlib/contrib/tests/fuzzers/OWNERS index 9a2fb6f..0ae5257 100644 --- a/third_party/zlib/contrib/tests/fuzzers/OWNERS +++ b/third_party/zlib/contrib/tests/fuzzers/OWNERS
@@ -1 +1,3 @@ cblume@chromium.org +hans@chromium.org +noel@chromium.org
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py index 1e4ae2c..78f4712b 100755 --- a/tools/clang/scripts/build.py +++ b/tools/clang/scripts/build.py
@@ -34,13 +34,13 @@ THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party') LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm') COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'compiler-rt') -LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap') -LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR, - 'llvm-bootstrap-install') -LLVM_INSTRUMENTED_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-instrumented') -LLVM_PROFDATA_FILE = os.path.join(LLVM_INSTRUMENTED_DIR, 'profdata.prof') LLVM_BUILD_TOOLS_DIR = os.path.abspath( - os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) + os.path.join(THIRD_PARTY_DIR, 'llvm-build-tools')) +LLVM_BOOTSTRAP_DIR = os.path.join(LLVM_BUILD_TOOLS_DIR, 'llvm-bootstrap') +LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(LLVM_BUILD_TOOLS_DIR, + 'llvm-bootstrap-install') +LLVM_INSTRUMENTED_DIR = os.path.join(LLVM_BUILD_TOOLS_DIR, 'llvm-instrumented') +LLVM_PROFDATA_FILE = os.path.join(LLVM_INSTRUMENTED_DIR, 'profdata.prof') ANDROID_NDK_DIR = os.path.join( CHROMIUM_DIR, 'third_party', 'android_ndk') FUCHSIA_SDK_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'fuchsia-sdk',
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index dbab5ab..f84918d 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -661,13 +661,10 @@ 'chromium.swangle': { 'linux-swangle-chromium-x64': 'gpu_tests_release_trybot_minimal_symbols_reclient', - 'linux-swangle-tot-angle-x64': 'angle_deqp_release_trybot_reclient', 'linux-swangle-tot-swiftshader-x64': 'angle_deqp_release_trybot_reclient', 'linux-swangle-x64': 'angle_deqp_release_trybot_reclient', 'mac-swangle-chromium-x64': 'gpu_tests_release_trybot_minimal_symbols', 'win-swangle-chromium-x86': 'gpu_tests_release_trybot_minimal_symbol_x86_resource_allowlisting_reclient', - 'win-swangle-tot-angle-x64': 'angle_deqp_release_trybot_reclient', - 'win-swangle-tot-angle-x86': 'angle_deqp_release_bot_dcheck_always_on_x86_reclient', 'win-swangle-tot-swiftshader-x64': 'angle_deqp_release_trybot_reclient', 'win-swangle-tot-swiftshader-x86': 'angle_deqp_release_bot_dcheck_always_on_x86_reclient', 'win-swangle-x64': 'angle_deqp_release_trybot_reclient', @@ -1217,13 +1214,10 @@ 'tryserver.chromium.swangle': { 'linux-swangle-chromium-try-x64': 'gpu_tests_release_trybot', - 'linux-swangle-try-tot-angle-x64': 'angle_deqp_release_trybot', 'linux-swangle-try-tot-swiftshader-x64': 'angle_deqp_release_trybot', 'linux-swangle-try-x64': 'angle_deqp_release_trybot', 'mac-swangle-chromium-try-x64': 'gpu_tests_release_trybot', 'win-swangle-chromium-try-x86': 'gpu_tests_release_trybot_x86_resource_allowlisting', - 'win-swangle-try-tot-angle-x64': 'angle_deqp_release_trybot', - 'win-swangle-try-tot-angle-x86': 'angle_deqp_release_trybot_x86', 'win-swangle-try-tot-swiftshader-x64': 'angle_deqp_release_trybot', 'win-swangle-try-tot-swiftshader-x86': 'angle_deqp_release_trybot_x86', 'win-swangle-try-x64': 'angle_deqp_release_trybot',
diff --git a/tools/mb/mb_config_expectations/chromium.swangle.json b/tools/mb/mb_config_expectations/chromium.swangle.json index 8f3e48a..a8fd27e 100644 --- a/tools/mb/mb_config_expectations/chromium.swangle.json +++ b/tools/mb/mb_config_expectations/chromium.swangle.json
@@ -11,17 +11,6 @@ "use_remoteexec": true } }, - "linux-swangle-tot-angle-x64": { - "gn_args": { - "build_angle_deqp_tests": true, - "dcheck_always_on": true, - "is_component_build": true, - "is_debug": false, - "symbol_level": 1, - "use_rbe": true, - "use_remoteexec": true - } - }, "linux-swangle-tot-swiftshader-x64": { "gn_args": { "build_angle_deqp_tests": true, @@ -69,29 +58,6 @@ "use_remoteexec": true } }, - "win-swangle-tot-angle-x64": { - "gn_args": { - "build_angle_deqp_tests": true, - "dcheck_always_on": true, - "is_component_build": true, - "is_debug": false, - "symbol_level": 1, - "use_rbe": true, - "use_remoteexec": true - } - }, - "win-swangle-tot-angle-x86": { - "gn_args": { - "build_angle_deqp_tests": true, - "dcheck_always_on": true, - "is_component_build": true, - "is_debug": false, - "symbol_level": 1, - "target_cpu": "x86", - "use_rbe": true, - "use_remoteexec": true - } - }, "win-swangle-tot-swiftshader-x64": { "gn_args": { "build_angle_deqp_tests": true,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.swangle.json b/tools/mb/mb_config_expectations/tryserver.chromium.swangle.json index c61d4d5..4cca2483 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.swangle.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.swangle.json
@@ -10,16 +10,6 @@ "use_goma": true } }, - "linux-swangle-try-tot-angle-x64": { - "gn_args": { - "build_angle_deqp_tests": true, - "dcheck_always_on": true, - "is_component_build": true, - "is_debug": false, - "symbol_level": 1, - "use_goma": true - } - }, "linux-swangle-try-tot-swiftshader-x64": { "gn_args": { "build_angle_deqp_tests": true, @@ -64,27 +54,6 @@ "use_goma": true } }, - "win-swangle-try-tot-angle-x64": { - "gn_args": { - "build_angle_deqp_tests": true, - "dcheck_always_on": true, - "is_component_build": true, - "is_debug": false, - "symbol_level": 1, - "use_goma": true - } - }, - "win-swangle-try-tot-angle-x86": { - "gn_args": { - "build_angle_deqp_tests": true, - "dcheck_always_on": true, - "is_component_build": true, - "is_debug": false, - "symbol_level": 0, - "target_cpu": "x86", - "use_goma": true - } - }, "win-swangle-try-tot-swiftshader-x64": { "gn_args": { "build_angle_deqp_tests": true,
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 21e69b2..250d962c 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -6260,6 +6260,42 @@ </description> </action> +<action name="ContentSuggestions.Follow.SnackbarGoToFeedButtonTapped"> + <owner>adamta@google.org</owner> + <owner>sczs@chromium.org</owner> + <owner>tinazwang@chromium.org</owner> + <description> + The user tapped GO TO FEED button on the follow succeed snackbar. + </description> +</action> + +<action name="ContentSuggestions.Follow.SnackbarRetryFollowButtonTapped"> + <owner>adamta@google.org</owner> + <owner>sczs@chromium.org</owner> + <owner>tinazwang@chromium.org</owner> + <description> + The user tapped RETRY button on the follow failed snackbar. + </description> +</action> + +<action name="ContentSuggestions.Follow.SnackbarRetryUnfollowButtonTapped"> + <owner>adamta@google.org</owner> + <owner>sczs@chromium.org</owner> + <owner>tinazwang@chromium.org</owner> + <description> + The user tapped RETRY button on the unfollow failed snackbar. + </description> +</action> + +<action name="ContentSuggestions.Follow.SnackbarUndoButtonTapped"> + <owner>adamta@google.org</owner> + <owner>sczs@chromium.org</owner> + <owner>tinazwang@chromium.org</owner> + <description> + The user tapped UNDO button on the unfollow succeed snackbar. + </description> +</action> + <action name="ContentSuggestions.NotificationsPreferenceOff"> <owner>dgn@chromium.org</owner> <owner>finkm@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 5ba54ee0..23d3e1b 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -25295,6 +25295,18 @@ <int value="3" label="Primary accounts present but different"/> </enum> +<enum name="DIPSRedirectCategory"> + <int value="0" label="No cookies accessed; no previous site engagement"/> + <int value="1" label="Cookies only read; no previous site engagement"/> + <int value="2" label="Cookies only written; no previous site engagement"/> + <int value="3" label="Cookies read and written; no previous site engagement"/> + <int value="4" label="No cookies accessed; site has previous engagement"/> + <int value="5" label="Cookies only read; site has previous engagement"/> + <int value="6" label="Cookies only written; site has previous engagement"/> + <int value="7" + label="Cookies read and written; site has previous engagement"/> +</enum> + <enum name="DircryptoMigrationEndStatus"> <int value="1" label="New migration failed (generic failure)"/> <int value="2" label="New migration succeeded"/> @@ -40101,6 +40113,9 @@ <int value="4221" label="GestureScrollUpdate"/> <int value="4222" label="GestureScrollEnd"/> <int value="4223" label="ArrayBufferTooBigForWebAPI"/> + <int value="4224" label="FedCmRevoke"/> + <int value="4225" label="FedCmLogout"/> + <int value="4226" label="FedCmLogoutRps"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -40241,6 +40256,12 @@ <int value="4" label="Feature is accessible to user. Recorded periodically."/> </enum> +<enum name="FedCmCspStatus"> + <int value="0" label="Success"/> + <int value="1" label="FailedPathButPassedOrigin"/> + <int value="2" label="FailedOrigin"/> +</enum> + <enum name="FedCmRequestIdTokenStatus"> <int value="0" label="Success"/> <int value="1" label="TooManyRequests"/> @@ -49691,6 +49712,7 @@ <int value="42" label="Timed out when fetching installable data"/> <int value="43" label="WebAPK install failed"/> <int value="44" label="Manifest URL scheme is not eligible for WebAPKs"/> + <int value="45" label="Service worker not required for install."/> </enum> <enum name="InstallationCounterReasonEnum"> @@ -55343,6 +55365,7 @@ <int value="-1517518406" label="force-update-menu-type"/> <int value="-1516955483" label="AutoDisableAccessibility:enabled"/> <int value="-1515415104" label="top-document-isolation:disabled"/> + <int value="-1515198913" label="AllowPolyDevicePairing:disabled"/> <int value="-1514943439" label="ash-enable-swipe-to-close-in-overview-mode"/> <int value="-1514611301" label="enable-data-reduction-proxy-bypass-warnings"/> <int value="-1512656386" label="disable-new-audio-rendering-mixing-strategy"/> @@ -59320,6 +59343,7 @@ <int value="1132521402" label="ConnectivityDiagnosticsWebUi:enabled"/> <int value="1132737110" label="WebAssemblyCodeProtectionPku:disabled"/> <int value="1133207726" label="MediaInspectorLogging:enabled"/> + <int value="1133581555" label="AllowPolyDevicePairing:enabled"/> <int value="1133635187" label="force-gpu-rasterization"/> <int value="1134969852" label="NtpPhotosModuleCustomizedOptInTitle:enabled"/> <int value="1135728116" label="PluginVmShowCameraPermissions:enabled"/>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index 3b4166c..e17bf61 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -809,6 +809,13 @@ </summary> </histogram> +<histogram name="Blink.FedCm.Status.Csp" enum="FedCmCspStatus" + expires_after="M120"> + <owner>cbiesinger@chromium.org</owner> + <owner>fedcm-core@google.com</owner> + <summary>Records the result of CSP checks in the FedCM API.</summary> +</histogram> + <histogram name="Blink.FedCm.Status.RequestIdToken" enum="FedCmRequestIdTokenStatus" expires_after="M110"> <owner>yigu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml index e90afa49..2e91c5ad 100644 --- a/tools/metrics/histograms/metadata/platform/histograms.xml +++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -706,6 +706,18 @@ </summary> </histogram> +<histogram name="Platform.Missive.CpuUsage" units="%" + expires_after="2023-05-03"> + <owner>xuhong@chromium.org</owner> + <owner>lbaraz@chromium.org</owner> + <owner>cros-reporting-team@google.com</owner> + <summary> + The percentage of CPU time that the Missive daemon has been using. The CPU + usage is not expected to be high and any usage beyond 100% is considered to + be in the overflow bucket. This is reported once every 10 minutes. + </summary> +</histogram> + <histogram name="Platform.Missive.StorageUsage" units="MiB" expires_after="2023-05-03"> <owner>xuhong@chromium.org</owner> @@ -1339,8 +1351,8 @@ </histogram> <histogram name="Platform.ZramCompressedSize" units="MB" - expires_after="2021-11-07"> - <owner>sonnyrao@chromium.org</owner> + expires_after="2022-11-10"> + <owner>bgeffon@chromium.org</owner> <owner>chromeos-memory@google.com</owner> <summary> Compressed swap size in megabytes. This is the actual amount of RAM used by @@ -1349,8 +1361,8 @@ </histogram> <histogram name="Platform.ZramCompressionRatioPercent" units="%" - expires_after="2022-04-17"> - <owner>sonnyrao@chromium.org</owner> + expires_after="2022-11-10"> + <owner>bgeffon@chromium.org</owner> <owner>chromeos-memory@google.com</owner> <summary> The ratio of compressed memory (zram) before and after compression when the
diff --git a/tools/metrics/histograms/metadata/privacy/histograms.xml b/tools/metrics/histograms/metadata/privacy/histograms.xml index 0b2f309f..6094951 100644 --- a/tools/metrics/histograms/metadata/privacy/histograms.xml +++ b/tools/metrics/histograms/metadata/privacy/histograms.xml
@@ -180,6 +180,19 @@ </summary> </histogram> +<histogram name="Privacy.DIPS.BounceCategory{DIPSCookieMode}" + enum="DIPSRedirectCategory" expires_after="2022-11-01"> + <owner>bcl@chromium.org</owner> + <owner>rtarpine@chromium.org</owner> + <owner>src/chrome/browser/dips/OWNERS</owner> + <summary> + Whether a redirect accessed cookies and whether its origin previously had + user engagement. Recorded when redirecting between different sites, + {DIPSCookieMode}. + </summary> + <token key="DIPSCookieMode" variants="DIPSCookieMode"/> +</histogram> + <histogram name="Privacy.DIPS.TimeFromInteractionToStorage{DIPSCookieMode}" units="ms" expires_after="2022-07-01"> <owner>bcl@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 9f05005..8570dc9 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -13,16 +13,16 @@ "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "mac": { - "hash": "ace0713453697e1cd862d4e59a2d44536ad593aa", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/e627dcb2bf50123e544974db737c9d93068abb9e/trace_processor_shell" + "hash": "3496ab91276a64961a110bd4c84dc83b40ceeda3", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/b3694fd90110c28532e47831bd1ffc517d0ccc1b/trace_processor_shell" }, "mac_arm64": { "hash": "e1ad4861384b06d911a65f035317914b8cc975c6", "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "a8d687c966f7b2258ad1614e60fd0b6eb4c9a104", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/7e20de3c529388bc4cecda77a6416e9911adc89c/trace_processor_shell" + "hash": "104528103761cef1b15ea2d7de8c34a112f2b857", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/342139a897833e6af5f47aac4f99f9e461464900/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/traffic_annotation/scripts/auditor/README.md b/tools/traffic_annotation/scripts/auditor/README.md index 629b50f..7700669 100644 --- a/tools/traffic_annotation/scripts/auditor/README.md +++ b/tools/traffic_annotation/scripts/auditor/README.md
@@ -40,3 +40,16 @@ CreateMutableNetworkTrafficAnnotationTag() function. * `test_annotation`: Files and paths in this category can use the TRAFFIC_ANNOTATION_FOR_TESTS tag. + +## hashes.py + +In logs from chrome://net-export, there is a `traffic_annotation` field, which +contains the ***hash code** of the network annotation. Since this hash code is +not recorded in annotations.xml, it is non-trivial to map it to its annotation. + +Running this scripts print a list of all annotations from `annotations.xml`, +along with their hash codes. This makes it easier to look up the annotation. + +``` +vpython3 ./tools/traffic_annotation/scripts/auditor/hashes.py +```
diff --git a/tools/traffic_annotation/scripts/auditor/hashes.py b/tools/traffic_annotation/scripts/auditor/hashes.py new file mode 100755 index 0000000..68ab61d --- /dev/null +++ b/tools/traffic_annotation/scripts/auditor/hashes.py
@@ -0,0 +1,40 @@ +#!/usr/bin/env vpython3 + +# Copyright 2022 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 argparse +import re +from pathlib import Path + +import util + +# Path to the directory where this script is. +SCRIPT_DIR = Path(__file__).resolve().parent + +# Absolute path to chrome/src. +SRC_DIR = SCRIPT_DIR.parents[3] + +# Default value of the |annotations_file| argument. +ANNOTATIONS_XML_PATH = 'tools/traffic_annotation/summary/annotations.xml' + +if __name__ == '__main__': + args_parser = argparse.ArgumentParser( + description='Reads annotations.xml and outputs a mapping of unique IDs ' + 'to their hashes.', + prog='hashes.py') + args_parser.add_argument( + 'annotations_file', + nargs='?', + default=SRC_DIR / ANNOTATIONS_XML_PATH, + type=Path, + help='Optional path to a summary file containing all annotations. ' + 'Defaults to {}.'.format(ANNOTATIONS_XML_PATH)) + + args = args_parser.parse_args() + + xml = args.annotations_file.read_text(encoding='utf-8') + unique_ids = sorted(re.findall(r'id="([^"]+)"', xml)) + for unique_id in unique_ids: + print('{}\t{}'.format(unique_id, util.compute_hash_value(unique_id)))
diff --git a/tools/typescript/definitions/pending.d.ts b/tools/typescript/definitions/pending.d.ts index 7d7a041..7174f75c 100644 --- a/tools/typescript/definitions/pending.d.ts +++ b/tools/typescript/definitions/pending.d.ts
@@ -12,13 +12,6 @@ // for detail. interface DocumentOrShadowRoot { getSelection(): Selection|null; - - // See https://github.com/microsoft/TypeScript/issues/30022. - adoptedStyleSheets: CSSStyleSheet[]; -} - -interface CSSStyleSheet { - replaceSync(text: string): void; } interface HTMLElement {
diff --git a/ui/display/mac/screen_mac.mm b/ui/display/mac/screen_mac.mm index 9056259..a9d9934 100644 --- a/ui/display/mac/screen_mac.mm +++ b/ui/display/mac/screen_mac.mm
@@ -149,7 +149,7 @@ display.set_color_spaces(display_color_spaces); } display_color_spaces.SetSDRMaxLuminanceNits( - gfx::ColorSpace::kDefaultSDRWhiteLevelV2); + gfx::ColorSpace::kDefaultSDRWhiteLevel); if (enable_hdr) { display.set_color_depth(Display::kHDR10BitsPerPixel);
diff --git a/ui/display/manager/display_change_observer_unittest.cc b/ui/display/manager/display_change_observer_unittest.cc index fbeceb1c..38b6f53 100644 --- a/ui/display/manager/display_change_observer_unittest.cc +++ b/ui/display/manager/display_change_observer_unittest.cc
@@ -441,7 +441,7 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(features::kUseHDRTransferFunction); - const auto display_color_space = gfx::ColorSpace::CreateHDR10(100.0f); + const auto display_color_space = gfx::ColorSpace::CreateHDR10(); const std::unique_ptr<DisplaySnapshot> display_snapshot = FakeDisplaySnapshot::Builder() .SetId(123)
diff --git a/ui/display/util/display_util.cc b/ui/display/util/display_util.cc index ab0c54f..2272f212 100644 --- a/ui/display/util/display_util.cc +++ b/ui/display/util/display_util.cc
@@ -218,7 +218,7 @@ if (value == "display-p3-d65") return gfx::ColorSpace::CreateDisplayP3D65(); if (value == "scrgb-linear") - return gfx::ColorSpace::CreateSCRGBLinear(); + return gfx::ColorSpace::CreateSRGBLinear(); if (value == "hdr10") return gfx::ColorSpace::CreateHDR10(); if (value == "extended-srgb")
diff --git a/ui/display/win/screen_win.cc b/ui/display/win/screen_win.cc index 0b661cb7..2bfaa9f 100644 --- a/ui/display/win/screen_win.cc +++ b/ui/display/win/screen_win.cc
@@ -263,7 +263,7 @@ // space is scRGB linear (defaults to 80 nits) or PQ (defaults to 100 nits). const auto& color_space = GetForcedDisplayColorProfile(); auto display_color_spaces = CreateDisplayColorSpaces( - color_space, gfx::ColorSpace::kDefaultSDRWhiteLevelV2); + color_space, gfx::ColorSpace::kDefaultSDRWhiteLevel); // Use the forced color profile's buffer format for all content usages. if (color_space.GetTransferID() == gfx::ColorSpace::TransferID::PQ) { display_color_spaces.SetOutputBufferFormats( @@ -303,7 +303,7 @@ hdr_max_luminance_relative = dxgi_output_desc->max_luminance / sdr_white_level; if (!dxgi_output_desc->hdr_enabled) - sdr_white_level = gfx::ColorSpace::kDefaultSDRWhiteLevelV2; + sdr_white_level = gfx::ColorSpace::kDefaultSDRWhiteLevel; } hdr_max_luminance_relative = std::max(hdr_max_luminance_relative, kMinHDRCapableMaxLuminanceRelative); @@ -312,7 +312,7 @@ } else { color_spaces = CreateDisplayColorSpaces( color_profile_reader->GetDisplayColorSpace(display.id()), - gfx::ColorSpace::kDefaultSDRWhiteLevelV2); + gfx::ColorSpace::kDefaultSDRWhiteLevel); } if (color_spaces.SupportsHDR()) { // These are (ab)used by pages via media query APIs to detect HDR support.
diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc index be062ddc..e48876dd 100644 --- a/ui/events/gestures/gesture_recognizer_impl.cc +++ b/ui/events/gestures/gesture_recognizer_impl.cc
@@ -322,12 +322,11 @@ // Do not iterate directly over |consumer_gesture_provider_| because canceling // active touches may cause the consumer to be removed from // |consumer_gesture_provider_|. See https://crbug.com/651258 for more info. - std::vector<GestureConsumer*> consumers(consumer_gesture_provider_.size()); + std::vector<GestureConsumer*> consumers; + consumers.reserve(consumer_gesture_provider_.size()); for (const auto& entry : consumer_gesture_provider_) { - if (entry.first == not_cancelled) - continue; - - consumers.push_back(entry.first); + if (entry.first != not_cancelled) + consumers.push_back(entry.first); } for (auto* consumer : consumers)
diff --git a/ui/gfx/android/android_surface_control_compat.cc b/ui/gfx/android/android_surface_control_compat.cc index b0bdc16..53153d89 100644 --- a/ui/gfx/android/android_surface_control_compat.cc +++ b/ui/gfx/android/android_surface_control_compat.cc
@@ -397,7 +397,7 @@ if (!color_space.IsValid() || color_space == gfx::ColorSpace::CreateSRGB()) return ADATASPACE_SRGB; - if (color_space == gfx::ColorSpace::CreateSCRGBLinear()) + if (color_space == gfx::ColorSpace::CreateSRGBLinear()) return ADATASPACE_SCRGB_LINEAR; if (color_space == gfx::ColorSpace::CreateDisplayP3D65())
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc index ec01231..0803a82 100644 --- a/ui/gfx/color_space.cc +++ b/ui/gfx/color_space.cc
@@ -81,23 +81,6 @@ return fn; } -float GetSDRWhiteLevelFromPQSkTransferFunction( - const skcms_TransferFunction& fn) { - DCHECK_EQ(fn.g, SkNamedTransferFn::kPQ.g); - const double ws_a = static_cast<double>(fn.a) / SkNamedTransferFn::kPQ.a; - const double w_a = pow(ws_a, fn.f); - const double sdr_white_level_a = 10000.0f / w_a; - return sdr_white_level_a; -} - -float GetSDRWhiteLevelFromHLGSkTransferFunction( - const skcms_TransferFunction& fn) { - DCHECK_EQ(fn.g, SkNamedTransferFn::kHLG.g); - if (fn.f == 0) - return ColorSpace::kDefaultSDRWhiteLevel; - return 1.0f / ((fn.f + 1) / ColorSpace::kDefaultSDRWhiteLevel); -} - bool PrimaryIdContainsSRGB(ColorSpace::PrimaryID id) { DCHECK(id != ColorSpace::PrimaryID::INVALID && id != ColorSpace::PrimaryID::CUSTOM); @@ -152,10 +135,8 @@ SetCustomTransferFunction(fn, is_hdr); } else if (skcms_TransferFunction_isHLGish(&fn)) { transfer_ = TransferID::HLG; - transfer_params_[0] = GetSDRWhiteLevelFromHLGSkTransferFunction(fn); } else if (skcms_TransferFunction_isPQish(&fn)) { transfer_ = TransferID::PQ; - transfer_params_[0] = GetSDRWhiteLevelFromPQSkTransferFunction(fn); } else { // Construct an invalid result: Unable to extract necessary parameters return; @@ -175,29 +156,6 @@ } // static -ColorSpace ColorSpace::CreateSCRGBLinear(float sdr_white_level) { - skcms_TransferFunction fn = {0}; - fn.g = 1.0f; - fn.a = kDefaultScrgbLinearSdrWhiteLevel / sdr_white_level; - return ColorSpace(PrimaryID::BT709, TransferID::CUSTOM_HDR, MatrixID::RGB, - RangeID::FULL, nullptr, &fn); -} - -// static -ColorSpace ColorSpace::CreateHDR10(float sdr_white_level) { - ColorSpace result(PrimaryID::BT2020, TransferID::PQ, MatrixID::RGB, - RangeID::FULL); - result.transfer_params_[0] = sdr_white_level; - return result; -} - -// static -ColorSpace ColorSpace::CreateHLG() { - return ColorSpace(PrimaryID::BT2020, TransferID::HLG, MatrixID::RGB, - RangeID::FULL); -} - -// static ColorSpace ColorSpace::CreatePiecewiseHDR( PrimaryID primaries, float sdr_joint, @@ -325,9 +283,6 @@ return 7; case TransferID::PIECEWISE_HDR: return 2; - case TransferID::PQ: - case TransferID::HLG: - return 1; default: return 0; } @@ -570,8 +525,7 @@ GetTransferFunction(&fn); if (fn.g == 1.0f && fn.a > 0.0f && fn.b == 0.0f && fn.c == 0.0f && fn.d == 0.0f && fn.e == 0.0f && fn.f == 0.0f) { - ss << "LINEAR_HDR (slope " << fn.a << ", SDR white point " - << kDefaultScrgbLinearSdrWhiteLevel / fn.a << " nits)"; + ss << "LINEAR_HDR (slope " << fn.a << ")"; break; } ss << fn.c << "*x + " << fn.f << " if |x| < " << fn.d << " else sign(x)*(" @@ -694,25 +648,6 @@ return result; } -ColorSpace ColorSpace::GetWithSDRWhiteLevel(float sdr_white_level) const { - ColorSpace result = *this; - if (transfer_ == TransferID::PQ || transfer_ == TransferID::HLG) { - result.transfer_params_[0] = sdr_white_level; - } else if (transfer_ == TransferID::SCRGB_LINEAR_80_NITS) { - skcms_TransferFunction fn = {0}; - GetTransferFunction(&fn, sdr_white_level); - result.transfer_ = TransferID::CUSTOM_HDR; - result.SetCustomTransferFunction(fn, false); - } else if (transfer_ == TransferID::LINEAR_HDR) { - result.transfer_ = TransferID::CUSTOM_HDR; - skcms_TransferFunction fn = {0}; - fn.g = 1.f; - fn.a = kDefaultScrgbLinearSdrWhiteLevel / sdr_white_level; - result.SetCustomTransferFunction(fn, false); - } - return result; -} - sk_sp<SkColorSpace> ColorSpace::ToSkColorSpace( absl::optional<float> sdr_white_level) const { // Handle only valid, full-range RGB spaces. @@ -737,11 +672,11 @@ break; case TransferID::HLG: transfer_fn = GetHLGSkTransferFunction( - sdr_white_level.value_or(kDefaultSDRWhiteLevelV2)); + sdr_white_level.value_or(kDefaultSDRWhiteLevel)); break; case TransferID::PQ: transfer_fn = GetPQSkTransferFunction( - sdr_white_level.value_or(kDefaultSDRWhiteLevelV2)); + sdr_white_level.value_or(kDefaultSDRWhiteLevel)); break; default: if (!GetTransferFunction(&transfer_fn, sdr_white_level)) { @@ -1172,17 +1107,6 @@ return true; } -bool ColorSpace::GetSDRWhiteLevel(float* sdr_white_level) const { - if (transfer_ != TransferID::PQ && transfer_ != TransferID::HLG) { - return false; - } - if (transfer_params_[0] == 0.0f) - *sdr_white_level = kDefaultSDRWhiteLevel; - else - *sdr_white_level = transfer_params_[0]; - return true; -} - bool ColorSpace::GetPiecewiseHDRParams(float* sdr_joint, float* hdr_level) const { if (transfer_ != TransferID::PIECEWISE_HDR)
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h index 7053160..3a1f056 100644 --- a/ui/gfx/color_space.h +++ b/ui/gfx/color_space.h
@@ -206,13 +206,12 @@ } // scRGB uses the same primaries as sRGB but has a linear transfer function - // for all real values, and a white point of kDefaultScrgbLinearSdrWhiteLevel. - static constexpr ColorSpace CreateSCRGBLinear() { + // for all real values. + static constexpr ColorSpace CreateSRGBLinear() { return ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR, MatrixID::RGB, RangeID::FULL); } - // Allows specifying a custom SDR white level. Only used on Windows. - static ColorSpace CreateSCRGBLinear(float sdr_white_level); + // scRGB uses the same primaries as sRGB but has a linear transfer function // for all real values, and an SDR white level of 80 nits. static constexpr ColorSpace CreateSCRGBLinear80Nits() { @@ -225,11 +224,12 @@ return ColorSpace(PrimaryID::BT2020, TransferID::PQ, MatrixID::RGB, RangeID::FULL); } - // Allows specifying a custom SDR white level. Only used on Windows. - static ColorSpace CreateHDR10(float sdr_white_level); // HLG uses the BT.2020 primaries with the ARIB_STD_B67 transfer function. - static ColorSpace CreateHLG(); + static constexpr ColorSpace CreateHLG() { + return ColorSpace(PrimaryID::BT2020, TransferID::HLG, MatrixID::RGB, + RangeID::FULL); + } // Create a piecewise-HDR color space. // - If |primaries| is CUSTOM, then |custom_primary_matrix| must be @@ -265,26 +265,7 @@ // The default number of nits for SDR white. This is used for transformations // between color spaces that do not specify an SDR white for tone mapping // (e.g, in 2D canvas). - // TODO(https://crbug.com/1286076): Replace both kDefaultSDRWhiteLevel and - // kDefaultScrgbLinearSdrWhiteLevel with this constant. - static constexpr float kDefaultSDRWhiteLevelV2 = 203.f; - - // On macOS and on ChromeOS, sRGB's (1,1,1) always coincides with PQ's 100 - // nits (which may not be 100 physical nits). On Windows, sRGB's (1,1,1) - // maps to scRGB linear's (1,1,1) when the SDR white level is set to 80 nits. - // See also kDefaultScrgbLinearSdrWhiteLevel. - static constexpr float kDefaultSDRWhiteLevel = 100.f; - - // The default white level in nits for scRGB linear color space. On Windows, - // sRGB's (1,1,1) maps to scRGB linear's (1,1,1) when the SDR white level is - // set to 80 nits. On Mac and ChromeOS, sRGB's (1,1,1) maps to PQ's 100 nits. - // Using a platform specific value here satisfies both constraints. -#if BUILDFLAG(IS_WIN) - static constexpr float kDefaultScrgbLinearSdrWhiteLevel = 80.0f; -#else - static constexpr float kDefaultScrgbLinearSdrWhiteLevel = - kDefaultSDRWhiteLevel; -#endif // BUILDFLAG(IS_WIN) + static constexpr float kDefaultSDRWhiteLevel = 203.f; bool operator==(const ColorSpace& other) const; bool operator!=(const ColorSpace& other) const; @@ -334,11 +315,6 @@ // the caller but replacing the matrix and range with the given values. ColorSpace GetWithMatrixAndRange(MatrixID matrix, RangeID range) const; - // If this color space has a PQ or scRGB linear transfer function, then return - // |this| with its SDR white level set to |sdr_white_level|. Otherwise return - // |this| unmodified. - ColorSpace GetWithSDRWhiteLevel(float sdr_white_level) const; - // This will return nullptr for non-RGB spaces, spaces with non-FULL // range, unspecified spaces, and spaces that require but are not provided // and SDR white level. @@ -375,11 +351,6 @@ skcms_TransferFunction* fn, absl::optional<float> sdr_white_level = absl::nullopt) const; - // Returns the SDR white level specified for the PQ or HLG transfer functions. - // If no value was specified, then use kDefaultSDRWhiteLevel. If the transfer - // function is not PQ then return false. - bool GetSDRWhiteLevel(float* sdr_white_level) const; - // Returns the parameters for a PIECEWISE_HDR transfer function. See // CreatePiecewiseHDR for parameter meanings. bool GetPiecewiseHDRParams(float* sdr_point, float* hdr_level) const;
diff --git a/ui/gfx/color_space_unittest.cc b/ui/gfx/color_space_unittest.cc index 355e729e..dd07eef 100644 --- a/ui/gfx/color_space_unittest.cc +++ b/ui/gfx/color_space_unittest.cc
@@ -175,7 +175,7 @@ // A linear transfer function being used for HDR should be blended using an // sRGB-like transfer function. - display_color_space = ColorSpace::CreateSCRGBLinear(); + display_color_space = ColorSpace::CreateSRGBLinear(); EXPECT_FALSE(display_color_space.IsSuitableForBlending()); // If not used for HDR, a linear transfer function should be left unchanged. @@ -199,7 +199,7 @@ ColorSpace(ColorSpace::PrimaryID::BT2020, ColorSpace::TransferID::SRGB), ColorSpace::CreateCustom(primary_matrix, transfer_fn), // HDR - ColorSpace::CreateSCRGBLinear(), + ColorSpace::CreateSRGBLinear(), }; sk_sp<SkColorSpace> sk_color_spaces[] = { SkColorSpace::MakeSRGB(), @@ -318,57 +318,6 @@ EXPECT_EQ(color_space.GetRangeID(), ColorSpace::RangeID::LIMITED); } -TEST(ColorSpace, PQWhiteLevel) { - constexpr float kCustomWhiteLevel = 200.f; - - ColorSpace color_space = ColorSpace::CreateHDR10(kCustomWhiteLevel); - EXPECT_EQ(color_space.GetTransferID(), ColorSpace::TransferID::PQ); - float sdr_white_level; - EXPECT_TRUE(color_space.GetSDRWhiteLevel(&sdr_white_level)); - EXPECT_EQ(sdr_white_level, kCustomWhiteLevel); - - color_space = ColorSpace::CreateHDR10(); - EXPECT_EQ(color_space.GetTransferID(), ColorSpace::TransferID::PQ); - EXPECT_TRUE(color_space.GetSDRWhiteLevel(&sdr_white_level)); - EXPECT_EQ(sdr_white_level, ColorSpace::kDefaultSDRWhiteLevel); - - color_space = color_space.GetWithSDRWhiteLevel(kCustomWhiteLevel); - EXPECT_EQ(color_space.GetTransferID(), ColorSpace::TransferID::PQ); - EXPECT_TRUE(color_space.GetSDRWhiteLevel(&sdr_white_level)); - EXPECT_EQ(sdr_white_level, kCustomWhiteLevel); - - constexpr float kCustomWhiteLevel2 = kCustomWhiteLevel * 2; - color_space = color_space.GetWithSDRWhiteLevel(kCustomWhiteLevel2); - EXPECT_EQ(color_space.GetTransferID(), ColorSpace::TransferID::PQ); - EXPECT_TRUE(color_space.GetSDRWhiteLevel(&sdr_white_level)); - EXPECT_EQ(sdr_white_level, kCustomWhiteLevel2); -} - -TEST(ColorSpace, LinearHDRWhiteLevel) { - constexpr float kCustomWhiteLevel = 200.f; - constexpr float kCustomSlope = - ColorSpace::kDefaultScrgbLinearSdrWhiteLevel / kCustomWhiteLevel; - - ColorSpace color_space = ColorSpace::CreateSCRGBLinear(kCustomWhiteLevel); - skcms_TransferFunction fn; - EXPECT_EQ(color_space.GetTransferID(), ColorSpace::TransferID::CUSTOM_HDR); - EXPECT_TRUE(color_space.GetTransferFunction(&fn)); - EXPECT_EQ(std::make_tuple(fn.g, fn.a, fn.b, fn.c, fn.d, fn.e, fn.f), - std::make_tuple(1.f, kCustomSlope, 0.f, 0.f, 0.f, 0.f, 0.f)); - - color_space = ColorSpace::CreateSCRGBLinear(); - EXPECT_EQ(color_space.GetTransferID(), ColorSpace::TransferID::LINEAR_HDR); - EXPECT_TRUE(color_space.GetTransferFunction(&fn)); - EXPECT_EQ(std::make_tuple(fn.g, fn.a, fn.b, fn.c, fn.d, fn.e, fn.f), - std::make_tuple(1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f)); - - color_space = color_space.GetWithSDRWhiteLevel(kCustomWhiteLevel); - EXPECT_EQ(color_space.GetTransferID(), ColorSpace::TransferID::CUSTOM_HDR); - EXPECT_TRUE(color_space.GetTransferFunction(&fn)); - EXPECT_EQ(std::make_tuple(fn.g, fn.a, fn.b, fn.c, fn.d, fn.e, fn.f), - std::make_tuple(1.f, kCustomSlope, 0.f, 0.f, 0.f, 0.f, 0.f)); -} - TEST(ColorSpace, ExpectationsMatchSRGB) { ColorSpace::PrimaryID primary_ids[] = { ColorSpace::PrimaryID::BT709,
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc index dc5bcfd..f4051a01 100644 --- a/ui/gfx/color_transform.cc +++ b/ui/gfx/color_transform.cc
@@ -934,7 +934,7 @@ float c3 = (2392.0f / 4096.0f) * 32.0f; float p = pow(v, 1.0f / m2); v = powf(max(p - c1, 0.0f) / (c2 - c3 * p), 1.0f / m1); - v *= 10000.0f / ColorSpace::kDefaultScrgbLinearSdrWhiteLevel; + v *= 10000.0f / ColorSpace::kDefaultSDRWhiteLevel; return v; } @@ -976,7 +976,7 @@ std::stringstream* src, size_t step_index) const override { auto sdr_white_level = - base::NumberToString(ColorSpace::kDefaultScrgbLinearSdrWhiteLevel); + base::NumberToString(ColorSpace::kDefaultSDRWhiteLevel); *hdr << "vec3 PQToneMapStep" << step_index << "(vec3 color) {\n" << " vec3 result = max(color, 0.0);\n" << " result =\n" @@ -1012,7 +1012,7 @@ void AppendSkShaderSource(std::stringstream* src) const override { auto sdr_white_level = - base::NumberToString(ColorSpace::kDefaultScrgbLinearSdrWhiteLevel); + base::NumberToString(ColorSpace::kDefaultSDRWhiteLevel); *src << "{\n" << " half4 result = max(color, 0.0);\n" << " result =\n"
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index da07bb4d..a8bebec 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -518,7 +518,7 @@ TEST(SimpleColorSpace, CanParseSkShaderSource) { std::vector<ColorSpace> common_color_spaces = { ColorSpace::CreateSRGB(), ColorSpace::CreateDisplayP3D65(), - ColorSpace::CreateExtendedSRGB(), ColorSpace::CreateSCRGBLinear(), + ColorSpace::CreateExtendedSRGB(), ColorSpace::CreateSRGBLinear(), ColorSpace::CreateJpeg(), ColorSpace::CreateREC601(), ColorSpace::CreateREC709()}; for (const auto& src : common_color_spaces) { @@ -605,9 +605,9 @@ bool> ColorSpaceTestData; -class ColorSpaceTest : public testing::TestWithParam<ColorSpaceTestData> { +class ColorSpaceTestBase : public testing::TestWithParam<ColorSpaceTestData> { public: - ColorSpaceTest() + ColorSpaceTestBase() : color_space_(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam()), @@ -620,7 +620,7 @@ ColorTransform::Options options_; }; -TEST_P(ColorSpaceTest, testNullTransform) { +TEST_P(ColorSpaceTestBase, testNullTransform) { std::unique_ptr<ColorTransform> t( ColorTransform::NewColorTransform(color_space_, color_space_, options_)); ColorTransform::TriStim tristim(0.4f, 0.5f, 0.6f); @@ -630,7 +630,7 @@ EXPECT_NEAR(tristim.z(), 0.6f, kMathEpsilon); } -TEST_P(ColorSpaceTest, toXYZandBack) { +TEST_P(ColorSpaceTestBase, toXYZandBack) { std::unique_ptr<ColorTransform> t1(ColorTransform::NewColorTransform( color_space_, ColorSpace::CreateXYZD50(), options_)); std::unique_ptr<ColorTransform> t2(ColorTransform::NewColorTransform( @@ -645,7 +645,7 @@ INSTANTIATE_TEST_SUITE_P( A, - ColorSpaceTest, + ColorSpaceTestBase, testing::Combine(testing::ValuesIn(all_primaries), testing::ValuesIn(simple_transfers), testing::Values(ColorSpace::MatrixID::BT709), @@ -654,7 +654,7 @@ INSTANTIATE_TEST_SUITE_P( B, - ColorSpaceTest, + ColorSpaceTestBase, testing::Combine(testing::Values(ColorSpace::PrimaryID::BT709), testing::ValuesIn(simple_transfers), testing::ValuesIn(all_matrices), @@ -663,7 +663,7 @@ INSTANTIATE_TEST_SUITE_P( C, - ColorSpaceTest, + ColorSpaceTestBase, testing::Combine(testing::ValuesIn(all_primaries), testing::Values(ColorSpace::TransferID::BT709), testing::ValuesIn(all_matrices), @@ -770,7 +770,7 @@ 0.5f, // 0.5 * sqrt(1.0 * 100 / 100) 0.65641f, // 0.17883277 * ln(1.0 * 200 / 100 - 0.28466892) + 0.55991073 }; - constexpr float nits[] = {80.f, 100.f, 200.f}; + constexpr float nits[] = {203.f / 2, 203.f, 203.f * 2}; for (size_t i = 0; i < 3; ++i) { // We'll set the SDR white level to the values in |nits| and also the @@ -796,7 +796,7 @@ // via a ColorSpace with the right SDR white level. switch (i) { case 0: - EXPECT_NEAR(val.x(), 1.f, kMathEpsilon); + EXPECT_NEAR(val.x(), 1.6f, kMathEpsilon); break; case 1: EXPECT_NEAR(val.y(), 1.f, kMathEpsilon); @@ -810,10 +810,6 @@ break; } - // The nit ratios should be preserved by the transform. - EXPECT_NEAR(val.y() / val.x(), nits[1] / nits[0], kMathEpsilon); - EXPECT_NEAR(val.z() / val.x(), nits[2] / nits[0], kMathEpsilon); - // Test the inverse transform. std::unique_ptr<ColorTransform> xform_inv( ColorTransform::NewColorTransform(target, hlg, options));
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc index e361879..ee6ef50 100644 --- a/ui/gfx/mac/io_surface.cc +++ b/ui/gfx/mac/io_surface.cc
@@ -157,7 +157,7 @@ color_space_name = kCGColorSpaceDisplayP3; } else if (color_space == ColorSpace::CreateExtendedSRGB()) { color_space_name = kCGColorSpaceExtendedSRGB; - } else if (color_space == ColorSpace::CreateSCRGBLinear()) { + } else if (color_space == ColorSpace::CreateSRGBLinear()) { color_space_name = kCGColorSpaceExtendedLinearSRGB; } }
diff --git a/ui/gl/direct_composition_surface_win_unittest.cc b/ui/gl/direct_composition_surface_win_unittest.cc index 3da0b2c5..67ede44 100644 --- a/ui/gl/direct_composition_surface_win_unittest.cc +++ b/ui/gl/direct_composition_surface_win_unittest.cc
@@ -833,7 +833,7 @@ TEST_F(DirectCompositionVideoPixelTest, SCRGBLinear) { // SCRGB doesn't make sense on an NV12 input, but don't crash. - TestVideo(gfx::ColorSpace::CreateSCRGBLinear(), SK_ColorTRANSPARENT, false); + TestVideo(gfx::ColorSpace::CreateSRGBLinear(), SK_ColorTRANSPARENT, false); } TEST_F(DirectCompositionVideoPixelTest, InvalidColorSpace) {
diff --git a/ui/gl/vsync_thread_win.cc b/ui/gl/vsync_thread_win.cc index 399e430..fd4646c 100644 --- a/ui/gl/vsync_thread_win.cc +++ b/ui/gl/vsync_thread_win.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/memory/singleton.h" +#include "base/power_monitor/power_monitor.h" #include "ui/gl/gl_angle_util_win.h" #include "ui/gl/vsync_observer.h" @@ -57,6 +58,10 @@ vsync_provider_(gfx::kNullAcceleratedWidget), d3d11_device_(QueryD3D11DeviceObjectFromANGLE()) { DCHECK(d3d11_device_); + + is_suspended_ = + base::PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState(this); + base::Thread::Options options; options.priority = base::ThreadPriority::DISPLAY; vsync_thread_.StartWithOptions(std::move(options)); @@ -68,17 +73,28 @@ observers_.clear(); } vsync_thread_.Stop(); + + base::PowerMonitor::RemovePowerSuspendObserver(this); +} + +void VSyncThreadWin::PostTaskIfNeeded() { + lock_.AssertAcquired(); + // PostTaskIfNeeded is called from AddObserver and OnResume. + // Before queuing up a task, make sure that there are observers waiting for + // VSync and that we're not already firing events to consumers. Avoid firing + // events if we're suspended to conserve battery life. + if (!is_vsync_task_posted_ && !observers_.empty() && !is_suspended_) { + vsync_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&VSyncThreadWin::WaitForVSync, base::Unretained(this))); + is_vsync_task_posted_ = true; + } } void VSyncThreadWin::AddObserver(VSyncObserver* obs) { base::AutoLock auto_lock(lock_); observers_.insert(obs); - if (is_idle_) { - is_idle_ = false; - vsync_thread_.task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&VSyncThreadWin::WaitForVSync, base::Unretained(this))); - } + PostTaskIfNeeded(); } void VSyncThreadWin::RemoveObserver(VSyncObserver* obs) { @@ -86,6 +102,17 @@ observers_.erase(obs); } +void VSyncThreadWin::OnSuspend() { + base::AutoLock auto_lock(lock_); + is_suspended_ = true; +} + +void VSyncThreadWin::OnResume() { + base::AutoLock auto_lock(lock_); + is_suspended_ = false; + PostTaskIfNeeded(); +} + void VSyncThreadWin::WaitForVSync() { base::TimeTicks vsync_phase; base::TimeDelta vsync_interval; @@ -120,16 +147,13 @@ } base::AutoLock auto_lock(lock_); - if (!observers_.empty()) { - vsync_thread_.task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&VSyncThreadWin::WaitForVSync, base::Unretained(this))); - const base::TimeTicks vsync_time = base::TimeTicks::Now(); - for (auto* obs : observers_) - obs->OnVSync(vsync_time, vsync_interval); - } else { - is_idle_ = true; - } + DCHECK(is_vsync_task_posted_); + is_vsync_task_posted_ = false; + PostTaskIfNeeded(); + + const base::TimeTicks vsync_time = base::TimeTicks::Now(); + for (auto* obs : observers_) + obs->OnVSync(vsync_time, vsync_interval); } } // namespace gl
diff --git a/ui/gl/vsync_thread_win.h b/ui/gl/vsync_thread_win.h index 388057a..f8a7a59d 100644 --- a/ui/gl/vsync_thread_win.h +++ b/ui/gl/vsync_thread_win.h
@@ -10,6 +10,7 @@ #include <wrl/client.h> #include "base/containers/flat_set.h" +#include "base/power_monitor/power_observer.h" #include "base/threading/thread.h" #include "ui/gl/gl_export.h" #include "ui/gl/vsync_provider_win.h" @@ -26,13 +27,17 @@ // can be added or removed on the main thread, and the vsync thread goes to // sleep if there are no observers. This is used by DirectCompositionSurfaceWin // to plumb vsync signal back to the display compositor's BeginFrameSource. -class GL_EXPORT VSyncThreadWin { +class GL_EXPORT VSyncThreadWin final : public base::PowerSuspendObserver { public: static VSyncThreadWin* GetInstance(); VSyncThreadWin(const VSyncThreadWin&) = delete; VSyncThreadWin& operator=(const VSyncThreadWin&) = delete; + // Implementation of base::PowerSuspendObserver + void OnSuspend() final; + void OnResume() final; + // These methods are not rentrancy safe, and shouldn't be called inside // VSyncObserver::OnVSync. It's safe to assume that these can be called only // from the main thread. @@ -45,8 +50,9 @@ friend struct base::DefaultSingletonTraits<VSyncThreadWin>; VSyncThreadWin(); - ~VSyncThreadWin(); + ~VSyncThreadWin() final; + void PostTaskIfNeeded(); void WaitForVSync(); base::Thread vsync_thread_; @@ -58,7 +64,8 @@ Microsoft::WRL::ComPtr<IDXGIOutput> primary_output_; base::Lock lock_; - bool GUARDED_BY(lock_) is_idle_ = true; + bool GUARDED_BY(lock_) is_vsync_task_posted_ = false; + bool GUARDED_BY(lock_) is_suspended_ = false; base::flat_set<VSyncObserver*> GUARDED_BY(lock_) observers_; }; } // namespace gl
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc index 749200ef..fb523910 100644 --- a/ui/views/controls/webview/web_dialog_view.cc +++ b/ui/views/controls/webview/web_dialog_view.cc
@@ -47,8 +47,8 @@ void ObservableWebView::DidFinishLoad( content::RenderFrameHost* render_frame_host, const GURL& validated_url) { - // Only listen to the main frame. - if (render_frame_host->GetParent()) + // Only listen to the primary main frame. + if (!render_frame_host->IsInPrimaryMainFrame()) return; if (delegate_)
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc index 77c8821e..38b3760 100644 --- a/ui/views/widget/widget_interactive_uitest.cc +++ b/ui/views/widget/widget_interactive_uitest.cc
@@ -627,58 +627,6 @@ EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get())); } -TEST_F(WidgetTestInteractive, ChildWidgetStackAbove) { - WidgetAutoclosePtr toplevel(CreateTopLevelPlatformWidget()); - Widget* children[] = {CreateChildPlatformWidget(toplevel->GetNativeView()), - CreateChildPlatformWidget(toplevel->GetNativeView()), - CreateChildPlatformWidget(toplevel->GetNativeView())}; - int order[] = {0, 1, 2}; - - children[0]->ShowInactive(); - children[1]->ShowInactive(); - children[2]->ShowInactive(); - ShowSync(toplevel.get()); - - do { - children[order[1]]->StackAboveWidget(children[order[0]]); - children[order[2]]->StackAboveWidget(children[order[1]]); - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - if (i < j) - EXPECT_FALSE( - IsWindowStackedAbove(children[order[i]], children[order[j]])); - else if (i > j) - EXPECT_TRUE( - IsWindowStackedAbove(children[order[i]], children[order[j]])); - } while (std::next_permutation(order, order + 3)); -} - -TEST_F(WidgetTestInteractive, ChildWidgetStackAtTop) { - WidgetAutoclosePtr toplevel(CreateTopLevelPlatformWidget()); - Widget* children[] = {CreateChildPlatformWidget(toplevel->GetNativeView()), - CreateChildPlatformWidget(toplevel->GetNativeView()), - CreateChildPlatformWidget(toplevel->GetNativeView())}; - int order[] = {0, 1, 2}; - - children[0]->ShowInactive(); - children[1]->ShowInactive(); - children[2]->ShowInactive(); - ShowSync(toplevel.get()); - - do { - children[order[1]]->StackAtTop(); - children[order[2]]->StackAtTop(); - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - if (i < j) - EXPECT_FALSE( - IsWindowStackedAbove(children[order[i]], children[order[j]])); - else if (i > j) - EXPECT_TRUE( - IsWindowStackedAbove(children[order[i]], children[order[j]])); - } while (std::next_permutation(order, order + 3)); -} - #if BUILDFLAG(IS_WIN) // Test view focus retention when a widget's HWND is disabled and re-enabled.
diff --git a/ui/webui/resources/cr_elements/cr_fingerprint/OWNERS b/ui/webui/resources/cr_elements/cr_fingerprint/OWNERS index 1633207..fc7e7853 100644 --- a/ui/webui/resources/cr_elements/cr_fingerprint/OWNERS +++ b/ui/webui/resources/cr_elements/cr_fingerprint/OWNERS
@@ -1 +1,2 @@ nsatragno@chromium.org +ckincaid@chromium.org
diff --git a/ui/webui/resources/cr_elements/shared_style_css.html b/ui/webui/resources/cr_elements/shared_style_css.html index c0976a8..eda419e 100644 --- a/ui/webui/resources/cr_elements/shared_style_css.html +++ b/ui/webui/resources/cr_elements/shared_style_css.html
@@ -121,15 +121,13 @@ margin-inline-start: 8px; } - paper-tooltip { - --paper-tooltip: { - border-radius: var(--paper-tooltip-border-radius, 2px); - font-size: 92.31%; /* Effectively 12px if the host default is 13px. */ - font-weight: 500; - max-width: 330px; - min-width: var(--paper-tooltip-min-width, 200px); - padding: var(--paper-tooltip-padding, 10px 8px); - } + paper-tooltip::part(tooltip) { + border-radius: var(--paper-tooltip-border-radius, 2px); + font-size: 92.31%; /* Effectively 12px if the host default is 13px. */ + font-weight: 500; + max-width: 330px; + min-width: var(--paper-tooltip-min-width, 200px); + padding: var(--paper-tooltip-padding, 10px 8px); } /* Typography */