diff --git a/DEPS b/DEPS index f77f08e6..fa4f820 100644 --- a/DEPS +++ b/DEPS
@@ -168,11 +168,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'ad21d47cfa8d9adb2145216c5e514d978d649096', + 'skia_revision': '7cb52cb5e67cd029e5ae7dc68d91eb8488072bf9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'e8fc00fb9ea3d8e5e4fa7193d45afee764165a0e', + 'v8_revision': 'a9e0cc38e4ce5d686dab1e1ac8bf5c742d1ce85f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -180,11 +180,11 @@ # 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': '867f8c92ed1ac207f1ee99121eb44d48505ccaae', + 'angle_revision': '3f647b1bf9a476adb1af5037b88ef7403eb73e31', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '9da287fd0264892a8997426a2d7d154aae560de4', + 'swiftshader_revision': '197a5725f2fecd3368433a1fbfc8249480da8955', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -299,7 +299,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. - 'shaderc_revision': 'c9d5be6b01708bf7d8a8401a7edb98bf3ab82f17', + 'shaderc_revision': 'e46010f01da9b74f63c77576ae3d91b900431073', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -818,7 +818,7 @@ }, 'src/third_party/breakpad/breakpad': - Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '5915ea929c43d61e77b68b64bc91d8709f5c9876', + Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '792e6b2143bffd46c93e8f80c10d00d8289b8d73', 'src/third_party/byte_buddy': { 'packages': [ @@ -892,7 +892,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '79d4f9950680c588d4c3a2cc8595179f3adc90d4', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '9577daf6673d4af851bbd87a2b714f7e03cdb670', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -927,7 +927,7 @@ }, 'src/third_party/ffmpeg': - Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '83304c4e5287d20407dff656545e6dddd73566f8', + Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'fa04e15e1ad61052e85f42413d4b841d2a496ec0', 'src/third_party/flac': Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'af862024c8c8fa0ae07ced05e89013d881b00596', @@ -961,7 +961,7 @@ }, 'src/third_party/glslang/src': - Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'f34cdc70ca1b4e741a9ea5a906f86d3593623356', + Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '37dcb894574e94a876c0165c4df96eeba68e6a5a', 'src/third_party/google_toolbox_for_mac/src': { 'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), @@ -1484,7 +1484,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'dd55f3ca8f2ea716ca917a4aaf36f0729fe902b1', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '229035db8cc676bb382f8734f9174df844e6a079', + Var('webrtc_git') + '/src.git' + '@' + '2bd2d85f65e83641ec4f6f5537a916eede4d366f', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -1551,7 +1551,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ed16d1d29e2f891c14764d138dd019b68cf5f96e', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d565d557945ea450b126f370b1a7b4d33518bf2b', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 371bf1e..edc07c6b 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1320,6 +1320,9 @@ r".*chrome[\\\/]android[\\\/]feed[\\\/]dummy[\\\/].*\.java", ] +# List of image extensions that are used as resources in chromium. +_IMAGE_EXTENSIONS = ['.svg', '.png', '.webp'] + # These paths contain test data and other known invalid JSON files. _KNOWN_INVALID_JSON_FILE_PATTERNS = [ r'test[\\/]data[\\/]', @@ -4079,6 +4082,36 @@ long_text=long_text)] +def _CheckNewImagesWarning(input_api, output_api): + """ + Warns authors who add images into the repo to make sure their images are + optimized before committing. + """ + images_added = False + image_paths = [] + errors = [] + filter_lambda = lambda x: input_api.FilterSourceFile( + x, + black_list=(('(?i).*test', r'.*\/junit\/') + + input_api.DEFAULT_BLACK_LIST), + white_list=[r'.*\/(drawable|mipmap)' ] + ) + for f in input_api.AffectedFiles( + include_deletes=False, file_filter=filter_lambda): + local_path = f.LocalPath().lower() + if any(local_path.endswith(extension) for extension in _IMAGE_EXTENSIONS): + images_added = True + image_paths.append(f) + if images_added: + errors.append(output_api.PresubmitPromptWarning( + 'It looks like you are trying to commit some images. If these are ' + 'non-test-only images, please make sure to read and apply the tips in ' + 'https://chromium.googlesource.com/chromium/src/+/HEAD/docs/speed/' + 'binary_size/optimization_advice.md#optimizing-images\nThis check is ' + 'FYI only and will not block your CL on the CQ.', image_paths)) + return errors + + def _AndroidSpecificOnUploadChecks(input_api, output_api): """Groups upload checks that target android code.""" results = [] @@ -4091,6 +4124,7 @@ results.extend(_CheckAndroidTestAnnotationUsage(input_api, output_api)) results.extend(_CheckAndroidWebkitImports(input_api, output_api)) results.extend(_CheckAndroidXmlStyle(input_api, output_api, True)) + results.extend(_CheckNewImagesWarning(input_api, output_api)) return results def _AndroidSpecificOnCommitChecks(input_api, output_api): @@ -4604,7 +4638,6 @@ def _CheckTranslationScreenshots(input_api, output_api): - PART_FILE_TAG = "part" import os import sys from io import StringIO @@ -4612,47 +4645,11 @@ try: old_sys_path = sys.path sys.path = sys.path + [input_api.os_path.join( - input_api.PresubmitLocalPath(), 'tools', 'grit')] - import grit.grd_reader - import grit.node.message - import grit.util + input_api.PresubmitLocalPath(), 'tools', 'translation')] + from helper import grd_helper finally: sys.path = old_sys_path - def _GetGrdMessages(grd_path_or_string, dir_path='.'): - """Load the grd file and return a dict of message ids to messages. - - Ignores any nested grdp files pointed by <part> tag. - """ - doc = grit.grd_reader.Parse(grd_path_or_string, dir_path, - stop_after=None, first_ids_file=None, - debug=False, defines={'_chromium': 1}, - tags_to_ignore=set([PART_FILE_TAG])) - return { - msg.attrs['name']:msg for msg in doc.GetChildrenOfType( - grit.node.message.MessageNode) - } - - def _GetGrdpMessagesFromString(grdp_string): - """Parses the contents of a grdp file given in grdp_string. - - grd_reader can't parse grdp files directly. Instead, this creates a - temporary directory with a grd file pointing to the grdp file, and loads the - grd from there. Any nested grdp files (pointed by <part> tag) are ignored. - """ - WRAPPER = """<?xml version="1.0" encoding="utf-8"?> - <grit latest_public_release="1" current_release="1"> - <release seq="1"> - <messages> - <part file="sub.grdp" /> - </messages> - </release> - </grit> - """ - with grit.util.TempDir({'main.grd': WRAPPER, - 'sub.grdp': grdp_string}) as temp_dir: - return _GetGrdMessages(temp_dir.GetPath('main.grd'), temp_dir.GetPath()) - new_or_added_paths = set(f.LocalPath() for f in input_api.AffectedFiles() if (f.Action() == 'A' or f.Action() == 'M')) @@ -4713,18 +4710,18 @@ new_id_to_msg_map = {} if file_path.endswith('.grdp'): if f.OldContents(): - old_id_to_msg_map = _GetGrdpMessagesFromString( + old_id_to_msg_map = grd_helper.GetGrdpMessagesFromString( unicode('\n'.join(f.OldContents()))) if f.NewContents(): - new_id_to_msg_map = _GetGrdpMessagesFromString( + new_id_to_msg_map = grd_helper.GetGrdpMessagesFromString( unicode('\n'.join(f.NewContents()))) else: if f.OldContents(): - old_id_to_msg_map = _GetGrdMessages( - StringIO(unicode('\n'.join(f.OldContents())))) + old_id_to_msg_map = grd_helper.GetGrdMessages( + StringIO(unicode('\n'.join(f.OldContents()))), '.') if f.NewContents(): - new_id_to_msg_map = _GetGrdMessages( - StringIO(unicode('\n'.join(f.NewContents())))) + new_id_to_msg_map = grd_helper.GetGrdMessages( + StringIO(unicode('\n'.join(f.NewContents()))), '.') # Compute added, removed and modified message IDs. old_ids = set(old_id_to_msg_map)
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index 6455b91d..4d330335 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -2250,6 +2250,38 @@ self.assertEqual(0, len(results)) +class NewImagesWarningTest(unittest.TestCase): + def testTruePositives(self): + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockFile('dir/android/res/drawable/foo.png', []), + MockFile('dir/android/res/drawable-v21/bar.svg', []), + MockFile('dir/android/res/mipmap-v21-en/baz.webp', []), + MockFile('dir/android/res_gshoe/drawable-mdpi/foobar.png', []), + ] + + results = PRESUBMIT._CheckNewImagesWarning(mock_input_api, MockOutputApi()) + self.assertEqual(1, len(results)) + self.assertEqual(4, len(results[0].items)) + self.assertTrue('foo.png' in results[0].items[0].LocalPath()) + self.assertTrue('bar.svg' in results[0].items[1].LocalPath()) + self.assertTrue('baz.webp' in results[0].items[2].LocalPath()) + self.assertTrue('foobar.png' in results[0].items[3].LocalPath()) + + def testFalsePositives(self): + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockFile('dir/pngs/README.md', []), + MockFile('java/test/res/drawable/foo.png', []), + MockFile('third_party/blink/foo.png', []), + MockFile('dir/third_party/libpng/src/foo.cc', ['foobar']), + MockFile('dir/resources.webp/.gitignore', ['foo.png']), + ] + + results = PRESUBMIT._CheckNewImagesWarning(mock_input_api, MockOutputApi()) + self.assertEqual(0, len(results)) + + class CheckUniquePtrTest(unittest.TestCase): def testTruePositivesNullptr(self): mock_input_api = MockInputApi() @@ -2395,6 +2427,31 @@ </grit> """.splitlines() + OLD_GRDP_CONTENTS = ( + '<?xml version="1.0" encoding="utf-8"?>', + '<grit-part>', + '</grit-part>' + ) + + NEW_GRDP_CONTENTS1 = ( + '<?xml version="1.0" encoding="utf-8"?>', + '<grit-part>', + '<message name="IDS_PART_TEST1">', + 'Part string 1', + '</message>', + '</grit-part>') + + NEW_GRDP_CONTENTS2 = ( + '<?xml version="1.0" encoding="utf-8"?>', + '<grit-part>', + '<message name="IDS_PART_TEST1">', + 'Part string 1', + '</message>', + '<message name="IDS_PART_TEST2">', + 'Part string 2', + '</message>', + '</grit-part>') + DO_NOT_UPLOAD_PNG_MESSAGE = ('Do not include actual screenshots in the ' 'changelist. Run ' 'tools/translate/upload_screenshots.py to ' @@ -2416,33 +2473,57 @@ [x.LocalPath() for x in input_api.AffectedFiles(include_deletes=True)]) return input_api + """ CL modified and added messages, but didn't add any screenshots.""" def testNoScreenshots(self): - # CL modified and added messages, but didn't add any screenshots. + # No new strings (file contents same). Should not warn. + input_api = self.makeInputApi([ + MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS1, + self.NEW_GRD_CONTENTS1, action='M'), + MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS1, + self.NEW_GRDP_CONTENTS1, action='M')]) + warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, + MockOutputApi()) + self.assertEqual(0, len(warnings)) + + # Add two new strings. Should have two warnings. input_api = self.makeInputApi([ MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2, - self.OLD_GRD_CONTENTS, action='M')]) + self.NEW_GRD_CONTENTS1, action='M'), + MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS2, + self.NEW_GRDP_CONTENTS1, action='M')]) warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, MockOutputApi()) self.assertEqual(1, len(warnings)) self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[0].message) self.assertEqual([ - os.path.join('test_grd', 'IDS_TEST1.png.sha1'), - os.path.join('test_grd', 'IDS_TEST2.png.sha1') - ], warnings[0].items) + os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'), + os.path.join('test_grd', 'IDS_TEST2.png.sha1')], + warnings[0].items) + # Add four new strings. Should have four warnings. input_api = self.makeInputApi([ MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2, - self.NEW_GRD_CONTENTS1, action='M')]) + self.OLD_GRD_CONTENTS, action='M'), + MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS2, + self.OLD_GRDP_CONTENTS, action='M')]) warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, MockOutputApi()) self.assertEqual(1, len(warnings)) self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[0].message) - self.assertEqual([os.path.join('test_grd', 'IDS_TEST2.png.sha1')], - warnings[0].items) + self.assertEqual([ + os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'), + os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'), + os.path.join('test_grd', 'IDS_TEST1.png.sha1'), + os.path.join('test_grd', 'IDS_TEST2.png.sha1'), + ], warnings[0].items) - - def testUnnecessaryScreenshots(self): - # CL added a single message and added the png file, but not the sha1 file. + def testPngAddedSha1NotAdded(self): + # CL added one new message in a grd file and added the png file associated + # with it, but did not add the corresponding sha1 file. This should warn + # twice: + # - Once for the added png file (because we don't want developers to upload + # actual images) + # - Once for the missing .sha1 file input_api = self.makeInputApi([ MockAffectedFile( 'test.grd', @@ -2462,38 +2543,59 @@ self.assertEqual([os.path.join('test_grd', 'IDS_TEST1.png.sha1')], warnings[1].items) - # CL added two messages, one has a png. Expect two messages: - # - One for the unnecessary png. - # - Another one for missing .sha1 files. + # CL added two messages (one in grd, one in grdp) and added the png files + # associated with the messages, but did not add the corresponding sha1 + # files. This should warn twice: + # - Once for the added png files (because we don't want developers to upload + # actual images) + # - Once for the missing .sha1 files input_api = self.makeInputApi([ + # Modified files: MockAffectedFile( 'test.grd', - self.NEW_GRD_CONTENTS2, + self.NEW_GRD_CONTENTS1, self.OLD_GRD_CONTENTS, action='M'), MockAffectedFile( - os.path.join('test_grd', 'IDS_TEST1.png'), 'binary', action='A') + 'part.grdp', + self.NEW_GRDP_CONTENTS1, + self.OLD_GRDP_CONTENTS, + action='M'), + # Added files: + MockAffectedFile( + os.path.join('test_grd', 'IDS_TEST1.png'), 'binary', action='A'), + MockAffectedFile( + os.path.join('part_grdp', 'IDS_PART_TEST1.png'), 'binary', + action='A') ]) warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, MockOutputApi()) self.assertEqual(2, len(warnings)) self.assertEqual(self.DO_NOT_UPLOAD_PNG_MESSAGE, warnings[0].message) - self.assertEqual([os.path.join('test_grd', 'IDS_TEST1.png')], + self.assertEqual([os.path.join('part_grdp', 'IDS_PART_TEST1.png'), + os.path.join('test_grd', 'IDS_TEST1.png')], warnings[0].items) self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[1].message) - self.assertEqual([ - os.path.join('test_grd', 'IDS_TEST1.png.sha1'), - os.path.join('test_grd', 'IDS_TEST2.png.sha1') - ], warnings[1].items) + self.assertEqual([os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'), + os.path.join('test_grd', 'IDS_TEST1.png.sha1')], + warnings[1].items) def testScreenshotsWithSha1(self): - # CL added two messages and their corresponding .sha1 files. No warnings. + # CL added four messages (two each in a grd and grdp) and their + # corresponding .sha1 files. No warnings. input_api = self.makeInputApi([ + # Modified files: MockAffectedFile( 'test.grd', self.NEW_GRD_CONTENTS2, self.OLD_GRD_CONTENTS, action='M'), + MockAffectedFile( + 'part.grdp', + self.NEW_GRDP_CONTENTS2, + self.OLD_GRDP_CONTENTS, + action='M'), + # Added files: MockFile( os.path.join('test_grd', 'IDS_TEST1.png.sha1'), 'binary', @@ -2501,61 +2603,106 @@ MockFile( os.path.join('test_grd', 'IDS_TEST2.png.sha1'), 'binary', - action='A') + action='A'), + MockFile( + os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'), + 'binary', + action='A'), + MockFile( + os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'), + 'binary', + action='A'), ]) warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, MockOutputApi()) self.assertEqual([], warnings) def testScreenshotsRemovedWithSha1(self): - # Swap old contents with new contents, remove IDS_TEST1 and IDS_TEST2. The - # sha1 files associated with the messages should also be removed by the CL. + # Replace new contents with old contents in grd and grp files, removing + # IDS_TEST1, IDS_TEST2, IDS_PART_TEST1 and IDS_PART_TEST2. + # Should warn to remove the sha1 files associated with these strings. input_api = self.makeInputApi([ + # Modified files: MockAffectedFile( 'test.grd', - self.OLD_GRD_CONTENTS, - self.NEW_GRD_CONTENTS2, + self.OLD_GRD_CONTENTS, # new_contents + self.NEW_GRD_CONTENTS2, # old_contents action='M'), - MockFile(os.path.join('test_grd', 'IDS_TEST1.png.sha1'), 'binary', ""), - MockFile(os.path.join('test_grd', 'IDS_TEST2.png.sha1'), 'binary', "") + MockAffectedFile( + 'part.grdp', + self.OLD_GRDP_CONTENTS, # new_contents + self.NEW_GRDP_CONTENTS2, # old_contents + action='M'), + # Unmodified files: + MockFile(os.path.join('test_grd', 'IDS_TEST1.png.sha1'), 'binary', ''), + MockFile(os.path.join('test_grd', 'IDS_TEST2.png.sha1'), 'binary', ''), + MockFile(os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'), + 'binary', ''), + MockFile(os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'), + 'binary', '') ]) warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, MockOutputApi()) self.assertEqual(1, len(warnings)) self.assertEqual(self.REMOVE_SIGNATURES_MESSAGE, warnings[0].message) self.assertEqual([ + os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'), + os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'), os.path.join('test_grd', 'IDS_TEST1.png.sha1'), os.path.join('test_grd', 'IDS_TEST2.png.sha1') ], warnings[0].items) - # Same as above, but this time one of the .sha1 files is removed. + # Same as above, but this time one of the .sha1 files is also removed. input_api = self.makeInputApi([ + # Modified files: MockAffectedFile( 'test.grd', - self.OLD_GRD_CONTENTS, - self.NEW_GRD_CONTENTS2, + self.OLD_GRD_CONTENTS, # new_contents + self.NEW_GRD_CONTENTS2, # old_contents action='M'), + MockAffectedFile( + 'part.grdp', + self.OLD_GRDP_CONTENTS, # new_contents + self.NEW_GRDP_CONTENTS2, # old_contents + action='M'), + # Unmodified files: MockFile(os.path.join('test_grd', 'IDS_TEST1.png.sha1'), 'binary', ''), + MockFile(os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'), + 'binary', ''), + # Deleted files: MockAffectedFile( os.path.join('test_grd', 'IDS_TEST2.png.sha1'), '', 'old_contents', + action='D'), + MockAffectedFile( + os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'), + '', + 'old_contents', action='D') ]) warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, MockOutputApi()) self.assertEqual(1, len(warnings)) self.assertEqual(self.REMOVE_SIGNATURES_MESSAGE, warnings[0].message) - self.assertEqual([os.path.join('test_grd', 'IDS_TEST1.png.sha1')], - warnings[0].items) + self.assertEqual([os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'), + os.path.join('test_grd', 'IDS_TEST1.png.sha1') + ], warnings[0].items) - # Remove both sha1 files. No presubmit warnings. + # Remove all sha1 files. There should be no warnings. input_api = self.makeInputApi([ + # Modified files: MockAffectedFile( 'test.grd', self.OLD_GRD_CONTENTS, self.NEW_GRD_CONTENTS2, action='M'), + MockAffectedFile( + 'part.grdp', + self.OLD_GRDP_CONTENTS, + self.NEW_GRDP_CONTENTS2, + action='M'), + # Deleted files: MockFile( os.path.join('test_grd', 'IDS_TEST1.png.sha1'), 'binary', @@ -2563,6 +2710,14 @@ MockFile( os.path.join('test_grd', 'IDS_TEST2.png.sha1'), 'binary', + action='D'), + MockFile( + os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'), + 'binary', + action='D'), + MockFile( + os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'), + 'binary', action='D') ]) warnings = PRESUBMIT._CheckTranslationScreenshots(input_api,
diff --git a/android_webview/browser/aw_browser_context_unittest.cc b/android_webview/browser/aw_browser_context_unittest.cc index 2f967b5..802b2ff 100644 --- a/android_webview/browser/aw_browser_context_unittest.cc +++ b/android_webview/browser/aw_browser_context_unittest.cc
@@ -17,6 +17,12 @@ class AwBrowserContextTest : public testing::Test { protected: + // Runs before the first test + static void SetUpTestSuite() { + net::NetworkChangeNotifier::SetFactory( + new AwNetworkChangeNotifierFactory()); + } + void SetUp() override { mojo::core::Init(); test_content_client_initializer_ = @@ -25,8 +31,6 @@ AwFeatureListCreator* aw_feature_list_creator = new AwFeatureListCreator(); aw_feature_list_creator->CreateLocalState(); browser_process_ = new AwBrowserProcess(aw_feature_list_creator); - net::NetworkChangeNotifier::SetFactory( - new AwNetworkChangeNotifierFactory()); } void TearDown() override {
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc index bcccb18..01ed19d 100644 --- a/ash/accelerators/accelerator_controller_impl.cc +++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -68,6 +68,7 @@ #include "ash/wm/overview/overview_controller.h" #include "ash/wm/screen_pinning_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "ash/wm/tablet_mode/tablet_mode_window_manager.h" #include "ash/wm/window_cycle_controller.h" #include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_state.h" @@ -756,6 +757,12 @@ accelerators::ToggleMinimized(); } +void HandleTopWindowMinimizeOnBack() { + base::RecordAction( + base::UserMetricsAction("Accel_Minimize_Top_Window_On_Back")); + WindowState::Get(TabletModeWindowManager::GetTopWindow())->Minimize(); +} + void HandleShowImeMenuBubble() { base::RecordAction(UserMetricsAction("Accel_Show_Ime_Menu_Bubble")); @@ -1674,6 +1681,8 @@ return CanHandleWindowSnap(); case FOCUS_PIP: return !!FindPipWidget(); + case MINIMIZE_TOP_WINDOW_ON_BACK: + return TabletModeWindowManager::ShouldMinimizeTopWindowOnBack(); // The following are always enabled. case BRIGHTNESS_DOWN: @@ -2070,6 +2079,9 @@ case WINDOW_MINIMIZE: HandleWindowMinimize(); break; + case MINIMIZE_TOP_WINDOW_ON_BACK: + HandleTopWindowMinimizeOnBack(); + break; } }
diff --git a/ash/accelerators/accelerator_table_unittest.cc b/ash/accelerators/accelerator_table_unittest.cc index 5b26aedc..4629935 100644 --- a/ash/accelerators/accelerator_table_unittest.cc +++ b/ash/accelerators/accelerator_table_unittest.cc
@@ -17,10 +17,10 @@ namespace { // The number of non-Search-based accelerators. -constexpr int kNonSearchAcceleratorsNum = 93; +constexpr int kNonSearchAcceleratorsNum = 94; // The hash of non-Search-based accelerators. See HashAcceleratorData(). constexpr char kNonSearchAcceleratorsHash[] = - "0be65cc67955b2320bef45ab7a9c68bb"; + "6b85e809b6de996abea7e88c89215d0c"; struct Cmp { bool operator()(const AcceleratorData& lhs,
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 09ea973..47be772 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -570,7 +570,7 @@ <message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_VIRTUAL_KEYBOARD" desc="The label used in the accessibility menu of the system tray to toggle on/off the onscreen keyboard."> On-screen keyboard </message> - <message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SWITCH_ACCESS" desc="The label used in the accessibility menu of the system tray to toggle switch access, a feature that allows the entire device to be controlled with as few as 1 switch or button."> + <message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SWITCH_ACCESS" desc="The label used in the accessibility menu of the system tray to toggle Switch Access, a feature that allows the entire device to be controlled with as few as 1 switch or button."> Switch Access </message> <message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_ADDITIONAL_SETTINGS" desc="The sub-header label for additional setting in accessibility menu of system tray."> @@ -1817,6 +1817,9 @@ <message name="IDS_ASH_LOGIN_PARENT_ACCESS_NEXT_NUMBER_PROMPT" desc="Accessible prompt read when next access code input field has been focused. Asks user to enter next piece of the access code."> Next number </message> + <message name="IDS_ASH_LOGIN_SIGN_IN_REQUIRED_MESSAGE" desc="Message shown in the login screen when online sign-in is required."> + Sign in required + </message> <message name="IDS_ASH_LOGIN_SMART_CARD_SIGN_IN_MESSAGE" desc="Label for the button shown in the user pod that starts signing in via a smart card."> Sign in with smart card </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_LOGIN_SIGN_IN_REQUIRED_MESSAGE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_LOGIN_SIGN_IN_REQUIRED_MESSAGE.png.sha1 new file mode 100644 index 0000000..c953213 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_LOGIN_SIGN_IN_REQUIRED_MESSAGE.png.sha1
@@ -0,0 +1 @@ +7cc1daa653d0cccf60f7d238cfe11025431c01a9 \ No newline at end of file
diff --git a/ash/home_screen/drag_window_from_shelf_controller.cc b/ash/home_screen/drag_window_from_shelf_controller.cc index eb31b8a4..f95ef87 100644 --- a/ash/home_screen/drag_window_from_shelf_controller.cc +++ b/ash/home_screen/drag_window_from_shelf_controller.cc
@@ -168,16 +168,17 @@ if (overview_controller->InOverviewSession()) { const SplitViewController::SnapPosition snap_position = GetSnapPosition(location_in_screen); - SplitViewDragIndicators::WindowDraggingState window_dragging_state = - SplitViewDragIndicators::ComputeWindowDraggingState( - drag_started_, - SplitViewDragIndicators::WindowDraggingState::kFromShelf, - snap_position); OverviewSession* overview_session = overview_controller->overview_session(); - overview_session->SetSplitViewDragIndicatorsWindowDraggingState( - window_dragging_state, location_in_screen); + overview_session->UpdateSplitViewDragIndicatorsWindowDraggingStates( + Shell::GetPrimaryRootWindow(), /*is_dragging=*/true, + SplitViewDragIndicators::WindowDraggingState::kFromShelf, + snap_position); overview_session->OnWindowDragContinued( - window_, gfx::PointF(location_in_screen), window_dragging_state); + window_, gfx::PointF(location_in_screen), + SplitViewDragIndicators::ComputeWindowDraggingState( + /*is_dragging=*/true, + SplitViewDragIndicators::WindowDraggingState::kFromShelf, + snap_position)); if (snap_position != SplitViewController::NONE) { // If the dragged window is in snap preview area, make sure overview is @@ -323,9 +324,10 @@ ShowOverviewDuringOrAfterDrag(); OverviewSession* overview_session = overview_controller->overview_session(); - overview_session->SetSplitViewDragIndicatorsWindowDraggingState( + overview_session->UpdateSplitViewDragIndicatorsWindowDraggingStates( + Shell::GetPrimaryRootWindow(), /*is_dragging=*/false, SplitViewDragIndicators::WindowDraggingState::kNoDrag, - location_in_screen); + SplitViewController::NONE); overview_session->OnWindowDragEnded( window_, gfx::PointF(location_in_screen), should_drop_window_in_overview,
diff --git a/ash/home_screen/drag_window_from_shelf_controller_unittest.cc b/ash/home_screen/drag_window_from_shelf_controller_unittest.cc index 3999704..341a13c 100644 --- a/ash/home_screen/drag_window_from_shelf_controller_unittest.cc +++ b/ash/home_screen/drag_window_from_shelf_controller_unittest.cc
@@ -481,33 +481,25 @@ OverviewController* overview_controller = Shell::Get()->overview_controller(); EXPECT_TRUE(overview_controller->InOverviewSession()); OverviewSession* overview_session = overview_controller->overview_session(); - SplitViewDragIndicators::WindowDraggingState window_dragging_state = - overview_session->split_view_drag_indicators() - ->current_window_dragging_state(); + ASSERT_EQ(1u, overview_session->grid_list().size()); + SplitViewDragIndicators* drag_indicators = + overview_session->grid_list()[0]->split_view_drag_indicators(); EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromShelf, - window_dragging_state); + drag_indicators->current_window_dragging_state()); Drag(gfx::Point(0, 200), 0.5f, 0.5f); - window_dragging_state = overview_session->split_view_drag_indicators() - ->current_window_dragging_state(); EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kToSnapLeft, - window_dragging_state); + drag_indicators->current_window_dragging_state()); Drag(gfx::Point(0, 300), 0.5f, 0.5f); - window_dragging_state = overview_session->split_view_drag_indicators() - ->current_window_dragging_state(); EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromShelf, - window_dragging_state); + drag_indicators->current_window_dragging_state()); Drag(gfx::Point(0, 200), 0.5f, 0.5f); - window_dragging_state = overview_session->split_view_drag_indicators() - ->current_window_dragging_state(); EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kToSnapLeft, - window_dragging_state); + drag_indicators->current_window_dragging_state()); Drag(gfx::Point(200, 200), 0.5f, 0.5f); - window_dragging_state = overview_session->split_view_drag_indicators() - ->current_window_dragging_state(); EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromShelf, - window_dragging_state); + drag_indicators->current_window_dragging_state()); EndDrag(shelf_bounds.CenterPoint(), /*velocity_y=*/base::nullopt);
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc index 4c38440c..2cc6532 100644 --- a/ash/login/ui/login_auth_user_view.cc +++ b/ash/login/ui/login_auth_user_view.cc
@@ -50,6 +50,7 @@ #include "ui/views/border.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/button/md_text_button.h" +#include "ui/views/controls/highlight_path_generator.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/flex_layout.h" @@ -80,9 +81,6 @@ constexpr SkColor kChallengeResponseErrorColor = SkColorSetRGB(0xEE, 0x67, 0x5C); -// The color of the online sign-in message text. -constexpr SkColor kOnlineSignInMessageColor = SkColorSetRGB(0xE6, 0x7C, 0x73); - // The color of the disabled auth message bubble when the color extracted from // wallpaper is transparent or invalid (i.e. color calculation fails or is // disabled). @@ -121,6 +119,24 @@ constexpr int kNonEmptyWidthDp = 1; +// The color of the required online sign-in message text. +constexpr SkColor kSystemButtonMessageColor = SK_ColorBLACK; +// The background color of the required online sign-in button. +constexpr SkColor kSystemButtonBackgroundColor = + SkColorSetA(gfx::kGoogleRed300, SK_AlphaOPAQUE); + +constexpr int kUserInfoBubbleWidth = 192; +constexpr int kUserInfoBubbleExternalPadding = 8; +constexpr int kSystemButtonIconSize = 20; +constexpr int kSystemButtonMarginTopBottomDp = 6; +constexpr int kSystemButtonMarginLeftRightDp = 16; +constexpr int kSystemButtonBorderRadius = 16; +constexpr int kSystemButtonImageLabelSpacing = 8; +constexpr int kSystemButtonMaxLabelWidthDp = + kUserInfoBubbleWidth - 2 * kUserInfoBubbleExternalPadding - + kSystemButtonIconSize - kSystemButtonImageLabelSpacing - + 2 * kSystemButtonBorderRadius; + // Returns an observer that will hide |view| when it fires. The observer will // delete itself after firing (by returning true). Make sure to call // |observer->SetActive()| after attaching it. @@ -161,22 +177,69 @@ DISALLOW_COPY_AND_ASSIGN(ClearPasswordAndHideAnimationObserver); }; -void DecorateOnlineSignInMessage(views::LabelButton* label_button) { - label_button->SetPaintToLayer(); - label_button->layer()->SetFillsBoundsOpaquely(false); - label_button->SetImage( - views::Button::STATE_NORMAL, - CreateVectorIcon(kLockScreenAlertIcon, kOnlineSignInMessageColor)); - label_button->SetTextSubpixelRenderingEnabled(false); - label_button->SetTextColor(views::Button::STATE_NORMAL, - kOnlineSignInMessageColor); - label_button->SetTextColor(views::Button::STATE_HOVERED, - kOnlineSignInMessageColor); - label_button->SetTextColor(views::Button::STATE_PRESSED, - kOnlineSignInMessageColor); - label_button->SetBorder(views::CreateEmptyBorder(gfx::Insets(9, 0))); +SkPath GetSystemButtonHighlightPath(const views::View* view) { + gfx::Rect rect(view->GetLocalBounds()); + return SkPath().addRoundRect(gfx::RectToSkRect(rect), + kSystemButtonBorderRadius, + kSystemButtonBorderRadius); } +class SystemButtonHighlightPathGenerator + : public views::HighlightPathGenerator { + public: + SystemButtonHighlightPathGenerator() = default; + SystemButtonHighlightPathGenerator( + const SystemButtonHighlightPathGenerator&) = delete; + SystemButtonHighlightPathGenerator& operator=( + const SystemButtonHighlightPathGenerator&) = delete; + + // views::HighlightPathGenerator: + SkPath GetHighlightPath(const views::View* view) override { + return GetSystemButtonHighlightPath(view); + } +}; + +class SystemButton : public views::LabelButton { + public: + SystemButton(views::ButtonListener* listener, const base::string16& text) + : LabelButton(listener, text) { + SetImageLabelSpacing(kSystemButtonImageLabelSpacing); + label()->SetMultiLine(true); + label()->SetMaximumWidth(kSystemButtonMaxLabelWidthDp); + label()->SetFontList( + gfx::FontList().DeriveWithWeight(gfx::Font::Weight::MEDIUM)); + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); + SetImage(views::Button::STATE_NORMAL, + CreateVectorIcon(kLockScreenAlertIcon, kSystemButtonMessageColor)); + SetTextSubpixelRenderingEnabled(false); + SetTextColor(views::Button::STATE_NORMAL, kSystemButtonMessageColor); + SetTextColor(views::Button::STATE_HOVERED, kSystemButtonMessageColor); + SetTextColor(views::Button::STATE_PRESSED, kSystemButtonMessageColor); + views::HighlightPathGenerator::Install( + this, std::make_unique<SystemButtonHighlightPathGenerator>()); + } + + SystemButton(const SystemButton&) = delete; + SystemButton& operator=(const SystemButton&) = delete; + ~SystemButton() override = default; + + // views::LabelButton: + void PaintButtonContents(gfx::Canvas* canvas) override { + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setColor(kSystemButtonBackgroundColor); + flags.setStyle(cc::PaintFlags::kFill_Style); + canvas->DrawPath(GetSystemButtonHighlightPath(this), flags); + } + + gfx::Insets GetInsets() const override { + return gfx::Insets( + kSystemButtonMarginTopBottomDp, kSystemButtonMarginLeftRightDp, + kSystemButtonMarginTopBottomDp, kSystemButtonMarginLeftRightDp); + } +}; + // The label shown below the fingerprint icon. class FingerprintLabel : public views::Label { public: @@ -775,10 +838,9 @@ callbacks.on_easy_unlock_icon_hovered, callbacks.on_easy_unlock_icon_tapped); - auto online_sign_in_message = std::make_unique<views::LabelButton>( - this, base::UTF8ToUTF16(user.basic_user_info.display_name)); + auto online_sign_in_message = std::make_unique<SystemButton>( + this, l10n_util::GetStringUTF16(IDS_ASH_LOGIN_SIGN_IN_REQUIRED_MESSAGE)); online_sign_in_message_ = online_sign_in_message.get(); - DecorateOnlineSignInMessage(online_sign_in_message_); auto disabled_auth_message = std::make_unique<DisabledAuthMessageView>(); disabled_auth_message_ = disabled_auth_message.get(); @@ -1172,7 +1234,7 @@ if (user_changed) password_view_->Clear(); online_sign_in_message_->SetText( - base::UTF8ToUTF16(user.basic_user_info.display_name)); + l10n_util::GetStringUTF16(IDS_ASH_LOGIN_SIGN_IN_REQUIRED_MESSAGE)); } void LoginAuthUserView::SetFingerprintState(FingerprintState state) {
diff --git a/ash/public/cpp/accelerators.cc b/ash/public/cpp/accelerators.cc index 11b1536..7b907f1 100644 --- a/ash/public/cpp/accelerators.cc +++ b/ash/public/cpp/accelerators.cc
@@ -161,6 +161,7 @@ {true, ui::VKEY_OEM_PLUS, ui::EF_ALT_DOWN, TOGGLE_MAXIMIZED}, {true, ui::VKEY_BROWSER_FORWARD, ui::EF_CONTROL_DOWN, FOCUS_NEXT_PANE}, {true, ui::VKEY_BROWSER_BACK, ui::EF_CONTROL_DOWN, FOCUS_PREVIOUS_PANE}, + {true, ui::VKEY_BROWSER_BACK, ui::EF_NONE, MINIMIZE_TOP_WINDOW_ON_BACK}, // Moving active window between displays shortcut. {true, ui::VKEY_M, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
diff --git a/ash/public/cpp/accelerators.h b/ash/public/cpp/accelerators.h index 6430d5d1..7072d53 100644 --- a/ash/public/cpp/accelerators.h +++ b/ash/public/cpp/accelerators.h
@@ -114,6 +114,7 @@ WINDOW_CYCLE_SNAP_LEFT, WINDOW_CYCLE_SNAP_RIGHT, WINDOW_MINIMIZE, + MINIMIZE_TOP_WINDOW_ON_BACK, // Debug accelerators are intentionally at the end, so that if you remove one // you don't need to update tests which check hashes of the ids.
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index 332c222..cb352d9 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -11,6 +11,9 @@ namespace ash { namespace features { +const base::Feature kAllowAmbientEQ{"AllowAmbientEQ", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kDockedMagnifier{"DockedMagnifier", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -100,6 +103,10 @@ const base::Feature kDragFromShelfToHomeOrOverview{ "DragFromShelfToHomeOrOverview", base::FEATURE_ENABLED_BY_DEFAULT}; +bool IsAllowAmbientEQEnabled() { + return base::FeatureList::IsEnabled(kAllowAmbientEQ); +} + bool IsHideArcMediaNotificationsEnabled() { return base::FeatureList::IsEnabled(kMediaSessionNotification) && base::FeatureList::IsEnabled(kHideArcMediaNotifications);
diff --git a/ash/public/cpp/ash_features.h b/ash/public/cpp/ash_features.h index aad0db0e..d03bbba8 100644 --- a/ash/public/cpp/ash_features.h +++ b/ash/public/cpp/ash_features.h
@@ -11,6 +11,10 @@ namespace ash { namespace features { +// Enables the UI to support Ambient EQ if the device supports it. +// See https://crbug.com/1021193 for more details. +ASH_PUBLIC_EXPORT extern const base::Feature kAllowAmbientEQ; + // Enables the docked (a.k.a. picture-in-picture) magnifier. // TODO(afakhry): Remove this after the feature is fully launched. // https://crbug.com/709824. @@ -129,6 +133,8 @@ // launched. ASH_PUBLIC_EXPORT extern const base::Feature kDragFromShelfToHomeOrOverview; +ASH_PUBLIC_EXPORT bool IsAllowAmbientEQEnabled(); + ASH_PUBLIC_EXPORT bool IsHideArcMediaNotificationsEnabled(); ASH_PUBLIC_EXPORT bool IsKeyboardShortcutViewerAppEnabled();
diff --git a/ash/public/cpp/ash_pref_names.cc b/ash/public/cpp/ash_pref_names.cc index c9b4443..df29324 100644 --- a/ash/public/cpp/ash_pref_names.cc +++ b/ash/public/cpp/ash_pref_names.cc
@@ -80,7 +80,7 @@ // A boolean pref which determines whether select-to-speak is enabled. const char kAccessibilitySelectToSpeakEnabled[] = "settings.a11y.select_to_speak"; -// A boolean pref which determines whether switch access is enabled. +// A boolean pref which determines whether Switch Access is enabled. const char kAccessibilitySwitchAccessEnabled[] = "settings.a11y.switch_access.enabled"; // A pref that stores the key code for the "select" action. @@ -102,7 +102,7 @@ const char kAccessibilitySwitchAccessPreviousSetting[] = "settings.a11y.switch_access.previous.setting"; // A boolean pref which determines whether auto-scanning is enabled within -// switch access. +// Switch Access. const char kAccessibilitySwitchAccessAutoScanEnabled[] = "settings.a11y.switch_access.auto_scan.enabled"; // An integer pref which determines time delay in ms before automatically
diff --git a/ash/resources/vector_icons/lock_screen_alert.icon b/ash/resources/vector_icons/lock_screen_alert.icon index db94d704..2192048 100644 --- a/ash/resources/vector_icons/lock_screen_alert.icon +++ b/ash/resources/vector_icons/lock_screen_alert.icon
@@ -2,40 +2,26 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 40, -MOVE_TO, 1.67f, 35, -LINE_TO, 38.33f, 35, -LINE_TO, 20, 3.33f, -LINE_TO, 1.67f, 35, -CLOSE, -MOVE_TO, 22, 30, -LINE_TO, 18, 30, -LINE_TO, 18, 26, -LINE_TO, 22, 26, -LINE_TO, 22, 30, -CLOSE, -MOVE_TO, 22, 23, -LINE_TO, 18, 23, -LINE_TO, 18, 16, -LINE_TO, 22, 16, -LINE_TO, 22, 23, -CLOSE - CANVAS_DIMENSIONS, 20, -MOVE_TO, 0.83f, 17.5f, -LINE_TO, 19.17f, 17.5f, -LINE_TO, 10, 1.67f, -LINE_TO, 0.83f, 17.5f, +MOVE_TO, 10.87f, 2.5f, +R_LINE_TO, 8, 14, +ARC_TO, 1, 1, 0, 0, 1, 18, 18, +H_LINE_TO, 2, +R_ARC_TO, 1, 1, 0, 0, 1, -0.87f, -1.5f, +R_LINE_TO, 8, -14, +R_ARC_TO, 1, 1, 0, 0, 1, 1.74f, 0, CLOSE, -MOVE_TO, 10.83f, 15, -LINE_TO, 9.17f, 15, -LINE_TO, 9.17f, 13.33f, -LINE_TO, 10.83f, 13.33f, -LINE_TO, 10.83f, 15, +MOVE_TO, 10, 5.02f, +LINE_TO, 3.72f, 16, +R_H_LINE_TO, 12.55f, CLOSE, -MOVE_TO, 10.83f, 11.67f, -LINE_TO, 9.17f, 11.67f, -LINE_TO, 9.17f, 8.33f, -LINE_TO, 10.83f, 8.33f, -LINE_TO, 10.83f, 11.67f, +MOVE_TO, 11, 13, +R_V_LINE_TO, 2, +H_LINE_TO, 9, +R_V_LINE_TO, -2, +CLOSE, +R_MOVE_TO, 0, -5, +R_V_LINE_TO, 4, +H_LINE_TO, 9, +V_LINE_TO, 8, CLOSE
diff --git a/ash/shelf/back_button.cc b/ash/shelf/back_button.cc index 4871082..22a0eb39 100644 --- a/ash/shelf/back_button.cc +++ b/ash/shelf/back_button.cc
@@ -8,6 +8,8 @@ #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_focus_cycler.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/wm/tablet_mode/tablet_mode_window_manager.h" +#include "ash/wm/window_state.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "ui/aura/window.h" @@ -61,15 +63,20 @@ views::InkDrop* ink_drop) { base::RecordAction(base::UserMetricsAction("AppList_BackButtonPressed")); - // Send up event as well as down event as ARC++ clients expect this sequence. - // TODO: Investigate if we should be using the current modifiers. - aura::Window* root_window = GetWidget()->GetNativeWindow()->GetRootWindow(); - ui::KeyEvent press_key_event(ui::ET_KEY_PRESSED, ui::VKEY_BROWSER_BACK, - ui::EF_NONE); - ignore_result(root_window->GetHost()->SendEventToSink(&press_key_event)); - ui::KeyEvent release_key_event(ui::ET_KEY_RELEASED, ui::VKEY_BROWSER_BACK, + if (TabletModeWindowManager::ShouldMinimizeTopWindowOnBack()) { + WindowState::Get(TabletModeWindowManager::GetTopWindow())->Minimize(); + } else { + // Send up event as well as down event as ARC++ clients expect this + // sequence. + // TODO: Investigate if we should be using the current modifiers. + aura::Window* root_window = GetWidget()->GetNativeWindow()->GetRootWindow(); + ui::KeyEvent press_key_event(ui::ET_KEY_PRESSED, ui::VKEY_BROWSER_BACK, ui::EF_NONE); - ignore_result(root_window->GetHost()->SendEventToSink(&release_key_event)); + ignore_result(root_window->GetHost()->SendEventToSink(&press_key_event)); + ui::KeyEvent release_key_event(ui::ET_KEY_RELEASED, ui::VKEY_BROWSER_BACK, + ui::EF_NONE); + ignore_result(root_window->GetHost()->SendEventToSink(&release_key_event)); + } } } // namespace ash
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 8cc20ad..d9322c8 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -1079,6 +1079,10 @@ return HotseatState::kShown; auto* app_list_controller = Shell::Get()->app_list_controller(); + // If the app list controller is null, we are probably in the middle of + // a shutdown, let's not change the hotseat state. + if (!app_list_controller) + return hotseat_state(); const auto* overview_controller = Shell::Get()->overview_controller(); const bool in_overview = ((overview_controller && overview_controller->InOverviewSession()) ||
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index 26daf257..434b2cb 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -2178,7 +2178,8 @@ // widget are created. EXPECT_TRUE(overview_grid->drop_target_widget()); EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, - overview_session->split_view_drag_indicators() + overview_session->grid_list()[0] + ->split_view_drag_indicators() ->current_window_dragging_state()); // Now drop the window, and validate the indicators and the drop target were // removed. @@ -2189,7 +2190,8 @@ EXPECT_TRUE(overview_session->no_windows_widget_for_testing()); EXPECT_FALSE(overview_grid->drop_target_widget()); EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kNoDrag, - overview_session->split_view_drag_indicators() + overview_session->grid_list()[0] + ->split_view_drag_indicators() ->current_window_dragging_state()); }
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index ae51412..412543a 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -41,6 +41,7 @@ #include "ash/wm/resize_shadow_controller.h" #include "ash/wm/splitview/split_view_constants.h" #include "ash/wm/splitview/split_view_divider.h" +#include "ash/wm/splitview/split_view_utils.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/tablet_mode/tablet_mode_window_state.h" #include "ash/wm/window_util.h" @@ -373,6 +374,10 @@ OverviewSession* overview_session) : root_window_(root_window), overview_session_(overview_session), + split_view_drag_indicators_( + ShouldAllowSplitView() + ? std::make_unique<SplitViewDragIndicators>(root_window) + : nullptr), bounds_(GetGridBoundsInScreen(root_window, /*divider_changed=*/false)) { for (auto* window : windows) { if (window->GetRootWindow() != root_window) @@ -647,13 +652,11 @@ overview_session_->window_drag_controller()->item()) { ignored_items.insert(overview_session_->window_drag_controller()->item()); } - auto* split_view_drag_indicators = - overview_session_->split_view_drag_indicators(); const gfx::Rect grid_bounds = GetGridBoundsInScreenForSplitview( root_window_, - split_view_drag_indicators + split_view_drag_indicators_ ? base::make_optional( - split_view_drag_indicators->current_window_dragging_state()) + split_view_drag_indicators_->current_window_dragging_state()) : base::nullopt); SetBoundsAndUpdatePositions(grid_bounds, ignored_items, /*animate=*/true); } @@ -713,7 +716,7 @@ // Update the grid's bounds. const gfx::Rect wanted_grid_bounds = GetGridBoundsInScreenForSplitview( - dragged_window, base::make_optional(window_dragging_state)); + root_window_, base::make_optional(window_dragging_state)); if (bounds_ != wanted_grid_bounds) { SetBoundsAndUpdatePositions(wanted_grid_bounds, {GetOverviewItemContaining(dragged_window)}, @@ -721,6 +724,18 @@ } } +void OverviewGrid::SetSplitViewDragIndicatorsDraggedWindow( + aura::Window* dragged_window) { + DCHECK(split_view_drag_indicators_); + split_view_drag_indicators_->SetDraggedWindow(dragged_window); +} + +void OverviewGrid::SetSplitViewDragIndicatorsWindowDraggingState( + SplitViewDragIndicators::WindowDraggingState window_dragging_state) { + DCHECK(split_view_drag_indicators_); + split_view_drag_indicators_->SetWindowDraggingState(window_dragging_state); +} + bool OverviewGrid::MaybeUpdateDesksWidgetBounds() { if (!desks_widget_) return false; @@ -864,7 +879,7 @@ // Update the grid bounds and reposition windows. Since the grid bounds might // be updated based on the preview area during drag, but the window finally // didn't be snapped to the preview area. - SetBoundsAndUpdatePositions(GetGridBoundsInScreenForSplitview(dragged_window), + SetBoundsAndUpdatePositions(GetGridBoundsInScreenForSplitview(root_window_), /*ignored_items=*/{}, /*animate=*/true); } @@ -903,6 +918,9 @@ } void OverviewGrid::OnDisplayMetricsChanged() { + if (split_view_drag_indicators_) + split_view_drag_indicators_->OnDisplayBoundsChanged(); + // In case of split view mode, the grid bounds and item positions will be // updated in |OnSplitViewDividerPositionChanged|. if (SplitViewController::Get(root_window_)->InSplitViewMode()) @@ -1910,10 +1928,8 @@ // Shift the widget down to make room for the splitview indicator guidance // when it's shown at the top of the screen when in portrait mode and no other // windows are snapped. - auto* split_view_drag_indicators = - overview_session_->split_view_drag_indicators(); - if (split_view_drag_indicators && - split_view_drag_indicators->current_window_dragging_state() == + if (split_view_drag_indicators_ && + split_view_drag_indicators_->current_window_dragging_state() == SplitViewDragIndicators::WindowDraggingState::kFromOverview && !IsCurrentScreenOrientationLandscape() && !SplitViewController::Get(root_window_)->InSplitViewMode()) {
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h index 840d563..437b474 100644 --- a/ash/wm/overview/overview_grid.h +++ b/ash/wm/overview/overview_grid.h
@@ -146,6 +146,13 @@ aura::Window* dragged_window, SplitViewDragIndicators::WindowDraggingState window_dragging_state); + // Sets the dragged window on |split_view_drag_indicators_|. + void SetSplitViewDragIndicatorsDraggedWindow(aura::Window* dragged_window); + + // Sets the window dragging state on |split_view_drag_indicators_|. + void SetSplitViewDragIndicatorsWindowDraggingState( + SplitViewDragIndicators::WindowDraggingState window_dragging_state); + // Updates the desks bar widget bounds if necessary. // Returns true if the desks widget's bounds have been updated. bool MaybeUpdateDesksWidgetBounds(); @@ -326,6 +333,10 @@ return window_list_; } + SplitViewDragIndicators* split_view_drag_indicators() { + return split_view_drag_indicators_.get(); + } + const DesksBarView* desks_bar_view() const { return desks_bar_view_; } const gfx::Rect bounds() const { return bounds_; } @@ -422,6 +433,10 @@ // Vector containing all the windows in this grid. std::vector<std::unique_ptr<OverviewItem>> window_list_; + // The owner of the widget that displays split-view-related information. Null + // if split view is unsupported (see |ShouldAllowSplitView|). + std::unique_ptr<SplitViewDragIndicators> split_view_drag_indicators_; + // Widget that contains the DeskBarView contents when the Virtual Desks // feature is enabled. std::unique_ptr<views::Widget> desks_widget_;
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index faa001b..c0f9888 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -110,9 +110,6 @@ if (restore_focus_window_) restore_focus_window_->AddObserver(this); - if (ShouldAllowSplitView()) - split_view_drag_indicators_ = std::make_unique<SplitViewDragIndicators>(); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); std::sort(root_windows.begin(), root_windows.end(), [](const aura::Window* a, const aura::Window* b) { @@ -323,16 +320,37 @@ void OverviewSession::SetSplitViewDragIndicatorsDraggedWindow( aura::Window* dragged_window) { - DCHECK(split_view_drag_indicators_); - split_view_drag_indicators_->SetDraggedWindow(dragged_window); + for (std::unique_ptr<OverviewGrid>& grid : grid_list_) + grid->SetSplitViewDragIndicatorsDraggedWindow(dragged_window); } -void OverviewSession::SetSplitViewDragIndicatorsWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState window_dragging_state, - const gfx::Point& event_location) { - DCHECK(split_view_drag_indicators_); - split_view_drag_indicators_->SetWindowDraggingState(window_dragging_state, - event_location); +void OverviewSession::UpdateSplitViewDragIndicatorsWindowDraggingStates( + const aura::Window* root_window_being_dragged_in, + bool is_dragging, + SplitViewDragIndicators::WindowDraggingState non_snap_state, + SplitViewController::SnapPosition snap_position) { + using State = SplitViewDragIndicators::WindowDraggingState; + const State window_dragging_state_on_root_window_being_dragged_in = + SplitViewDragIndicators::ComputeWindowDraggingState( + is_dragging, non_snap_state, snap_position); + const State window_dragging_state_on_root_windows_not_being_dragged_in = + SplitViewDragIndicators::ComputeWindowDraggingState( + is_dragging, non_snap_state, SplitViewController::NONE); + for (std::unique_ptr<OverviewGrid>& grid : grid_list_) { + grid->SetSplitViewDragIndicatorsWindowDraggingState( + grid->root_window() == root_window_being_dragged_in + ? window_dragging_state_on_root_window_being_dragged_in + : window_dragging_state_on_root_windows_not_being_dragged_in); + } +} + +void OverviewSession::RearrangeDuringDrag(aura::Window* dragged_window) { + for (std::unique_ptr<OverviewGrid>& grid : grid_list_) { + DCHECK(grid->split_view_drag_indicators()); + grid->RearrangeDuringDrag( + dragged_window, + grid->split_view_drag_indicators()->current_window_dragging_state()); + } } OverviewGrid* OverviewSession::GetGridWithRootWindow( @@ -777,9 +795,6 @@ GetGridWithRootWindow(Shell::GetRootWindowForDisplayId(display.id())) ->OnDisplayMetricsChanged(); - if (split_view_drag_indicators_) - split_view_drag_indicators_->OnDisplayBoundsChanged(); - // The no windows widget is on the primary root window. If |display| // corresponds to another root window, then we are done. if (display.id() !=
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h index 906c8a6..6a37dec 100644 --- a/ash/wm/overview/overview_session.h +++ b/ash/wm/overview/overview_session.h
@@ -26,7 +26,6 @@ #include "ui/wm/public/activation_change_observer.h" namespace gfx { -class Point; class PointF; } // namespace gfx @@ -130,15 +129,23 @@ // Activates |item's| window. void SelectWindow(OverviewItem* item); - // Sets the dragged window on |split_view_drag_indicators_|. + // Sets the dragged window on the split view drag indicators. void SetSplitViewDragIndicatorsDraggedWindow(aura::Window* dragged_window); - // Called to show or hide the split view drag indicators. This will do - // nothing if split view is not enabled. |event_location| is used to reparent - // |split_view_drag_indicators_|'s widget, if necessary. - void SetSplitViewDragIndicatorsWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState window_dragging_state, - const gfx::Point& event_location); + // This function sets the window dragging state on the split view drag + // indicators on every root window. On |root_window_being_dragged_in|, the + // state is determined by forwarding the other three arguments to + // |SplitViewDragIndicators::ComputeWindowDraggingState|. On other root + // windows, as snap previews are not appropriate, the state is determined + // similarly but with |SplitViewController::NONE| instead of |snap_position|. + void UpdateSplitViewDragIndicatorsWindowDraggingStates( + const aura::Window* root_window_being_dragged_in, + bool is_dragging, + SplitViewDragIndicators::WindowDraggingState non_snap_state, + SplitViewController::SnapPosition snap_position); + + // See |OverviewGrid::RearrangeDuringDrag|. + void RearrangeDuringDrag(aura::Window* dragged_window); // Retrieves the window grid whose root window matches |root_window|. Returns // nullptr if the window grid is not found. @@ -296,10 +303,6 @@ is_shutting_down_ = is_shutting_down; } - SplitViewDragIndicators* split_view_drag_indicators() { - return split_view_drag_indicators_.get(); - } - const std::vector<std::unique_ptr<OverviewGrid>>& grid_list() const { return grid_list_; } @@ -381,10 +384,6 @@ // List of all the window overview grids, one for each root window. std::vector<std::unique_ptr<OverviewGrid>> grid_list_; - // The owner of the widget which displays splitview related information in - // overview mode. This will be nullptr if split view is not enabled. - std::unique_ptr<SplitViewDragIndicators> split_view_drag_indicators_; - // The following variables are used for metric collection purposes. All of // them refer to this particular overview session and are not cumulative: // The time when overview was started.
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc index 8097b99..3f992bf 100644 --- a/ash/wm/overview/overview_session_unittest.cc +++ b/ash/wm/overview/overview_session_unittest.cc
@@ -4077,6 +4077,7 @@ overview_session()->Drag(item1, gfx::PointF()); EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kToSnapLeft, overview_session() + ->grid_list()[0] ->split_view_drag_indicators() ->current_window_dragging_state()); EXPECT_FALSE(window2->layer()->clip_rect().IsEmpty()); @@ -5669,7 +5670,8 @@ } // Test dragging to snap an overview item on an external display. -TEST_P(SplitViewOverviewSessionInClamshellTestMultiDisplayOnly, Dragging) { +TEST_P(SplitViewOverviewSessionInClamshellTestMultiDisplayOnly, + DraggingOnExternalDisplay) { UpdateDisplay("800x600,800x600"); aura::Window::Windows root_windows = Shell::GetAllRootWindows(); ASSERT_EQ(2u, root_windows.size()); @@ -5684,7 +5686,7 @@ SplitViewController* split_view_controller = SplitViewController::Get(root_windows[1]); SplitViewDragIndicators* indicators = - overview_session()->split_view_drag_indicators(); + grid_on_root2->split_view_drag_indicators(); Shell::Get()->cursor_manager()->SetDisplay( display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[1])); @@ -5726,6 +5728,123 @@ split_view_controller->state()); } +// Test dragging from one display to another. +TEST_P(SplitViewOverviewSessionInClamshellTestMultiDisplayOnly, + MultiDisplayDragging) { + wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager(); + UpdateDisplay("800x600,800x600"); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + ASSERT_EQ(2u, root_windows.size()); + const display::Display display_with_root1 = + display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[0]); + const display::Display display_with_root2 = + display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[1]); + const gfx::Rect bounds_within_root1(0, 0, 400, 400); + const gfx::Rect bounds_within_root2(800, 0, 400, 400); + std::unique_ptr<aura::Window> window1 = CreateTestWindow(bounds_within_root1); + std::unique_ptr<aura::Window> window2 = CreateTestWindow(bounds_within_root1); + std::unique_ptr<aura::Window> window3 = CreateTestWindow(bounds_within_root2); + ToggleOverview(); + OverviewGrid* grid_on_root1 = + overview_session()->GetGridWithRootWindow(root_windows[0]); + OverviewGrid* grid_on_root2 = + overview_session()->GetGridWithRootWindow(root_windows[1]); + OverviewItem* item1 = grid_on_root1->GetOverviewItemContaining(window1.get()); + SplitViewDragIndicators* indicators_on_root1 = + grid_on_root1->split_view_drag_indicators(); + SplitViewDragIndicators* indicators_on_root2 = + grid_on_root2->split_view_drag_indicators(); + + ASSERT_EQ(display_with_root1.id(), cursor_manager->GetDisplay().id()); + overview_session()->InitiateDrag(item1, item1->target_bounds().CenterPoint(), + /*is_touch_dragging=*/false); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kNoDrag, + indicators_on_root1->current_window_dragging_state()); + EXPECT_EQ(display_with_root1.work_area(), grid_on_root1->bounds()); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kNoDrag, + indicators_on_root2->current_window_dragging_state()); + EXPECT_EQ(display_with_root2.work_area(), grid_on_root2->bounds()); + + const gfx::PointF root1_left_snap_point(0.f, 300.f); + overview_session()->Drag(item1, root1_left_snap_point); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kToSnapLeft, + indicators_on_root1->current_window_dragging_state()); + EXPECT_EQ( + SplitViewController::Get(root_windows[0]) + ->GetSnappedWindowBoundsInScreen(SplitViewController::RIGHT, + /*window_for_minimum_size=*/nullptr), + grid_on_root1->bounds()); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, + indicators_on_root2->current_window_dragging_state()); + EXPECT_EQ(display_with_root2.work_area(), grid_on_root2->bounds()); + + const gfx::PointF root1_middle_point(400.f, 300.f); + overview_session()->Drag(item1, root1_middle_point); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, + indicators_on_root1->current_window_dragging_state()); + EXPECT_EQ(display_with_root1.work_area(), grid_on_root1->bounds()); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, + indicators_on_root2->current_window_dragging_state()); + EXPECT_EQ(display_with_root2.work_area(), grid_on_root2->bounds()); + + const gfx::PointF root1_right_snap_point(799.f, 300.f); + overview_session()->Drag(item1, root1_right_snap_point); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kToSnapRight, + indicators_on_root1->current_window_dragging_state()); + EXPECT_EQ( + SplitViewController::Get(root_windows[0]) + ->GetSnappedWindowBoundsInScreen(SplitViewController::LEFT, + /*window_for_minimum_size=*/nullptr), + grid_on_root1->bounds()); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, + indicators_on_root2->current_window_dragging_state()); + EXPECT_EQ(display_with_root2.work_area(), grid_on_root2->bounds()); + + const gfx::PointF root2_left_snap_point(800.f, 300.f); + cursor_manager->SetDisplay(display_with_root2); + overview_session()->Drag(item1, root2_left_snap_point); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, + indicators_on_root1->current_window_dragging_state()); + EXPECT_EQ(display_with_root1.work_area(), grid_on_root1->bounds()); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kToSnapLeft, + indicators_on_root2->current_window_dragging_state()); + EXPECT_EQ( + SplitViewController::Get(root_windows[1]) + ->GetSnappedWindowBoundsInScreen(SplitViewController::RIGHT, + /*window_for_minimum_size=*/nullptr), + grid_on_root2->bounds()); + + const gfx::PointF root2_right_snap_point(1599.f, 300.f); + overview_session()->Drag(item1, root2_right_snap_point); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, + indicators_on_root1->current_window_dragging_state()); + EXPECT_EQ(display_with_root1.work_area(), grid_on_root1->bounds()); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kToSnapRight, + indicators_on_root2->current_window_dragging_state()); + EXPECT_EQ( + SplitViewController::Get(root_windows[1]) + ->GetSnappedWindowBoundsInScreen(SplitViewController::LEFT, + /*window_for_minimum_size=*/nullptr), + grid_on_root2->bounds()); + + const gfx::PointF root2_middle_point(1200.f, 300.f); + overview_session()->Drag(item1, root2_middle_point); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, + indicators_on_root1->current_window_dragging_state()); + EXPECT_EQ(display_with_root1.work_area(), grid_on_root1->bounds()); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, + indicators_on_root2->current_window_dragging_state()); + EXPECT_EQ(display_with_root2.work_area(), grid_on_root2->bounds()); + + overview_session()->CompleteDrag(item1, root2_middle_point); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kNoDrag, + indicators_on_root1->current_window_dragging_state()); + EXPECT_EQ(display_with_root1.work_area(), grid_on_root1->bounds()); + EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kNoDrag, + indicators_on_root2->current_window_dragging_state()); + EXPECT_EQ(display_with_root2.work_area(), grid_on_root2->bounds()); +} + // Verify that when in overview mode, the selector items unsnappable indicator // shows up when expected. TEST_P(SplitViewOverviewSessionInClamshellTestMultiDisplayOnly,
diff --git a/ash/wm/overview/overview_utils.cc b/ash/wm/overview/overview_utils.cc index 5849c5c..4306ab6 100644 --- a/ash/wm/overview/overview_utils.cc +++ b/ash/wm/overview/overview_utils.cc
@@ -17,6 +17,7 @@ #include "ash/wm/overview/cleanup_animation_observer.h" #include "ash/wm/overview/delayed_animation_observer_impl.h" #include "ash/wm/overview/overview_controller.h" +#include "ash/wm/overview/overview_grid.h" #include "ash/wm/overview/scoped_overview_animation_settings.h" #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/splitview/split_view_utils.h" @@ -220,12 +221,12 @@ } // Get the grid bounds if a window is snapped in splitview, or what they will be -// when snapped based on |indicator_state|. +// when snapped based on |target_root| and |indicator_state|. gfx::Rect GetGridBoundsInScreenForSplitview( - aura::Window* window, + aura::Window* target_root, base::Optional<SplitViewDragIndicators::WindowDraggingState> window_dragging_state) { - auto* split_view_controller = SplitViewController::Get(window); + auto* split_view_controller = SplitViewController::Get(target_root); auto state = split_view_controller->state(); // If we are in splitview mode already just use the given state, otherwise @@ -252,7 +253,7 @@ SplitViewController::LEFT, /*window_for_minimum_size=*/nullptr); default: return screen_util:: - GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(window); + GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(target_root); } } @@ -263,20 +264,23 @@ auto* overview_session = Shell::Get()->overview_controller()->overview_session(); DCHECK(overview_session); - DCHECK(overview_session->split_view_drag_indicators()); + aura::Window* root_window = Shell::GetPrimaryRootWindow(); + DCHECK(overview_session->GetGridWithRootWindow(root_window) + ->split_view_drag_indicators()); // TODO(sammiequon): This does not work for drag from top as they have // different drag indicators object as regular overview. - auto window_dragging_state = overview_session->split_view_drag_indicators() - ->current_window_dragging_state(); - if (!SplitViewController::Get(Shell::GetPrimaryRootWindow()) - ->InSplitViewMode() && + auto window_dragging_state = + overview_session->GetGridWithRootWindow(root_window) + ->split_view_drag_indicators() + ->current_window_dragging_state(); + if (!SplitViewController::Get(root_window)->InSplitViewMode() && SplitViewDragIndicators::GetSnapPosition(window_dragging_state) == SplitViewController::NONE) { return base::nullopt; } return base::make_optional(gfx::RectF(GetGridBoundsInScreenForSplitview( - window, base::make_optional(window_dragging_state)))); + root_window, base::make_optional(window_dragging_state)))); } bool ShouldUseTabletModeGridLayout() {
diff --git a/ash/wm/overview/overview_utils.h b/ash/wm/overview/overview_utils.h index 09b04e7..c82d102f 100644 --- a/ash/wm/overview/overview_utils.h +++ b/ash/wm/overview/overview_utils.h
@@ -81,9 +81,9 @@ void MaximizeIfSnapped(aura::Window* window); // Get the grid bounds if a window is snapped in splitview, or what they will be -// when snapped based on |indicator_state|. +// when snapped based on |target_root| and |indicator_state|. gfx::Rect GetGridBoundsInScreenForSplitview( - aura::Window* window, + aura::Window* target_root, base::Optional<SplitViewDragIndicators::WindowDraggingState> window_dragging_state = base::nullopt);
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index 5f72a3e2..7392f205 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -243,9 +243,10 @@ if (should_allow_split_view_) { overview_session_->SetSplitViewDragIndicatorsDraggedWindow( item_->GetWindow()); - overview_session_->SetSplitViewDragIndicatorsWindowDraggingState( + overview_session_->UpdateSplitViewDragIndicatorsWindowDraggingStates( + GetRootWindowBeingDraggedIn(), /*is_dragging=*/true, SplitViewDragIndicators::WindowDraggingState::kFromOverview, - gfx::ToRoundedPoint(location_in_screen)); + SplitViewController::NONE); item_->HideCannotSnapWarning(); // Update the split view divider bar status if necessary. If splitview is @@ -338,8 +339,10 @@ } item_->overview_grid()->RemoveDropTarget(); if (should_allow_split_view_) { - overview_session_->SetSplitViewDragIndicatorsWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kNoDrag, gfx::Point()); + overview_session_->UpdateSplitViewDragIndicatorsWindowDraggingStates( + item_->overview_grid()->root_window(), /*is_dragging=*/false, + SplitViewDragIndicators::WindowDraggingState::kNoDrag, + SplitViewController::NONE); item_->UpdateCannotSnapWarningVisibility(); } } @@ -525,9 +528,10 @@ // Update window grid bounds and |snap_position_| in case the screen // orientation was changed. UpdateDragIndicatorsAndOverviewGrid(location_in_screen); - overview_session_->SetSplitViewDragIndicatorsWindowDraggingState( + overview_session_->UpdateSplitViewDragIndicatorsWindowDraggingStates( + GetRootWindowBeingDraggedIn(), /*is_dragging=*/true, SplitViewDragIndicators::WindowDraggingState::kNoDrag, - rounded_screen_point); + SplitViewController::NONE); item_->UpdateCannotSnapWarningVisibility(); } @@ -586,15 +590,19 @@ return; snap_position_ = GetSnapPosition(location_in_screen); - SplitViewDragIndicators::WindowDraggingState window_dragging_state = - SplitViewDragIndicators::ComputeWindowDraggingState( - /*is_dragging=*/true, - SplitViewDragIndicators::WindowDraggingState::kFromOverview, - snap_position_); - overview_session_->SetSplitViewDragIndicatorsWindowDraggingState( - window_dragging_state, gfx::ToRoundedPoint(location_in_screen)); - item_->overview_grid()->RearrangeDuringDrag(item_->GetWindow(), - window_dragging_state); + overview_session_->UpdateSplitViewDragIndicatorsWindowDraggingStates( + GetRootWindowBeingDraggedIn(), /*is_dragging=*/true, + SplitViewDragIndicators::WindowDraggingState::kFromOverview, + snap_position_); + overview_session_->RearrangeDuringDrag(item_->GetWindow()); +} + +const aura::Window* OverviewWindowDragController::GetRootWindowBeingDraggedIn() + const { + return is_touch_dragging_ + ? item_->root_window() + : Shell::GetRootWindowForDisplayId( + Shell::Get()->cursor_manager()->GetDisplay().id()); } gfx::Rect OverviewWindowDragController::GetWorkAreaOfDisplayBeingDraggedIn() @@ -606,16 +614,6 @@ : Shell::Get()->cursor_manager()->GetDisplay().work_area(); } -SplitViewController* -OverviewWindowDragController::GetSplitViewControllerForDisplayBeingDraggedIn() - const { - return SplitViewController::Get( - is_touch_dragging_ - ? item_->root_window() - : Shell::GetRootWindowForDisplayId( - Shell::Get()->cursor_manager()->GetDisplay().id())); -} - bool OverviewWindowDragController::ShouldUpdateDragIndicatorsOrSnap( const gfx::PointF& event_location) { auto snap_position = GetSnapPosition(event_location); @@ -686,7 +684,7 @@ // should show the preview window as soon as the window past the split divider // bar. SplitViewController* split_view_controller = - GetSplitViewControllerForDisplayBeingDraggedIn(); + SplitViewController::Get(GetRootWindowBeingDraggedIn()); if (split_view_controller->InSplitViewMode()) { const int position = gfx::ToRoundedInt(is_landscape ? location_in_screen.x() - area.x() @@ -717,9 +715,9 @@ aura::Window* window = item_->GetWindow(); // TODO(crbug.com/970013): Properly implement the multi-display behavior which // involves reparenting |window| to put it on the destination display. - GetSplitViewControllerForDisplayBeingDraggedIn()->SnapWindow( - window, snap_position, - /*use_divider_spawn_animation=*/true); + SplitViewController::Get(GetRootWindowBeingDraggedIn()) + ->SnapWindow(window, snap_position, + /*use_divider_spawn_animation=*/true); item_ = nullptr; wm::ActivateWindow(window); }
diff --git a/ash/wm/overview/overview_window_drag_controller.h b/ash/wm/overview/overview_window_drag_controller.h index edb99952..bcba1d8f 100644 --- a/ash/wm/overview/overview_window_drag_controller.h +++ b/ash/wm/overview/overview_window_drag_controller.h
@@ -103,8 +103,8 @@ void UpdateDragIndicatorsAndOverviewGrid( const gfx::PointF& location_in_screen); + const aura::Window* GetRootWindowBeingDraggedIn() const; gfx::Rect GetWorkAreaOfDisplayBeingDraggedIn() const; - SplitViewController* GetSplitViewControllerForDisplayBeingDraggedIn() const; // Dragged items should not attempt to update the indicators or snap if // the drag started in a snap region and has not been dragged pass the
diff --git a/ash/wm/overview/overview_window_drag_controller_unittest.cc b/ash/wm/overview/overview_window_drag_controller_unittest.cc index df234f3..b441b42d 100644 --- a/ash/wm/overview/overview_window_drag_controller_unittest.cc +++ b/ash/wm/overview/overview_window_drag_controller_unittest.cc
@@ -325,7 +325,7 @@ } SplitViewDragIndicators* drag_indicators() { - return overview_session()->split_view_drag_indicators(); + return overview_session()->grid_list()[0]->split_view_drag_indicators(); } OverviewGrid* overview_grid() {
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index c13892e..10c4d8b 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -328,15 +328,9 @@ DCHECK(window && CanSnapInSplitview(window)); DCHECK_NE(snap_position, NONE); DCHECK(!is_resizing_); + DCHECK(!IsDividerAnimating()); DCHECK_EQ(root_window_, window->GetRootWindow()); - // This check detects the case that you try to snap a window while watching - // the divider snap animation. It also detects the case that you click a - // window in overview while tap dragging the divider (possible by using the - // emulator or chrome://flags/#force-tablet-mode). - if (IsDividerAnimating()) - return; - UpdateSnappingWindowTransformedBounds(window); RemoveWindowFromOverviewIfApplicable(window);
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index 0901fa63..1a314f8 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -1121,36 +1121,6 @@ EXPECT_EQ(split_view_controller()->right_window(), window2.get()); } -// Verify that you cannot snap a window during the divider snap animation. -TEST_P(SplitViewControllerTest, SnapWindowDuringDividerSnapAnimation) { - const gfx::Rect bounds(0, 0, 400, 400); - std::unique_ptr<aura::Window> window1(CreateWindow(bounds)); - std::unique_ptr<aura::Window> window2(CreateWindow(bounds)); - std::unique_ptr<aura::Window> window3(CreateWindow(bounds)); - std::unique_ptr<aura::Window> window4(CreateWindow(bounds)); - - split_view_controller()->SnapWindow(window1.get(), SplitViewController::LEFT); - split_view_controller()->SnapWindow(window2.get(), - SplitViewController::RIGHT); - ASSERT_EQ(split_view_controller()->left_window(), window1.get()); - ASSERT_EQ(split_view_controller()->right_window(), window2.get()); - - // Drag the divider to trigger the snap animation. - const gfx::Point divider_center = - split_view_divider() - ->GetDividerBoundsInScreen(false /* is_dragging */) - .CenterPoint(); - GetEventGenerator()->set_current_screen_location(divider_center); - GetEventGenerator()->DragMouseBy(20, 0); - ASSERT_TRUE(IsDividerAnimating()); - - split_view_controller()->SnapWindow(window3.get(), SplitViewController::LEFT); - split_view_controller()->SnapWindow(window4.get(), - SplitViewController::RIGHT); - EXPECT_EQ(split_view_controller()->left_window(), window1.get()); - EXPECT_EQ(split_view_controller()->right_window(), window2.get()); -} - // Verify that you cannot start dragging the divider during its snap animation. TEST_P(SplitViewControllerTest, StartDraggingDividerDuringSnapAnimation) { const gfx::Rect bounds(0, 0, 400, 400);
diff --git a/ash/wm/splitview/split_view_drag_indicators.cc b/ash/wm/splitview/split_view_drag_indicators.cc index 11c5c78..368bc553 100644 --- a/ash/wm/splitview/split_view_drag_indicators.cc +++ b/ash/wm/splitview/split_view_drag_indicators.cc
@@ -42,15 +42,15 @@ constexpr float kOtherHighlightScreenPrimaryAxisRatio = 0.03f; // Creates the widget responsible for displaying the indicators. -std::unique_ptr<views::Widget> CreateWidget() { +std::unique_ptr<views::Widget> CreateWidget(aura::Window* root_window) { auto widget = std::make_unique<views::Widget>(); views::Widget::InitParams params; params.type = views::Widget::InitParams::TYPE_POPUP; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; params.accept_events = false; - params.parent = Shell::GetContainer(Shell::Get()->GetPrimaryRootWindow(), - kShellWindowId_OverlayContainer); + params.parent = + Shell::GetContainer(root_window, kShellWindowId_OverlayContainer); widget->set_focus_on_creation(false); widget->Init(std::move(params)); return widget; @@ -612,9 +612,10 @@ DISALLOW_COPY_AND_ASSIGN(SplitViewDragIndicatorsView); }; -SplitViewDragIndicators::SplitViewDragIndicators() { +SplitViewDragIndicators::SplitViewDragIndicators(aura::Window* root_window) { indicators_view_ = new SplitViewDragIndicatorsView(); - widget_ = CreateWidget(); + widget_ = CreateWidget(root_window); + widget_->SetBounds(GetWorkAreaBoundsNoOverlapWithShelf(root_window)); widget_->SetContentsView(indicators_view_); widget_->Show(); } @@ -635,22 +636,9 @@ } void SplitViewDragIndicators::SetWindowDraggingState( - WindowDraggingState window_dragging_state, - const gfx::Point& event_location) { + WindowDraggingState window_dragging_state) { if (window_dragging_state == current_window_dragging_state_) return; - - // Reparent the widget if needed. - aura::Window* target = ash::window_util::GetRootWindowAt(event_location); - aura::Window* root_window = target->GetRootWindow(); - if (widget_->GetNativeView()->GetRootWindow() != root_window) { - views::Widget::ReparentNativeView( - widget_->GetNativeView(), - Shell::GetContainer(root_window, kShellWindowId_OverlayContainer)); - widget_->SetContentsView(indicators_view_); - } - widget_->SetBounds(GetWorkAreaBoundsNoOverlapWithShelf(root_window)); - current_window_dragging_state_ = window_dragging_state; indicators_view_->OnWindowDraggingStateChanged(window_dragging_state); }
diff --git a/ash/wm/splitview/split_view_drag_indicators.h b/ash/wm/splitview/split_view_drag_indicators.h index 08999fe6..bc350d88 100644 --- a/ash/wm/splitview/split_view_drag_indicators.h +++ b/ash/wm/splitview/split_view_drag_indicators.h
@@ -85,12 +85,11 @@ WindowDraggingState non_snap_state, SplitViewController::SnapPosition snap_position); - SplitViewDragIndicators(); + SplitViewDragIndicators(aura::Window* root_window); ~SplitViewDragIndicators(); void SetDraggedWindow(aura::Window* dragged_window); - void SetWindowDraggingState(WindowDraggingState window_dragging_state, - const gfx::Point& event_location); + void SetWindowDraggingState(WindowDraggingState window_dragging_state); void OnDisplayBoundsChanged(); bool GetIndicatorTypeVisibilityForTesting(IndicatorType type) const; gfx::Rect GetLeftHighlightViewBoundsForTesting() const;
diff --git a/ash/wm/splitview/split_view_drag_indicators_unittest.cc b/ash/wm/splitview/split_view_drag_indicators_unittest.cc index 788930a..e0c90fb 100644 --- a/ash/wm/splitview/split_view_drag_indicators_unittest.cc +++ b/ash/wm/splitview/split_view_drag_indicators_unittest.cc
@@ -66,7 +66,7 @@ overview_session_ = Shell::Get()->overview_controller()->overview_session(); ASSERT_TRUE(overview_session_); split_view_drag_indicators_ = - overview_session_->split_view_drag_indicators(); + overview_session_->grid_list()[0]->split_view_drag_indicators(); } SplitViewController* split_view_controller() { @@ -368,8 +368,9 @@ // Verify when the window dragging state changes, the expected indicators will // become visible or invisible. TEST_F(SplitViewDragIndicatorsTest, SplitViewDragIndicatorsVisibility) { - auto indicator = std::make_unique<SplitViewDragIndicators>(); std::unique_ptr<aura::Window> dragged_window(CreateTestWindow()); + auto indicator = std::make_unique<SplitViewDragIndicators>( + dragged_window->GetRootWindow()); indicator->SetDraggedWindow(dragged_window.get()); auto to_int = [](IndicatorType type) { return static_cast<int>(type); }; @@ -388,12 +389,10 @@ } }; - // Check each state has the correct views displayed. Pass and empty point as - // the location since there is no need to reparent the widget. Verify that - // nothing is shown in state - // |SplitViewDragIndicators::WindowDraggingState::kNoDrag|. + // Check each state has the correct views displayed. Verify that nothing is + // shown in state |SplitViewDragIndicators::WindowDraggingState::kNoDrag|. indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kNoDrag, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kNoDrag); check_helper(indicator.get(), 0); const int all = to_int(IndicatorType::kLeftHighlight) | @@ -403,35 +402,34 @@ // Verify that everything is visible in state // |SplitViewDragIndicators::WindowDraggingState::kFromOverview|. indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kFromOverview, - gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kFromOverview); check_helper(indicator.get(), all); // Verify that only one highlight shows up for the snap states. indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kToSnapLeft, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kToSnapLeft); check_helper(indicator.get(), to_int(IndicatorType::kLeftHighlight)); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kToSnapRight, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kToSnapRight); check_helper(indicator.get(), to_int(IndicatorType::kRightHighlight)); // Verify that only snap previews are shown for window dragging from shelf. indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kNoDrag, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kNoDrag); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kFromShelf, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kFromShelf); check_helper(indicator.get(), 0); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kToSnapLeft, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kToSnapLeft); check_helper(indicator.get(), to_int(IndicatorType::kLeftHighlight)); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kFromShelf, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kFromShelf); check_helper(indicator.get(), 0); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kToSnapRight, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kToSnapRight); check_helper(indicator.get(), to_int(IndicatorType::kRightHighlight)); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kFromShelf, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kFromShelf); check_helper(indicator.get(), 0); ScreenOrientationControllerTestApi orientation_api( @@ -442,14 +440,14 @@ ASSERT_EQ(OrientationLockType::kLandscapePrimary, orientation_api.GetCurrentOrientation()); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kNoDrag, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kNoDrag); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kFromTop, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kFromTop); check_helper(indicator.get(), all); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kToSnapRight, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kToSnapRight); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kFromTop, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kFromTop); check_helper(indicator.get(), all); const int right_with_text = to_int(IndicatorType::kRightHighlight) | @@ -462,71 +460,15 @@ ASSERT_EQ(OrientationLockType::kPortraitPrimary, orientation_api.GetCurrentOrientation()); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kNoDrag, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kNoDrag); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kFromTop, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kFromTop); check_helper(indicator.get(), right_with_text); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kToSnapRight, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kToSnapRight); indicator->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kFromTop, gfx::Point()); + SplitViewDragIndicators::WindowDraggingState::kFromTop); check_helper(indicator.get(), right_with_text); } -// Verify that the split view drag indicators widget reparents when starting a -// drag on a different display. -TEST_F(SplitViewDragIndicatorsTest, SplitViewDragIndicatorsWidgetReparenting) { - // Add two displays and one window on each display. - UpdateDisplay("600x600,600x600"); - // DisplayConfigurationObserver enables mirror mode when tablet mode is - // enabled. Disable mirror mode to test multiple displays. - display_manager()->SetMirrorMode(display::MirrorMode::kOff, base::nullopt); - base::RunLoop().RunUntilIdle(); - - auto root_windows = Shell::Get()->GetAllRootWindows(); - ASSERT_EQ(2u, root_windows.size()); - - const gfx::Rect primary_screen_bounds(0, 0, 600, 600); - const gfx::Rect secondary_screen_bounds(600, 0, 600, 600); - auto primary_screen_window(CreateTestWindow(primary_screen_bounds)); - auto secondary_screen_window(CreateTestWindow(secondary_screen_bounds)); - - ToggleOverview(); - - // Select an item on the primary display and verify the drag indicators - // widget's parent is the primary root window. - OverviewItem* item = GetOverviewItemForWindow(primary_screen_window.get()); - gfx::PointF start_location(item->target_bounds().CenterPoint()); - overview_session_->InitiateDrag(item, start_location, - /*is_touch_dragging=*/true); - overview_session_->Drag(item, gfx::PointF(100.f, start_location.y())); - EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, - window_dragging_state()); - EXPECT_EQ(root_windows[0], overview_session_->split_view_drag_indicators() - ->widget_->GetNativeView() - ->GetRootWindow()); - // Drag the item in a way that neither opens the window nor activates - // splitview mode. - overview_session_->Drag(item, - gfx::PointF(primary_screen_bounds.CenterPoint())); - overview_session_->CompleteDrag( - item, gfx::PointF(primary_screen_bounds.CenterPoint())); - ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); - ASSERT_FALSE(split_view_controller()->InSplitViewMode()); - - // Select an item on the secondary display and verify the indicators widget - // has reparented to the secondary root window. - item = GetOverviewItemForWindow(secondary_screen_window.get(), 1); - start_location = item->target_bounds().CenterPoint(); - overview_session_->InitiateDrag(item, start_location, - /*is_touch_dragging=*/true); - overview_session_->Drag(item, gfx::PointF(800.f, start_location.y())); - EXPECT_EQ(SplitViewDragIndicators::WindowDraggingState::kFromOverview, - window_dragging_state()); - EXPECT_EQ(root_windows[1], overview_session_->split_view_drag_indicators() - ->widget_->GetNativeView() - ->GetRootWindow()); - overview_session_->CompleteDrag(item, start_location); -} - } // namespace ash
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc index 0479a1a..5dcd058 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc
@@ -98,8 +98,8 @@ TabletModeWindowDragDelegate::TabletModeWindowDragDelegate() : split_view_controller_( SplitViewController::Get(Shell::GetPrimaryRootWindow())), - split_view_drag_indicators_(std::make_unique<SplitViewDragIndicators>()) { -} + split_view_drag_indicators_(std::make_unique<SplitViewDragIndicators>( + Shell::GetPrimaryRootWindow())) {} TabletModeWindowDragDelegate::~TabletModeWindowDragDelegate() { if (dragged_window_) { @@ -250,8 +250,7 @@ is_window_considered_moved_, SplitViewDragIndicators::WindowDraggingState::kFromTop, GetSnapPosition(location_in_screen)); - split_view_drag_indicators_->SetWindowDraggingState(window_dragging_state, - location_in_screen); + split_view_drag_indicators_->SetWindowDraggingState(window_dragging_state); if (GetOverviewSession()) { GetOverviewSession()->OnWindowDragContinued(dragged_window_, @@ -284,8 +283,7 @@ split_view_controller_->OnWindowDragEnded(dragged_window_, snap_position, location_in_screen); split_view_drag_indicators_->SetWindowDraggingState( - SplitViewDragIndicators::WindowDraggingState::kNoDrag, - location_in_screen); + SplitViewDragIndicators::WindowDraggingState::kNoDrag); // Reset the dragged window's window shadow elevation. ::wm::SetShadowElevation(dragged_window_, original_shadow_elevation_);
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.cc b/ash/wm/tablet_mode/tablet_mode_window_manager.cc index 0a7d2e0..fca1ac11 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
@@ -8,6 +8,7 @@ #include "ash/display/screen_orientation_controller.h" #include "ash/public/cpp/app_types.h" +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_properties.h" @@ -16,6 +17,7 @@ #include "ash/screen_util.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" +#include "ash/shell_delegate.h" #include "ash/wm/desks/desks_util.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/overview_controller.h" @@ -233,6 +235,33 @@ return windows.empty() ? nullptr : windows[0]; } +// static +bool TabletModeWindowManager::ShouldMinimizeTopWindowOnBack() { + if (!features::IsSwipingFromLeftEdgeToGoBackEnabled()) + return false; + + Shell* shell = Shell::Get(); + if (!shell->tablet_mode_controller()->InTabletMode()) + return false; + + aura::Window* window = GetTopWindow(); + if (!window) + return false; + + const int app_type = window->GetProperty(aura::client::kAppType); + if (app_type != static_cast<int>(AppType::BROWSER) && + app_type != static_cast<int>(AppType::CHROME_APP)) { + return false; + } + + WindowState* window_state = WindowState::Get(window); + if (!window_state || !window_state->CanMinimize()) + return false; + + // Minimize the window if it is at the bottom page. + return !shell->shell_delegate()->CanGoBack(window); +} + void TabletModeWindowManager::Init() { { ScopedObserveWindowAnimation scoped_observe(GetTopWindow(), this,
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.h b/ash/wm/tablet_mode/tablet_mode_window_manager.h index bf934f4..c263a6e 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager.h +++ b/ash/wm/tablet_mode/tablet_mode_window_manager.h
@@ -49,8 +49,13 @@ TabletModeWindowManager(); ~TabletModeWindowManager() override; + // Returns the top window on MRU window list, or null if the list + // is empty. static aura::Window* GetTopWindow(); + // Returns whether the top window should be minimized on back action. + static bool ShouldMinimizeTopWindowOnBack(); + void Init(); // Stops tracking windows and returns them to their clamshell mode state. Work
diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc index efcabe2..f00ca20 100644 --- a/ash/wm/toplevel_window_event_handler.cc +++ b/ash/wm/toplevel_window_event_handler.cc
@@ -11,11 +11,11 @@ #include "ash/public/cpp/ash_features.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" -#include "ash/shell_delegate.h" #include "ash/wm/back_gesture_affordance.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/resize_shadow_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "ash/wm/tablet_mode/tablet_mode_window_manager.h" #include "ash/wm/window_resizer.h" #include "ash/wm/window_state.h" #include "ash/wm/window_state_observer.h" @@ -103,7 +103,7 @@ } // True if we can start swiping from left edge to go to previous page. -bool CanStartGoingBack(aura::Window* target) { +bool CanStartGoingBack() { if (!features::IsSwipingFromLeftEdgeToGoBackEnabled()) return false; @@ -126,18 +126,6 @@ return false; } - views::Widget* widget = views::Widget::GetTopLevelWidgetForNativeView(target); - if (!widget) - return false; - - aura::Window* native_window = widget->GetNativeWindow(); - const int app_type = native_window->GetProperty(aura::client::kAppType); - // No need to show the back gesture affordance and go back if the active - // browser web contents can not go back. - if (app_type == static_cast<int>(AppType::BROWSER) || - app_type == static_cast<int>(AppType::CHROME_APP)) { - return Shell::Get()->shell_delegate()->CanGoBack(widget->GetNativeWindow()); - } return true; } @@ -896,7 +884,7 @@ bool ToplevelWindowEventHandler::HandleGoingBackFromLeftEdge( ui::GestureEvent* event) { aura::Window* target = static_cast<aura::Window*>(event->target()); - if (!CanStartGoingBack(target)) + if (!CanStartGoingBack()) return false; gfx::Point screen_location = event->location(); @@ -924,16 +912,20 @@ if (back_gesture_affordance_->IsActivated() || (event->type() == ui::ET_SCROLL_FLING_START && event->details().velocity_x() >= kFlingVelocityForGoingBack)) { - aura::Window* root_window = - window_util::GetRootWindowAt(screen_location); - ui::KeyEvent press_key_event(ui::ET_KEY_PRESSED, ui::VKEY_BROWSER_BACK, - ui::EF_NONE); - ignore_result( - root_window->GetHost()->SendEventToSink(&press_key_event)); - ui::KeyEvent release_key_event(ui::ET_KEY_RELEASED, + if (TabletModeWindowManager::ShouldMinimizeTopWindowOnBack()) { + WindowState::Get(TabletModeWindowManager::GetTopWindow())->Minimize(); + } else { + aura::Window* root_window = + window_util::GetRootWindowAt(screen_location); + ui::KeyEvent press_key_event(ui::ET_KEY_PRESSED, ui::VKEY_BROWSER_BACK, ui::EF_NONE); - ignore_result( - root_window->GetHost()->SendEventToSink(&release_key_event)); + ignore_result( + root_window->GetHost()->SendEventToSink(&press_key_event)); + ui::KeyEvent release_key_event(ui::ET_KEY_RELEASED, + ui::VKEY_BROWSER_BACK, ui::EF_NONE); + ignore_result( + root_window->GetHost()->SendEventToSink(&release_key_event)); + } back_gesture_affordance_->Complete(); } else { back_gesture_affordance_->Abort();
diff --git a/base/mac/scoped_objc_class_swizzler.h b/base/mac/scoped_objc_class_swizzler.h index e18e4ab..545ac55 100644 --- a/base/mac/scoped_objc_class_swizzler.h +++ b/base/mac/scoped_objc_class_swizzler.h
@@ -31,7 +31,17 @@ // Return a callable function pointer for the replaced method. To call this // from the replacing function, the first two arguments should be |self| and // |_cmd|. These are followed by the (variadic) method arguments. - IMP GetOriginalImplementation(); + IMP GetOriginalImplementation() const; + + // Invoke the original function directly, optionally with some arguments. + // Prefer this to hanging onto pointers to the original implementation + // function or to casting the result of GetOriginalImplementation() yourself. + template <typename Ret, typename... Args> + Ret InvokeOriginal(id receiver, SEL selector, Args... args) const { + auto func = reinterpret_cast<Ret (*)(id, SEL, Args...)>( + GetOriginalImplementation()); + return func(receiver, selector, args...); + } private: // Delegated constructor.
diff --git a/base/mac/scoped_objc_class_swizzler.mm b/base/mac/scoped_objc_class_swizzler.mm index 20e5c569..0065ed7 100644 --- a/base/mac/scoped_objc_class_swizzler.mm +++ b/base/mac/scoped_objc_class_swizzler.mm
@@ -30,7 +30,7 @@ method_exchangeImplementations(old_selector_impl_, new_selector_impl_); } -IMP ScopedObjCClassSwizzler::GetOriginalImplementation() { +IMP ScopedObjCClassSwizzler::GetOriginalImplementation() const { // Note that while the swizzle is in effect the "new" method is actually // pointing to the original implementation, since they have been swapped. return method_getImplementation(new_selector_impl_);
diff --git a/base/mac/scoped_objc_class_swizzler_unittest.mm b/base/mac/scoped_objc_class_swizzler_unittest.mm index 79820a3f..3aa5e9e 100644 --- a/base/mac/scoped_objc_class_swizzler_unittest.mm +++ b/base/mac/scoped_objc_class_swizzler_unittest.mm
@@ -92,9 +92,7 @@ EXPECT_EQ(6, [object_one method]); EXPECT_EQ(7, [object_two method]); - IMP original = swizzler.GetOriginalImplementation(); - id expected_result = reinterpret_cast<id>(3); - EXPECT_EQ(expected_result, original(object_one, @selector(method))); + EXPECT_EQ(3, swizzler.InvokeOriginal<int>(object_one, @selector(method))); } EXPECT_EQ(3, [object_one method]); @@ -113,10 +111,8 @@ EXPECT_EQ(20, [ObjCClassSwizzlerTestOne function]); EXPECT_EQ(10, [ObjCClassSwizzlerTestTwo function]); - IMP original = swizzler.GetOriginalImplementation(); - id expected_result = reinterpret_cast<id>(10); - EXPECT_EQ(expected_result, - original([ObjCClassSwizzlerTestOne class], @selector(function))); + EXPECT_EQ(10, swizzler.InvokeOriginal<int>([ObjCClassSwizzlerTestOne class], + @selector(function))); } EXPECT_EQ(10, [ObjCClassSwizzlerTestOne function]); @@ -135,9 +131,7 @@ @selector(alternate)); EXPECT_EQ(9, [object_one method]); - IMP original = swizzler.GetOriginalImplementation(); - id expected_result = reinterpret_cast<id>(3); - EXPECT_EQ(expected_result, original(object_one, @selector(method))); + EXPECT_EQ(3, swizzler.InvokeOriginal<int>(object_one, @selector(method))); } EXPECT_EQ(3, [object_one method]); @@ -155,9 +149,7 @@ @selector(childAlternate)); EXPECT_EQ(15, [child method]); - IMP original = swizzler.GetOriginalImplementation(); - id expected_result = reinterpret_cast<id>(3); - EXPECT_EQ(expected_result, original(child, @selector(method))); + EXPECT_EQ(3, swizzler.InvokeOriginal<int>(child, @selector(method))); } EXPECT_EQ(3, [child method]);
diff --git a/build/config/fuchsia/tests.cmx b/build/config/fuchsia/tests.cmx index 43ab020..3b616dd7 100644 --- a/build/config/fuchsia/tests.cmx +++ b/build/config/fuchsia/tests.cmx
@@ -11,6 +11,7 @@ "zero" ], "services": [ + "fuchsia.accessibility.semantics.SemanticsManager", "fuchsia.device.NameProvider", "fuchsia.deprecatedtimezone.Timezone", "fuchsia.fonts.Provider",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index af896cd..b7e41ea 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1221,6 +1221,11 @@ "java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerProperties.java", "java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerViewBinder.java", "java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerView.java", + "java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java", + "java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarMediator.java", + "java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarProperties.java", + "java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarViewBinder.java", + "java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarView.java", "java/src/org/chromium/chrome/browser/payments/JourneyLogger.java", "java/src/org/chromium/chrome/browser/payments/PackageManagerDelegate.java", "java/src/org/chromium/chrome/browser/payments/PaymentApp.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 69ca95b..3973aa1 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -91,7 +91,9 @@ "javatests/src/org/chromium/chrome/browser/device_dialog/ItemChooserDialogTest.java", "javatests/src/org/chromium/chrome/browser/device_dialog/UsbChooserDialogTest.java", "javatests/src/org/chromium/chrome/browser/directactions/CloseTabDirectActionHandlerTest.java", - "javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityTest.java", + "javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityCustomTabTest.java", + "javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityTabbedTest.java", + "javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityWebappTest.java", "javatests/src/org/chromium/chrome/browser/directactions/DirectActionTestRule.java", "javatests/src/org/chromium/chrome/browser/directactions/DirectActionTestUtils.java", "javatests/src/org/chromium/chrome/browser/directactions/DirectActionsInActivityTest.java",
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java index dfbf1c46..6150132d 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -162,7 +162,7 @@ @Override public void willCloseTab(Tab tab, boolean animate) { if (normalTabModel.getCount() <= 1 - || mPropertyModel.get(IS_SHOWING_OVERVIEW)) { + && mPropertyModel.get(IS_SHOWING_OVERVIEW)) { setTabCarouselVisibility(false); } }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java index 6a35731c..81b2646 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -41,6 +41,7 @@ import org.chromium.base.GarbageCollectionTestUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MinAndroidSdkLevel; @@ -73,6 +74,7 @@ import java.util.LinkedList; import java.util.List; +// clang-format off /** Tests for the {@link StartSurfaceLayout} */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, @@ -80,7 +82,10 @@ "force-fieldtrials=Study/Group"}) @Restriction( {UiRestriction.RESTRICTION_TYPE_PHONE, Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE}) +@DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M, + message = "https://crbug.com/1023833") public class StartSurfaceLayoutTest { + // clang-format on private static final String BASE_PARAMS = "force-fieldtrial-params=" + "Study.Group:soft-cleanup-delay/0/cleanup-delay/0/skip-slow-zooming/false" + "/zooming-min-sdk-version/19/zooming-min-memory-mb/512"; @@ -132,7 +137,9 @@ .getCurrentTabModelFilter()::isTabModelRestored)); assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting()); - // Only skip thumbnail releasing assertion when "warm" (large soft-cleanup-delay). + // Only skip thumbnail releasing assertion when "warm" (large soft-cleanup-delay) or in + // RenderTest. + // TODO(wychen): figure out why thumbnails are not released in RenderTest. mSkipAssertThumbnailsAreReleased = false; } @@ -146,14 +153,16 @@ @Feature({"RenderTest"}) @CommandLineFlags.Add({BASE_PARAMS}) public void testRenderGrid_3WebTabs() throws InterruptedException, IOException { + mSkipAssertThumbnailsAreReleased = true; + prepareTabs(3, 0, mUrl); TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); TabUiTestHelper.clickFirstCardFromTabSwitcher(mActivityTestRule.getActivity()); enterGTS(); - mRenderTestRule.render( - mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "3_web_tabs"); - leaveGTS(); + mRenderTestRule.render(mActivityTestRule.getActivity().findViewById( + org.chromium.chrome.tab_ui.R.id.tab_list_view), + "3_web_tabs"); } @Test @@ -161,14 +170,16 @@ @Feature({"RenderTest"}) @CommandLineFlags.Add({BASE_PARAMS}) public void testRenderGrid_10WebTabs() throws InterruptedException, IOException { + mSkipAssertThumbnailsAreReleased = true; + prepareTabs(10, 0, mUrl); TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); TabUiTestHelper.clickFirstCardFromTabSwitcher(mActivityTestRule.getActivity()); enterGTS(); - mRenderTestRule.render( - mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "10_web_tabs"); - leaveGTS(); + mRenderTestRule.render(mActivityTestRule.getActivity().findViewById( + org.chromium.chrome.tab_ui.R.id.tab_list_view), + "10_web_tabs"); } @Test @@ -176,6 +187,8 @@ @Feature({"RenderTest"}) @CommandLineFlags.Add({BASE_PARAMS}) public void testRenderGrid_10WebTabs_InitialScroll() throws InterruptedException, IOException { + mSkipAssertThumbnailsAreReleased = true; + prepareTabs(10, 0, mUrl); TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); TabUiTestHelper.clickNthCardFromTabSwitcher(mActivityTestRule.getActivity(), @@ -184,9 +197,9 @@ enterGTS(); // Make sure the grid tab switcher is scrolled down to show the selected tab. - mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), + mRenderTestRule.render(mActivityTestRule.getActivity().findViewById( + org.chromium.chrome.tab_ui.R.id.tab_list_view), "10_web_tabs-select_last"); - leaveGTS(); } @Test @@ -194,6 +207,8 @@ @Feature({"RenderTest"}) @CommandLineFlags.Add({BASE_PARAMS}) public void testRenderGrid_Incognito() throws InterruptedException, IOException { + mSkipAssertThumbnailsAreReleased = true; + // Prepare some incognito tabs and enter tab switcher. prepareTabs(1, 3, mUrl); assertTrue(mActivityTestRule.getActivity().getCurrentTabModel().isIncognito()); @@ -201,28 +216,9 @@ TabUiTestHelper.clickFirstCardFromTabSwitcher(mActivityTestRule.getActivity()); enterGTS(); - mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), + mRenderTestRule.render(mActivityTestRule.getActivity().findViewById( + org.chromium.chrome.tab_ui.R.id.tab_list_view), "3_incognito_web_tabs"); - leaveGTS(); - } - - @Test - @MediumTest - @Feature({"RenderTest"}) - @CommandLineFlags.Add({BASE_PARAMS}) - public void testRenderGrid_3IncognitoNTPs() throws InterruptedException, IOException { - // Prepare some incognito native tabs and enter tab switcher. - // NTP in incognito mode is chosen for its consistency in look, and we don't have to mock - // away the MV tiles, login promo, feed, etc. - prepareTabs(1, 3, null); - assertTrue(mActivityTestRule.getActivity().getCurrentTabModel().isIncognito()); - TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); - TabUiTestHelper.clickFirstCardFromTabSwitcher(mActivityTestRule.getActivity()); - - enterGTS(); - mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), - "3_incognito_ntps"); - leaveGTS(); } @Test @@ -468,7 +464,7 @@ waitForCaptureRateControl(); } int count = getCaptureCount(); - onView(withId(R.id.tab_list_view)) + onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) .perform(RecyclerViewActions.actionOnItemAtPosition(targetIndex, click())); CriteriaHelper.pollUiThread(() -> { boolean doneHiding = @@ -591,16 +587,16 @@ public void testIncognitoEnterGts() throws InterruptedException { prepareTabs(1, 1, null); enterGTS(); - onView(withId(R.id.tab_list_view)) + onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(1)); - onView(withId(R.id.tab_list_view)) + onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())); CriteriaHelper.pollInstrumentationThread( () -> !mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); enterGTS(); - onView(withId(R.id.tab_list_view)) + onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(1)); } @@ -613,16 +609,16 @@ // Prepare two incognito tabs and enter tab switcher. prepareTabs(1, 2, mUrl); enterGTS(); - onView(withId(R.id.tab_list_view)) + onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(2)); for (int i = 0; i < mRepeat; i++) { switchTabModel(false); - onView(withId(R.id.tab_list_view)) + onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(1)); switchTabModel(true); - onView(withId(R.id.tab_list_view)) + onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) .check(TabCountAssertion.havingTabCount(2)); } leaveGTS();
diff --git a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java index e2a6ebe5..12ee98d 100644 --- a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java +++ b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java
@@ -194,12 +194,16 @@ StartSurfaceMediator mediator = createStartSurfaceMediator(SurfaceMode.SINGLE_PANE); verify(mNormalTabModel).addObserver(mTabModelObserverCaptor.capture()); - doReturn(1).when(mNormalTabModel).getCount(); + doReturn(2).when(mNormalTabModel).getCount(); mediator.showOverview(false); assertThat(mPropertyModel.get(IS_SHOWING_OVERVIEW), equalTo(true)); assertThat(mPropertyModel.get(IS_TAB_CAROUSEL_VISIBLE), equalTo(true)); - doReturn(0).when(mNormalTabModel).getCount(); + mTabModelObserverCaptor.getValue().willCloseTab(mock(Tab.class), false); + assertThat(mPropertyModel.get(IS_SHOWING_OVERVIEW), equalTo(true)); + assertThat(mPropertyModel.get(IS_TAB_CAROUSEL_VISIBLE), equalTo(true)); + + doReturn(1).when(mNormalTabModel).getCount(); mTabModelObserverCaptor.getValue().willCloseTab(mock(Tab.class), false); assertThat(mPropertyModel.get(IS_SHOWING_OVERVIEW), equalTo(true)); assertThat(mPropertyModel.get(IS_TAB_CAROUSEL_VISIBLE), equalTo(false));
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java index 3f7a49e..163ce8e 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java
@@ -326,9 +326,9 @@ private void setupDialogSelectionEditor() { assert mTabSelectionEditorController != null; - TabSelectionEditorActionProvider actionProvider = new TabSelectionEditorActionProvider( - mTabModelSelector, mTabSelectionEditorController, - TabSelectionEditorActionProvider.TabSelectionEditorAction.UNGROUP); + TabSelectionEditorActionProvider actionProvider = + new TabSelectionEditorActionProvider(mTabSelectionEditorController, + TabSelectionEditorActionProvider.TabSelectionEditorAction.UNGROUP); String actionButtonText = mContext.getString(R.string.tab_grid_dialog_selection_mode_remove);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProvider.java index ef66c6b..c53a8c1 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProvider.java
@@ -21,42 +21,65 @@ * Provider of actions for a list of selected tabs in {@link TabSelectionEditorMediator}. */ class TabSelectionEditorActionProvider { - @IntDef({TabSelectionEditorAction.UNGROUP, TabSelectionEditorAction.GROUP}) + @IntDef({TabSelectionEditorAction.UNDEFINED_ACTION, TabSelectionEditorAction.GROUP, + TabSelectionEditorAction.UNGROUP, TabSelectionEditorAction.CLOSE}) @Retention(RetentionPolicy.SOURCE) @interface TabSelectionEditorAction { - int GROUP = 0; - int UNGROUP = 1; - int NUM_ENTRIES = 2; + int UNDEFINED_ACTION = 0; + int GROUP = 1; + int UNGROUP = 2; + int CLOSE = 3; + int NUM_ENTRIES = 4; } - private final TabModelSelector mTabModelSelector; + private final TabSelectionEditorCoordinator .TabSelectionEditorController mTabSelectionEditorController; - private final int mAction; + private final @TabSelectionEditorAction int mAction; - TabSelectionEditorActionProvider(TabModelSelector tabModelSelector, + /** + * Construct {@link TabSelectionEditorActionProvider} with customized process selected tabs + * action. + * @see TabSelectionEditorActionProvider#processSelectedTabs(List, TabModelSelector). + */ + TabSelectionEditorActionProvider() { + mTabSelectionEditorController = null; + mAction = TabSelectionEditorAction.UNDEFINED_ACTION; + } + + /** + * Construct {@link TabSelectionEditorActionProvider} with defined + * {@link TabSelectionEditorAction}. + * + * @param tabSelectionEditorController Controller that associated with the TabSelectionEditor. + * @param action {@link TabSelectionEditorAction} to provide. + */ + TabSelectionEditorActionProvider( TabSelectionEditorCoordinator.TabSelectionEditorController tabSelectionEditorController, @TabSelectionEditorAction int action) { - mTabModelSelector = tabModelSelector; mTabSelectionEditorController = tabSelectionEditorController; mAction = action; } /** * Defines how to process {@code selectedTabs} based on the {@link TabSelectionEditorAction} - * specified in the constructor. + * specified in the constructor. If {@link TabSelectionEditorAction} is not specified, the + * caller must override this method. * * @param selectedTabs The list of selected tabs to process. + * @param tabModelSelector {@link TabModelSelector} to use. */ - void processSelectedTabs(List<Tab> selectedTabs) { - assert mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter() - instanceof TabGroupModelFilter; + void processSelectedTabs(List<Tab> selectedTabs, TabModelSelector tabModelSelector) { + assert !(mAction == TabSelectionEditorAction.GROUP) + && !(mAction == TabSelectionEditorAction.UNGROUP) + || tabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter() + instanceof TabGroupModelFilter; switch (mAction) { case TabSelectionEditorAction.GROUP: - Tab destinationTab = getDestinationTab(selectedTabs); + Tab destinationTab = getDestinationTab(selectedTabs, tabModelSelector); TabGroupModelFilter tabGroupModelFilter = - (TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider() + (TabGroupModelFilter) tabModelSelector.getTabModelFilterProvider() .getCurrentTabModelFilter(); tabGroupModelFilter.mergeListOfTabsToGroup( selectedTabs, destinationTab, false, true); @@ -67,28 +90,35 @@ break; case TabSelectionEditorAction.UNGROUP: TabGroupModelFilter filter = - (TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider() + (TabGroupModelFilter) tabModelSelector.getTabModelFilterProvider() .getCurrentTabModelFilter(); for (Tab tab : selectedTabs) { filter.moveTabOutOfGroup(tab.getId()); } mTabSelectionEditorController.hide(); break; + case TabSelectionEditorAction.CLOSE: + tabModelSelector.getCurrentModel().closeMultipleTabs(selectedTabs, true); + mTabSelectionEditorController.hide(); + break; + case TabSelectionEditorAction.UNDEFINED_ACTION: default: - assert false; + assert false : "TabSelectionEditorActionProvider must override" + + "processSelectedTab() if mAction is not pre-defined with" + + "TabSelectionEditorAction."; } } /** * @return The {@link Tab} that has the greatest index in TabModel among the given list of tabs. */ - private Tab getDestinationTab(List<Tab> tabs) { + private Tab getDestinationTab(List<Tab> tabs, TabModelSelector tabModelSelector) { int greatestIndex = TabModel.INVALID_TAB_INDEX; for (int i = 0; i < tabs.size(); i++) { int index = TabModelUtils.getTabIndexById( - mTabModelSelector.getCurrentModel(), tabs.get(i).getId()); + tabModelSelector.getCurrentModel(), tabs.get(i).getId()); greatestIndex = Math.max(index, greatestIndex); } - return mTabModelSelector.getCurrentModel().getTabAt(greatestIndex); + return tabModelSelector.getCurrentModel().getTabAt(greatestIndex); } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java index 3abfada..d523706d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java
@@ -94,7 +94,7 @@ } if (mActionProvider == null) return; - mActionProvider.processSelectedTabs(selectedTabs); + mActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector); } }; @@ -163,8 +163,8 @@ mTabModelSelector.addObserver(mTabModelSelectorObserver); // Default action for action button is to group selected tabs. - mActionProvider = new TabSelectionEditorActionProvider(mTabModelSelector, this, - TabSelectionEditorActionProvider.TabSelectionEditorAction.GROUP); + mActionProvider = new TabSelectionEditorActionProvider( + this, TabSelectionEditorActionProvider.TabSelectionEditorAction.GROUP); if (mPositionProvider != null) { mModel.set(TabSelectionEditorProperties.SELECTION_EDITOR_GLOBAL_LAYOUT_LISTENER,
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java index 5a1a891f..9743294 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
@@ -265,7 +265,7 @@ Tab previousTab = previousTabModel.getTabAt(previousTabIndex); ChromeTabUtils.newTabFromMenu(InstrumentationRegistry.getInstrumentation(), - rule.getActivity(), isIncognito, true); + rule.getActivity(), isIncognito, url == null); if (url != null) rule.loadUrl(url);
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProviderUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProviderUnitTest.java index 149c73b..68c0f96 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProviderUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProviderUnitTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.tasks.tab_management; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -28,6 +29,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; import org.chromium.chrome.test.util.browser.Features; @@ -36,6 +38,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; /** * Tests for {@link TabSelectionEditorActionProvider}. @@ -97,11 +100,10 @@ @Test public void testGroupAction() { TabSelectionEditorActionProvider tabSelectionEditorActionProvider = - new TabSelectionEditorActionProvider(mTabModelSelector, - mTabSelectionEditorController, + new TabSelectionEditorActionProvider(mTabSelectionEditorController, TabSelectionEditorActionProvider.TabSelectionEditorAction.GROUP); List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2)); - tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs); + tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector); verify(mTabGroupModelFilter) .mergeListOfTabsToGroup(eq(selectedTabs), eq(mTab2), eq(false), eq(true)); @@ -111,17 +113,46 @@ @Test public void testUngroupAction() { TabSelectionEditorActionProvider tabSelectionEditorActionProvider = - new TabSelectionEditorActionProvider(mTabModelSelector, - mTabSelectionEditorController, + new TabSelectionEditorActionProvider(mTabSelectionEditorController, TabSelectionEditorActionProvider.TabSelectionEditorAction.UNGROUP); List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2)); - tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs); + tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector); verify(mTabGroupModelFilter).moveTabOutOfGroup(TAB1_ID); verify(mTabGroupModelFilter).moveTabOutOfGroup(TAB2_ID); verify(mTabSelectionEditorController).hide(); } + @Test + public void testCloseAction() { + TabSelectionEditorActionProvider tabSelectionEditorActionProvider = + new TabSelectionEditorActionProvider(mTabSelectionEditorController, + TabSelectionEditorActionProvider.TabSelectionEditorAction.CLOSE); + List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2)); + tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector); + + verify(mTabModel).closeMultipleTabs(selectedTabs, true); + verify(mTabSelectionEditorController).hide(); + } + + @Test + public void testCustomizeAction() { + AtomicBoolean isProcessed = new AtomicBoolean(); + + TabSelectionEditorActionProvider tabSelectionEditorActionProvider = + new TabSelectionEditorActionProvider() { + @Override + void processSelectedTabs( + List<Tab> selectedTabs, TabModelSelector tabModelSelector) { + isProcessed.set(true); + } + }; + List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2)); + tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector); + + assertTrue(isProcessed.get()); + } + private Tab prepareTab(int id, String title) { Tab tab = mock(Tab.class); when(tab.getView()).thenReturn(mock(View.class));
diff --git a/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml b/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml index 29eb4724..897848eb 100644 --- a/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml +++ b/chrome/android/java/res/layout/ephemeral_tab_toolbar.xml
@@ -23,16 +23,16 @@ <RelativeLayout android:layout_width="match_parent" android:layout_height="62dp" + android:paddingStart="8dp" android:orientation="horizontal"> <org.chromium.ui.widget.ChromeImageView android:id="@+id/favicon" android:layout_width="48dp" android:layout_height="48dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" android:layout_marginTop="12dp" android:padding="12dp" + android:layout_alignParentStart="true" android:scaleType="fitCenter" tools:ignore="ContentDescription" /> @@ -62,6 +62,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" + android:layout_marginStart="8dp" android:layout_toStartOf="@id/open_in_new_tab" android:layout_toEndOf="@id/favicon" android:textAlignment="viewStart" @@ -73,6 +74,7 @@ android:id="@+id/security_icon" android:layout_width="16dp" android:layout_height="16dp" + android:layout_marginStart="8dp" android:layout_below="@id/ephemeral_tab_text" android:layout_toEndOf="@id/favicon" android:layout_marginTop="4dp"
diff --git a/chrome/android/java/res/layout/payment_handler_content.xml b/chrome/android/java/res/layout/payment_handler_content.xml index a5defabf..b3af8a30 100644 --- a/chrome/android/java/res/layout/payment_handler_content.xml +++ b/chrome/android/java/res/layout/payment_handler_content.xml
@@ -4,11 +4,7 @@ found in the LICENSE file. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:background="@color/sheet_bg_color" android:layout_width="match_parent" android:layout_height="match_parent"> - <org.chromium.chrome.browser.ui.widget.FadingShadowView - android:id="@+id/shadow" - android:layout_width="match_parent" - android:layout_height="@dimen/action_bar_shadow_height"/> + </FrameLayout>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetCoordinator.java index 6574914..b81a9dbe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationSheetCoordinator.java
@@ -244,9 +244,10 @@ @Override public void close(boolean animate) { - if (mBottomSheetController.get() == null) return; - if (!isHidden()) mBottomSheetController.get().hideContent(this, animate); - mBottomSheetController.get().removeObserver(mSheetObserver); + BottomSheetController controller = mBottomSheetController.get(); + if (controller == null) return; + controller.hideContent(this, animate); + controller.removeObserver(mSheetObserver); mMediator.clear(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java index 9d412ba9..552d2a8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java
@@ -8,6 +8,7 @@ import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeVersionInfo; import org.chromium.chrome.browser.WebContentsFactory; +import org.chromium.chrome.browser.payments.handler.toolbar.PaymentHandlerToolbarCoordinator; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController; import org.chromium.components.embedder_support.view.ContentView; import org.chromium.content_public.browser.LoadUrlParams; @@ -59,7 +60,11 @@ bottomSheetController.addObserver(mediator); webContents.addObserver(mediator); - PaymentHandlerView view = new PaymentHandlerView(activity, webContents, webContentView); + PaymentHandlerToolbarCoordinator toolbarCoordinator = new PaymentHandlerToolbarCoordinator( + activity, webContents, () -> { mHider.run(); }); + PaymentHandlerView view = new PaymentHandlerView( + activity, webContents, webContentView, toolbarCoordinator.getView()); + assert toolbarCoordinator.getToolbarHeightPx() == view.getToolbarHeightPx(); PropertyModelChangeProcessor changeProcessor = PropertyModelChangeProcessor.create(model, view, PaymentHandlerViewBinder::bind); mHider = () -> {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java index a1bf14f..7151d2c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java
@@ -23,6 +23,8 @@ extends WebContentsObserver implements BottomSheetObserver { private final PropertyModel mModel; private final Runnable mHider; + /** Postfixed with "Ref" to distinguish from mWebContent in WebContentsObserver. */ + private final WebContents mWebContentsRef; /** * Build a new mediator that handle events from outside the payment handler component. @@ -35,28 +37,17 @@ /* package */ PaymentHandlerMediator( PropertyModel model, Runnable hider, WebContents webContents) { super(webContents); + mWebContentsRef = webContents; mModel = model; mHider = hider; } - /** - * Hide the bottom-sheet if weak-ref of web-contents refers to null. - * @return Return true if the sheet is hidden. - */ - private boolean hideSheetIfWebContentsNotExist() { - if (mWebContents != null) return false; - // TODO(maxlg): how to inform the service worker when the web-contents is missing. - mHider.run(); - return true; - } - // BottomSheetObserver: @Override public void onSheetStateChanged(@SheetState int newState) { - if (hideSheetIfWebContentsNotExist()) return; switch (newState) { case BottomSheetController.SheetState.HIDDEN: - ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindow(mWebContents.get()); + ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindow(mWebContentsRef); mHider.run(); break; } @@ -88,28 +79,25 @@ // WebContentsObserver: @Override public void didFinishLoad(long frameId, String validatedUrl, boolean isMainFrame) { - if (hideSheetIfWebContentsNotExist()) return; - if (!SslValidityChecker.isValidPageInPaymentHandlerWindow(mWebContents.get())) { + if (!SslValidityChecker.isValidPageInPaymentHandlerWindow(mWebContentsRef)) { ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindowForInsecureNavigation( - mWebContents.get()); + mWebContentsRef); mHider.run(); } } @Override public void didAttachInterstitialPage() { - if (hideSheetIfWebContentsNotExist()) return; ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindowForInsecureNavigation( - mWebContents.get()); + mWebContentsRef); mHider.run(); } @Override public void didFailLoad( boolean isMainFrame, int errorCode, String description, String failingUrl) { - if (hideSheetIfWebContentsNotExist()) return; // TODO(crbug.com/1017926): Respond to service worker with the net error. - ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindow(mWebContents.get()); + ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindow(mWebContentsRef); mHider.run(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerView.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerView.java index a3454e2..dc64b1ef 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerView.java
@@ -11,13 +11,10 @@ import android.view.ViewGroup.LayoutParams; import android.widget.FrameLayout; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.thinwebview.ThinWebView; import org.chromium.chrome.browser.thinwebview.ThinWebViewFactory; -import org.chromium.chrome.browser.ui.widget.FadingShadow; -import org.chromium.chrome.browser.ui.widget.FadingShadowView; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetContent; import org.chromium.components.embedder_support.view.ContentView; import org.chromium.content_public.browser.WebContents; @@ -25,12 +22,12 @@ /** PaymentHandler UI. */ /* package */ class PaymentHandlerView implements BottomSheetContent { - private final int mToolbarHeightPx; private final View mToolbarView; private final FrameLayout mContentView; private final ThinWebView mThinWebView; private final Handler mReflowHandler = new Handler(); private final int mTabHeight; + private final int mToolbarHeightPx; /** * Construct the PaymentHandlerView. @@ -39,13 +36,12 @@ * @param webContents The web-content of the payment-handler web-app. * @param webContentView The {@link ContentView} that has been contructed with the web-content. */ - /* package */ PaymentHandlerView( - ChromeActivity activity, WebContents webContents, ContentView webContentView) { - mToolbarHeightPx = activity.getResources().getDimensionPixelSize( - R.dimen.custom_tabs_control_container_height); + /* package */ PaymentHandlerView(ChromeActivity activity, WebContents webContents, + ContentView webContentView, View toolbarView) { mTabHeight = activity.getActivityTab().getHeight(); - - mToolbarView = LayoutInflater.from(activity).inflate(R.layout.custom_tabs_toolbar, null); + mToolbarView = toolbarView; + mToolbarHeightPx = + activity.getResources().getDimensionPixelSize(R.dimen.preview_tab_toolbar_height); mContentView = (FrameLayout) LayoutInflater.from(activity).inflate( R.layout.payment_handler_content, null); @@ -63,13 +59,10 @@ */ private void initContentView(ChromeActivity activity, ThinWebView thinWebView, WebContents webContents, ContentView webContentView) { - FadingShadowView shadow = mContentView.findViewById(R.id.shadow); - shadow.init(ApiCompatibilityUtils.getColor( - activity.getResources(), R.color.toolbar_shadow_color), - FadingShadow.POSITION_TOP); assert webContentView.getParent() == null; thinWebView.attachWebContents(webContents, webContentView); - mContentView.setPadding(/*left=*/0, /*top=*/mToolbarHeightPx, /*right=*/0, /*bottom=*/0); + mContentView.setPadding( + /*left=*/0, /*top=*/mToolbarHeightPx, /*right=*/0, /*bottom=*/0); mContentView.addView(thinWebView.getView(), /*index=*/0); } @@ -89,6 +82,10 @@ mThinWebView.getView().setLayoutParams(params); } + /* package */ int getToolbarHeightPx() { + return mToolbarHeightPx; + } + // BottomSheetContent: @Override public View getContentView() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java new file mode 100644 index 0000000..59fa48e --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java
@@ -0,0 +1,61 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.payments.handler.toolbar; + +import android.content.Context; +import android.view.View; + +import org.chromium.components.security_state.ConnectionSecurityLevel; +import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor; + +/** + * PaymentHandlerToolbar coordinator, which owns the component overall, i.e., creates other objects + * in the component and connects them. It decouples the implementation of this component from other + * components and acts as the point of contact between them. Any code in this component that needs + * to interact with another component does that through this coordinator. + */ +public class PaymentHandlerToolbarCoordinator { + private Runnable mHider; + private PaymentHandlerToolbarView mToolbarView; + + /** + * Observer for the error of the payment handler toolbar. + */ + public interface ErrorObserver { + /** + * Called when the UI gets an error + */ + void onError(); + } + + /** Constructs the payment-handler toolbar component coordinator. */ + public PaymentHandlerToolbarCoordinator( + Context context, WebContents webContents, ErrorObserver errorObserver) { + mToolbarView = new PaymentHandlerToolbarView(context); + PropertyModel model = new PropertyModel.Builder(PaymentHandlerToolbarProperties.ALL_KEYS) + .with(PaymentHandlerToolbarProperties.PROGRESS_VISIBLE, true) + .with(PaymentHandlerToolbarProperties.LOAD_PROGRESS, 0) + .with(PaymentHandlerToolbarProperties.SECURITY_ICON, + ConnectionSecurityLevel.NONE) + .build(); + PaymentHandlerToolbarMediator mediator = + new PaymentHandlerToolbarMediator(model, webContents, errorObserver); + webContents.addObserver(mediator); + PropertyModelChangeProcessor changeProcessor = PropertyModelChangeProcessor.create( + model, mToolbarView, PaymentHandlerToolbarViewBinder::bind); + } + + /** @return The height of the toolbar in px. */ + public int getToolbarHeightPx() { + return mToolbarView.getToolbarHeightPx(); + } + + /** @return The toolbar of the PaymentHandler. */ + public View getView() { + return mToolbarView.getView(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarMediator.java new file mode 100644 index 0000000..1fca49a --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarMediator.java
@@ -0,0 +1,134 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.payments.handler.toolbar; + +import android.os.Handler; +import android.support.annotation.DrawableRes; + +import org.chromium.base.Log; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.payments.handler.toolbar.PaymentHandlerToolbarCoordinator.ErrorObserver; +import org.chromium.chrome.browser.ssl.SecurityStateModel; +import org.chromium.components.security_state.ConnectionSecurityLevel; +import org.chromium.components.url_formatter.UrlFormatter; +import org.chromium.content_public.browser.NavigationHandle; +import org.chromium.content_public.browser.WebContents; +import org.chromium.content_public.browser.WebContentsObserver; +import org.chromium.ui.modelutil.PropertyModel; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * PaymentHandlerToolbar mediator, which is responsible for receiving events from the view and + * notifies the backend (the coordinator). + */ +/* package */ class PaymentHandlerToolbarMediator extends WebContentsObserver { + private static final String TAG = "PaymentHandlerTb"; + /** The delay (four video frames - for 60Hz) after which the hide progress will be hidden. */ + private static final long HIDE_PROGRESS_BAR_DELAY_MS = (1000 / 60) * 4; + + private final PropertyModel mModel; + private final ErrorObserver mErrorObserver; + /** The handler to delay hiding the progress bar. */ + private Handler mHideProgressBarHandler; + /** Postfixed with "Ref" to distinguish from mWebContent in WebContentsObserver. */ + private final WebContents mWebContentsRef; + + /** + * Build a new mediator that handle events from outside the payment handler toolbar component. + * @param model The {@link PaymentHandlerToolbarProperties} that holds all the view state for + * the payment handler toolbar component. + * @param hider The callback to clean up the {@link ErrorObserver} when the sheet is + * hidden. + * @param webContents The web-contents that loads the payment app. + */ + /* package */ PaymentHandlerToolbarMediator( + PropertyModel model, WebContents webContents, ErrorObserver errorObserver) { + super(webContents); + mWebContentsRef = webContents; + mModel = model; + mErrorObserver = errorObserver; + } + + // WebContentsObserver: + @Override + public void didFinishLoad(long frameId, String validatedUrl, boolean isMainFrame) { + // Hides the Progress Bar after a delay to make sure it is rendered for at least + // a few frames, otherwise its completion won't be visually noticeable. + mHideProgressBarHandler = new Handler(); + mHideProgressBarHandler.postDelayed(() -> { + mModel.set(PaymentHandlerToolbarProperties.PROGRESS_VISIBLE, false); + mHideProgressBarHandler = null; + }, HIDE_PROGRESS_BAR_DELAY_MS); + return; + } + + @Override + public void didFailLoad( + boolean isMainFrame, int errorCode, String description, String failingUrl) { + mModel.set(PaymentHandlerToolbarProperties.PROGRESS_VISIBLE, false); + } + + @Override + public void didFinishNavigation(NavigationHandle navigation) { + if (navigation.hasCommitted() && navigation.isInMainFrame()) { + String url = navigation.getUrl(); + String origin = UrlFormatter.formatUrlForSecurityDisplayOmitScheme(url); + try { + mModel.set(PaymentHandlerToolbarProperties.PROGRESS_VISIBLE, false); + mModel.set(PaymentHandlerToolbarProperties.ORIGIN, new URI(origin)); + } catch (URISyntaxException e) { + Log.e(TAG, "Failed to instantiate URI with the origin \"%s\", whose url is \"%s\".", + origin, url); + mErrorObserver.onError(); + return; + } + } + } + + @Override + public void titleWasSet(String title) { + mModel.set(PaymentHandlerToolbarProperties.TITLE, title); + } + + @Override + public void loadProgressChanged(float progress) { + if (progress == 1.0) return; + // If the load restarts when the progress bar is waiting to hide, cancel the handler + // callbacks. + if (mHideProgressBarHandler != null) { + mHideProgressBarHandler.removeCallbacksAndMessages(null); + mHideProgressBarHandler = null; + } + mModel.set(PaymentHandlerToolbarProperties.PROGRESS_VISIBLE, true); + mModel.set(PaymentHandlerToolbarProperties.LOAD_PROGRESS, progress); + } + + @DrawableRes + private static int getSecurityIconResource(@ConnectionSecurityLevel int securityLevel) { + switch (securityLevel) { + case ConnectionSecurityLevel.NONE: + case ConnectionSecurityLevel.WARNING: + return R.drawable.omnibox_info; + case ConnectionSecurityLevel.DANGEROUS: + return R.drawable.omnibox_not_secure_warning; + case ConnectionSecurityLevel.SECURE_WITH_POLICY_INSTALLED_CERT: + case ConnectionSecurityLevel.SECURE: + case ConnectionSecurityLevel.EV_SECURE: + return R.drawable.omnibox_https_valid; + default: + assert false; + } + return 0; + } + + @Override + public void didChangeVisibleSecurityState() { + int securityLevel = SecurityStateModel.getSecurityLevelForWebContents(mWebContentsRef); + mModel.set(PaymentHandlerToolbarProperties.SECURITY_ICON, + getSecurityIconResource(securityLevel)); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarProperties.java new file mode 100644 index 0000000..6b76baf --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarProperties.java
@@ -0,0 +1,36 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.payments.handler.toolbar; + +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableFloatPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; + +import java.net.URI; + +/** PaymentHandlerToolbar UI properties, which fully describe the state of the UI. */ +/* package */ class PaymentHandlerToolbarProperties { + /* package */ static final WritableObjectPropertyKey<URI> ORIGIN = + new WritableObjectPropertyKey<>(); + + /* package */ static final WritableObjectPropertyKey<String> TITLE = + new WritableObjectPropertyKey<>(); + + /* package */ static final WritableFloatPropertyKey LOAD_PROGRESS = + new WritableFloatPropertyKey(); + + /* package */ static final WritableBooleanPropertyKey PROGRESS_VISIBLE = + new WritableBooleanPropertyKey(); + + /* package */ static final WritableIntPropertyKey SECURITY_ICON = new WritableIntPropertyKey(); + + /* package */ static final PropertyKey[] ALL_KEYS = + new PropertyKey[] {ORIGIN, TITLE, LOAD_PROGRESS, PROGRESS_VISIBLE, SECURITY_ICON}; + + // Prevent instantiation. + private PaymentHandlerToolbarProperties() {} +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarView.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarView.java new file mode 100644 index 0000000..fecfd99 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarView.java
@@ -0,0 +1,63 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.payments.handler.toolbar; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.ui.widget.FadingShadow; +import org.chromium.chrome.browser.ui.widget.FadingShadowView; + +/** PaymentHandlerToolbar UI. */ +/* package */ class PaymentHandlerToolbarView { + private final int mToolbarHeightPx; + private final View mToolbarView; + + /* package */ final TextView mOriginView; + /* package */ final TextView mTitleView; + /* package */ final ProgressBar mProgressBar; + /* package */ final ImageView mSecurityIconView; + + /** + * Construct the PaymentHandlerToolbarView. + * + * @param context The context where the bottome-sheet should be shown. + */ + /* package */ PaymentHandlerToolbarView(Context context) { + mToolbarHeightPx = + context.getResources().getDimensionPixelSize(R.dimen.preview_tab_toolbar_height); + + mToolbarView = LayoutInflater.from(context).inflate(R.layout.ephemeral_tab_toolbar, null); + mOriginView = mToolbarView.findViewById(R.id.ephemeral_tab_caption); + mTitleView = mToolbarView.findViewById(R.id.ephemeral_tab_text); + mProgressBar = mToolbarView.findViewById(R.id.progress_bar); + mSecurityIconView = mToolbarView.findViewById(R.id.security_icon); + + // These parts from ephemeral_tab_toolbar are not needed in this component. + mToolbarView.findViewById(R.id.open_in_new_tab).setVisibility(View.GONE); + mToolbarView.findViewById(R.id.favicon).setVisibility(View.GONE); + + FadingShadowView shadow = mToolbarView.findViewById(R.id.shadow); + shadow.init(ApiCompatibilityUtils.getColor( + context.getResources(), R.color.toolbar_shadow_color), + FadingShadow.POSITION_TOP); + } + + /** @return The height of the toolbar in px. */ + /* package */ int getToolbarHeightPx() { + return mToolbarHeightPx; + } + + /** @return The layout of the PaymentHandlerToolbar. */ + /* package */ View getView() { + return mToolbarView; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarViewBinder.java new file mode 100644 index 0000000..263802f --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarViewBinder.java
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.payments.handler.toolbar; + +import android.view.View; + +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; + +/** + * PaymentHandlerToolbar view binder, which is stateless. It is called to bind a given model to a + * given view. Should contain as little business logic as possible. + */ +/* package */ class PaymentHandlerToolbarViewBinder { + /* package */ static void bind( + PropertyModel model, PaymentHandlerToolbarView view, PropertyKey propertyKey) { + if (PaymentHandlerToolbarProperties.ORIGIN == propertyKey) { + view.mOriginView.setText(model.get(PaymentHandlerToolbarProperties.ORIGIN).toString()); + } else if (PaymentHandlerToolbarProperties.TITLE == propertyKey) { + view.mTitleView.setText(model.get(PaymentHandlerToolbarProperties.TITLE)); + } else if (PaymentHandlerToolbarProperties.LOAD_PROGRESS == propertyKey) { + view.mProgressBar.setProgress( + Math.round(model.get(PaymentHandlerToolbarProperties.LOAD_PROGRESS) * 100)); + } else if (PaymentHandlerToolbarProperties.PROGRESS_VISIBLE == propertyKey) { + boolean visible = model.get(PaymentHandlerToolbarProperties.PROGRESS_VISIBLE); + view.mProgressBar.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); + } else if (PaymentHandlerToolbarProperties.SECURITY_ICON == propertyKey) { + int securityIconResource = model.get(PaymentHandlerToolbarProperties.SECURITY_ICON); + view.mSecurityIconView.setImageResource(securityIconResource); + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/RadioButtonGroupThemePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/RadioButtonGroupThemePreference.java index f0ed2a4d..eff92cb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/RadioButtonGroupThemePreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/RadioButtonGroupThemePreference.java
@@ -20,23 +20,28 @@ import org.chromium.chrome.browser.night_mode.NightModeMetrics; import org.chromium.chrome.browser.preferences.themes.ThemePreferences.ThemeSetting; import org.chromium.chrome.browser.ui.widget.RadioButtonWithDescription; +import org.chromium.chrome.browser.ui.widget.RadioButtonWithDescriptionLayout; import java.util.ArrayList; import java.util.Collections; /** * A radio button group Preference used for Themes. Currently, it has 3 options: System default, - * Light, and Dark. + * Light, and Dark. When an additional flag, DARKEN_WEBSITES_CHECKBOX_IN_THEMES_SETTING, is active + * there is an option added underneath the currently selected preference to allow website contents + * to be darkened (active for System default and Dark). */ public class RadioButtonGroupThemePreference extends Preference implements RadioGroup.OnCheckedChangeListener { private @ThemeSetting int mSetting; + private RadioButtonWithDescription mSettingRadioButton; + private RadioButtonWithDescriptionLayout mGroup; private ArrayList<RadioButtonWithDescription> mButtons; + + // Additional view that darkens website contents. + private LinearLayout mCheckboxContainer; private boolean mDarkenWebsitesEnabled; private CheckBox mCheckBox; - private LinearLayout mLayoutContainer; - private LinearLayout mCheckboxContainer; - private RadioGroup mRadioGroup; public RadioButtonGroupThemePreference(Context context, AttributeSet attrs) { super(context, attrs); @@ -61,10 +66,9 @@ super.onBindViewHolder(holder); mCheckboxContainer = (LinearLayout) holder.findViewById(R.id.checkbox_container); mCheckBox = (CheckBox) holder.findViewById(R.id.darken_websites); - mLayoutContainer = (LinearLayout) holder.itemView; - mRadioGroup = (RadioGroup) holder.findViewById(R.id.radio_button_layout); - mRadioGroup.setOnCheckedChangeListener(this); + mGroup = (RadioButtonWithDescriptionLayout) holder.findViewById(R.id.radio_button_layout); + mGroup.setOnCheckedChangeListener(this); mCheckboxContainer.setOnClickListener(x -> { mCheckBox.setChecked(!mCheckBox.isChecked()); @@ -86,20 +90,20 @@ mButtons.set( ThemeSetting.DARK, (RadioButtonWithDescription) holder.findViewById(R.id.dark)); - mButtons.get(mSetting).setChecked(true); + mSettingRadioButton = mButtons.get(mSetting); + mSettingRadioButton.setChecked(true); positionCheckbox(); } /** - * Remove and insert the checkbox to the view, based on the value of mSetting + * Remove and insert the checkbox to the view, based on the current theme preference. */ private void positionCheckbox() { if (ChromeFeatureList.isEnabled( ChromeFeatureList.DARKEN_WEBSITES_CHECKBOX_IN_THEMES_SETTING)) { if (mSetting == ThemeSetting.SYSTEM_DEFAULT || mSetting == ThemeSetting.DARK) { - mLayoutContainer.removeView(mCheckboxContainer); + mGroup.attachAccessoryView(mCheckboxContainer, mSettingRadioButton); mCheckboxContainer.setVisibility(View.VISIBLE); - mLayoutContainer.addView(mCheckboxContainer, mSetting + 1); } else { mCheckboxContainer.setVisibility(View.GONE); } @@ -111,9 +115,12 @@ for (int i = 0; i < ThemeSetting.NUM_ENTRIES; i++) { if (mButtons.get(i).isChecked()) { mSetting = i; + mSettingRadioButton = mButtons.get(i); break; } } + assert mSetting >= 0 && mSetting < ThemeSetting.NUM_ENTRIES : "No matching setting found."; + positionCheckbox(); callChangeListener(mSetting); NightModeMetrics.recordThemePreferencesChanged(mSetting);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/widget/OWNERS index 6bc8c97..ff0a541 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/OWNERS
@@ -1,4 +1,5 @@ twellington@chromium.org +per-file FeatureHighlightProvider.java=mdjones@chromium.org per-file ToolbarProgressBar*=mdjones@chromium.org per-file ScrimView.java=mdjones@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityCustomTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityCustomTabTest.java new file mode 100644 index 0000000..be0cc52 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityCustomTabTest.java
@@ -0,0 +1,61 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.directactions; +import static org.junit.Assert.assertThat; + +import android.annotation.TargetApi; +import android.content.Intent; +import android.os.Build; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; + +import org.hamcrest.Matchers; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.MinAndroidSdkLevel; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; +import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; + +/** + * Tests the availability of core direct actions in different activities. + * + * <p>This tests both {@link DirectActionInitializer} and its integration with {@link + * ChromeActivity} and its different subclasses. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_DIRECT_ACTIONS) +@MinAndroidSdkLevel(Build.VERSION_CODES.N) +@TargetApi(24) // For java.util.function.Consumer. +public class DirectActionAvailabilityCustomTabTest { + @Rule + public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule(); + + @Rule + public DirectActionTestRule mDirectActionRule = new DirectActionTestRule(); + + @Test + @MediumTest + @Feature({"DirectActions"}) + public void testCoreDirectActionInCustomTabActivity() throws Exception { + Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), "about:blank"); + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + + assertThat( + DirectActionTestUtils.setupActivityAndGetDirectAction(mCustomTabActivityTestRule), + Matchers.containsInAnyOrder( + "go_back", "reload", "go_forward", "bookmark_this_page", "preferences")); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityTabbedTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityTabbedTest.java new file mode 100644 index 0000000..e98e6d2 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityTabbedTest.java
@@ -0,0 +1,64 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.directactions; +import static org.junit.Assert.assertThat; + +import android.annotation.TargetApi; +import android.os.Build; +import android.support.test.filters.MediumTest; + +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.MinAndroidSdkLevel; +import org.chromium.base.test.util.RetryOnFailure; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; + +/** + * Tests the availability of core direct actions in different activities. + * + * <p>This tests both {@link DirectActionInitializer} and its integration with {@link + * ChromeActivity} and its different subclasses. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_DIRECT_ACTIONS) +@MinAndroidSdkLevel(Build.VERSION_CODES.N) +@TargetApi(24) // For java.util.function.Consumer. +public class DirectActionAvailabilityTabbedTest { + @Rule + public ChromeTabbedActivityTestRule mTabbedActivityTestRule = + new ChromeTabbedActivityTestRule(); + + @Rule + public DirectActionTestRule mDirectActionRule = new DirectActionTestRule(); + + @Before + public void setUp() throws Exception { + // Using OnBlank times out when waiting for NTP. Using null makes the test work. + mTabbedActivityTestRule.startMainActivityWithURL(null); + } + + @Test + @MediumTest + @RetryOnFailure + @Feature({"DirectActions"}) + public void testCoreDirectActionInTabbedActivity() throws Exception { + assertThat(DirectActionTestUtils.setupActivityAndGetDirectAction(mTabbedActivityTestRule), + Matchers.containsInAnyOrder("go_back", "reload", "go_forward", "bookmark_this_page", + "downloads", "preferences", "open_history", "help", "new_tab", "close_tab", + "close_all_tabs")); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityTest.java deleted file mode 100644 index 6f7f775..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityTest.java +++ /dev/null
@@ -1,130 +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. - -package org.chromium.chrome.browser.directactions; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import android.annotation.TargetApi; -import android.content.Intent; -import android.os.Build; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.MediumTest; - -import org.hamcrest.Matchers; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.MinAndroidSdkLevel; -import org.chromium.chrome.browser.ChromeActivity; -import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.ChromeSwitches; -import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; -import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.webapps.WebappActivityTestRule; -import org.chromium.chrome.test.ChromeActivityTestRule; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.chrome.test.util.ChromeTabUtils; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; -import org.chromium.content_public.browser.test.util.TestThreadUtils; - -import java.util.List; - -/** - * Tests the availability of core direct actions in different activities. - * - * <p>This tests both {@link DirectActionInitializer} and its integration with {@link - * ChromeActivity} and its different subclasses. - */ -@RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_DIRECT_ACTIONS) -@MinAndroidSdkLevel(Build.VERSION_CODES.N) -@TargetApi(24) // For java.util.function.Consumer. -public class DirectActionAvailabilityTest { - @Rule - public ChromeTabbedActivityTestRule mTabbedActivityTestRule = - new ChromeTabbedActivityTestRule(); - - @Rule - public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule(); - - @Rule - public WebappActivityTestRule mWebAppActivityTestRule = new WebappActivityTestRule(); - - @Rule - public DirectActionTestRule mDirectActionRule = new DirectActionTestRule(); - - @Test - @MediumTest - @Feature({"DirectActions"}) - public void testCoreDirectActionInTabbedActivity() throws Exception { - mTabbedActivityTestRule.startMainActivityOnBlankPage(); - - assertThat(setupActivityAndGetDirectAction(mTabbedActivityTestRule), - Matchers.containsInAnyOrder("go_back", "reload", "go_forward", "bookmark_this_page", - "downloads", "preferences", "open_history", "help", "new_tab", "close_tab", - "close_all_tabs")); - } - - @Test - @MediumTest - @Feature({"DirectActions"}) - public void testCoreDirectActionInCustomTabActivity() throws Exception { - Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( - InstrumentationRegistry.getTargetContext(), "about:blank"); - mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); - - assertThat(setupActivityAndGetDirectAction(mCustomTabActivityTestRule), - Matchers.containsInAnyOrder( - "go_back", "reload", "go_forward", "bookmark_this_page", "preferences")); - } - - @Test - @MediumTest - @Feature({"DirectActions"}) - @DisabledTest(message = "https://crbug.com/1018183") - public void testCoreDirectActionInWebappActivity() throws Exception { - mWebAppActivityTestRule.startWebappActivity(); - - assertThat(setupActivityAndGetDirectAction(mWebAppActivityTestRule), - Matchers.containsInAnyOrder("go_back", "reload", "go_forward")); - } - - private List<String> setupActivityAndGetDirectAction(ChromeActivityTestRule<?> rule) - throws Exception { - allowGoForward(rule); - return DirectActionTestUtils.callOnGetDirectActions(rule.getActivity()); - } - - /** - * Forces availability of the "go_forward" direct action on the current tab by loading another - * URL then navigating back to the current one. - * - * <p>The activity of the given rule must have been started and have loaded a page. - */ - public static void allowGoForward(ChromeActivityTestRule<?> rule) throws Exception { - ChromeActivity activity = rule.getActivity(); - String initialUrl = TestThreadUtils.runOnUiThreadBlocking( - () -> activity.getCurrentWebContents().getLastCommittedUrl()); - - // Any built-in page that is not about:blank and is reasonably cheap to render will do, - // here. - String visitedUrl = "chrome://version/"; - assertThat(initialUrl, Matchers.not(Matchers.equalTo(visitedUrl))); - rule.loadUrl(visitedUrl); - - Tab tab = activity.getTabModelSelector().getCurrentTab(); - TestThreadUtils.runOnUiThreadBlocking( - () -> activity.getCurrentWebContents().getNavigationController().goBack()); - ChromeTabUtils.waitForTabPageLoaded(tab, initialUrl); - assertTrue(tab.canGoForward()); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityWebappTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityWebappTest.java new file mode 100644 index 0000000..f84dadd --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityWebappTest.java
@@ -0,0 +1,54 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.directactions; +import static org.junit.Assert.assertThat; + +import android.annotation.TargetApi; +import android.os.Build; +import android.support.test.filters.MediumTest; + +import org.hamcrest.Matchers; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.MinAndroidSdkLevel; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.webapps.WebappActivityTestRule; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; + +/** + * Tests the availability of core direct actions in different activities. + * + * <p>This tests both {@link DirectActionInitializer} and its integration with {@link + * ChromeActivity} and its different subclasses. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_DIRECT_ACTIONS) +@MinAndroidSdkLevel(Build.VERSION_CODES.N) +@TargetApi(24) // For java.util.function.Consumer. +public class DirectActionAvailabilityWebappTest { + @Rule + public WebappActivityTestRule mWebAppActivityTestRule = new WebappActivityTestRule(); + + @Rule + public DirectActionTestRule mDirectActionRule = new DirectActionTestRule(); + + @Test + @MediumTest + @Feature({"DirectActions"}) + public void testCoreDirectActionInWebappActivity() throws Exception { + mWebAppActivityTestRule.startWebappActivity(); + + assertThat(DirectActionTestUtils.setupActivityAndGetDirectAction(mWebAppActivityTestRule), + Matchers.containsInAnyOrder("go_back", "reload", "go_forward")); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionTestUtils.java index d8e3de9..6ce50e24 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionTestUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionTestUtils.java
@@ -4,11 +4,19 @@ package org.chromium.chrome.browser.directactions; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + import android.os.Bundle; import android.os.CancellationSignal; +import org.hamcrest.Matchers; + import org.chromium.base.Callback; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.test.ChromeActivityTestRule; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.util.ArrayList; @@ -17,7 +25,7 @@ /** * Utilities for writing tests that check for or perform direct actions on an activity. */ -public class DirectActionTestUtils { +class DirectActionTestUtils { /** Perform a direct action, with the given name. */ public static void callOnPerformDirectActions( ChromeActivity activity, String actionId, Callback<Bundle> callback) { @@ -43,6 +51,41 @@ return directActions; } + /** + * Sets the ChromeActivityTestRule by forcing "go_forward" to be available. + * + * <p>The activity of the given rule must have been started and have loaded a page. + */ + static List<String> setupActivityAndGetDirectAction(ChromeActivityTestRule<?> rule) + throws Exception { + allowGoForward(rule); + return callOnGetDirectActions(rule.getActivity()); + } + + /** + * Forces availability of the "go_forward" direct action on the current tab by loading another + * URL then navigating back to the current one. + * + * <p>The activity of the given rule must have been started and have loaded a page. + */ + static void allowGoForward(ChromeActivityTestRule<?> rule) throws Exception { + ChromeActivity activity = rule.getActivity(); + String initialUrl = TestThreadUtils.runOnUiThreadBlocking( + () -> activity.getCurrentWebContents().getLastCommittedUrl()); + + // Any built-in page that is not about:blank and is reasonably cheap to render will do, + // here. + String visitedUrl = "chrome://version/"; + assertThat(initialUrl, Matchers.not(Matchers.equalTo(visitedUrl))); + rule.loadUrl(visitedUrl); + + Tab tab = activity.getTabModelSelector().getCurrentTab(); + TestThreadUtils.runOnUiThreadBlocking( + () -> activity.getCurrentWebContents().getNavigationController().goBack()); + ChromeTabUtils.waitForTabPageLoaded(tab, initialUrl); + assertTrue(tab.canGoForward()); + } + private DirectActionTestUtils() { // This is a utility class; it is not meant to be instantiated. }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/OWNERS new file mode 100644 index 0000000..829eb83 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/OWNERS
@@ -0,0 +1 @@ +file://components/autofill_assistant/OWNERS \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java index 0df99d9..c8e1f4d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
@@ -23,6 +23,7 @@ import org.chromium.base.library_loader.LoadStatusRecorder.LoadLibraryStatus; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; @@ -150,6 +151,8 @@ @Test @LargeTest @RetryOnFailure + @DisableIf.Build(sdk_is_greater_than = Build.VERSION_CODES.N_MR1, + message = "https://crbug.com/1023433") public void testStartWithURLRecorded() throws Exception { runAndWaitForPageLoadMetricsRecorded( () -> mTabbedActivityTestRule.startMainActivityWithURL(mTestPage)); @@ -218,6 +221,8 @@ @Test @LargeTest @RetryOnFailure + @DisableIf.Build(sdk_is_greater_than = Build.VERSION_CODES.N_MR1, + message = "https://crbug.com/1023433") public void testFromExternalAppRecorded() throws Exception { runAndWaitForPageLoadMetricsRecorded( () -> mTabbedActivityTestRule.startMainActivityFromExternalApp(mTestPage, null));
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 58baeee..cd336c4 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -10255,6 +10255,32 @@ Verify </message> + <!-- App pause prompt --> + <message name="IDS_APP_PAUSE_PROMPT_TITLE" desc="Titlebar of the app pause prompt window"> + App paused + </message> + + <message name="IDS_APP_PAUSE_HEADING_HOURS_AND_MINUTES" desc="Tells the user the app will be paused."> + The limit on "<ph name="APP_NAME">$1<ex>Google Photos</ex></ph>" that your parent set ran out. You can use it for <ph name="HOURS">$2<ex>2 hours</ex></ph> <ph name="MINUTES">$3<ex>30 minutes</ex></ph> tomorrow. + </message> + <message name="IDS_APP_PAUSE_HEADING_HOURS_ONLY" desc="Tells the user the app will be paused."> + The limit on "<ph name="APP_NAME">$1<ex>Google Photos</ex></ph>" that your parent set ran out. You can use it for <ph name="HOURS">$2<ex>2 hours</ex></ph> tomorrow. + </message> + <message name="IDS_APP_PAUSE_HEADING_MINUTES_ONLY" desc="Tells the user the app will be paused."> + The limit on "<ph name="APP_NAME">$1<ex>Google Photos</ex></ph>" that your parent set ran out. You can use it for <ph name="MINUTES">$2<ex>30 minutes</ex></ph> tomorrow. + </message> + <message name="IDS_APP_PAUSE_HEADING_HOURS" desc="Tells the user the app can be run how many hours. [ICU Syntax]"> + {HOURS, plural, + =1 {# hour} + other {# hours}} + </message> + <message name="IDS_APP_PAUSE_HEADING_MINUTES" desc="Tells the user the app can be run how many minutes. [ICU Syntax]"> + {MINUTES, plural, + =1 {# minute} + other {# minutes}} + </message> + + </messages> </release> </grit>
diff --git a/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_HOURS.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_HOURS.png.sha1 new file mode 100644 index 0000000..a90bf8d --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_HOURS.png.sha1
@@ -0,0 +1 @@ +b9d8a5bb225403e83014694d7c8693d652003cb8 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_HOURS_AND_MINUTES.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_HOURS_AND_MINUTES.png.sha1 new file mode 100644 index 0000000..1024e26 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_HOURS_AND_MINUTES.png.sha1
@@ -0,0 +1 @@ +ac9f6657699ab90f5ed2c65d5de7b67e4fdc7be8 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_HOURS_ONLY.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_HOURS_ONLY.png.sha1 new file mode 100644 index 0000000..5ae63e7 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_HOURS_ONLY.png.sha1
@@ -0,0 +1 @@ +8b21c8dff4948451dc44ca53f6c3ab4d4b676921 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_MINUTES.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_MINUTES.png.sha1 new file mode 100644 index 0000000..a90bf8d --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_MINUTES.png.sha1
@@ -0,0 +1 @@ +b9d8a5bb225403e83014694d7c8693d652003cb8 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_MINUTES_ONLY.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_MINUTES_ONLY.png.sha1 new file mode 100644 index 0000000..e4030fb6 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_HEADING_MINUTES_ONLY.png.sha1
@@ -0,0 +1 @@ +19bdab026c688357ed9f0275d0b795fc6f0cb23a \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_APP_PAUSE_PROMPT_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_PROMPT_TITLE.png.sha1 new file mode 100644 index 0000000..6b005f9 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_PAUSE_PROMPT_TITLE.png.sha1
@@ -0,0 +1 @@ +5b713d24b0c6a493d8cbe52a3bb7e5127290b587 \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 52132ed..2bfe199 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -511,11 +511,11 @@ <message name="IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_OPTIONS_LABEL" desc="In the settings tab, the label for the button that opens the Options page for the Select-to-Speak feature."> Open select-to-speak settings </message> - <message name="IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION" desc="In the settings tab, the text next to the checkbox to enable switch access (for users with limited motor control)."> - Switch access (control the computer with just one or two switches) + <message name="IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION" desc="In the settings tab, the text next to the checkbox to enable Switch Access (for users with limited motor control)."> + Switch Access (control the computer with just one or two switches) </message> <message name="IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_OPTIONS_LABEL" desc="In the settings tab, the label for the button that opens the Options page for the Switch Access feature."> - Switch access options + Switch Access options </message> <message name="IDS_SETTINGS_ACCESSIBILITY_TEXT_TO_SPEECH_HEADING" desc="In the settings tab, the heading for accessibility features that enable the computer to speak text from the computer screen."> Text-to-Speech
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 2745d67..62e8141 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4124,6 +4124,10 @@ FEATURE_VALUE_TYPE(features::kUseSkiaRenderer)}, #if defined(OS_CHROMEOS) + {"allow-ambient-eq", flag_descriptions::kAllowAmbientEQName, + flag_descriptions::kAllowAmbientEQDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kAllowAmbientEQ)}, + {"allow-disable-mouse-acceleration", flag_descriptions::kAllowDisableMouseAccelerationName, flag_descriptions::kAllowDisableMouseAccelerationDescription, kOsCrOS,
diff --git a/chrome/browser/app_controller_mac_browsertest.mm b/chrome/browser/app_controller_mac_browsertest.mm index bcc5c17..7b03e59 100644 --- a/chrome/browser/app_controller_mac_browsertest.mm +++ b/chrome/browser/app_controller_mac_browsertest.mm
@@ -63,6 +63,11 @@ using base::SysUTF16ToNSString; +@interface AppController (ForTesting) +- (void)getUrl:(NSAppleEventDescriptor*)event + withReply:(NSAppleEventDescriptor*)reply; +@end + namespace { GURL g_open_shortcut_url = GURL::EmptyGURL(); @@ -86,14 +91,7 @@ void SendAppleEventToOpenUrlToAppController(const GURL& url) { AppController* controller = base::mac::ObjCCast<AppController>([NSApp delegate]); - Method get_url = - class_getInstanceMethod([controller class], @selector(getUrl:withReply:)); - - ASSERT_TRUE(get_url); - - NSAppleEventDescriptor* shortcut_event = AppleEventToOpenUrl(url); - - method_invoke(controller, get_url, shortcut_event, NULL); + [controller getUrl:AppleEventToOpenUrl(url) withReply:nullptr]; } void RunClosureWhenProfileInitialized(const base::Closure& closure,
diff --git a/chrome/browser/apps/app_service/app_service_proxy.cc b/chrome/browser/apps/app_service/app_service_proxy.cc index cc20b21..89b9ec3 100644 --- a/chrome/browser/apps/app_service/app_service_proxy.cc +++ b/chrome/browser/apps/app_service/app_service_proxy.cc
@@ -280,6 +280,50 @@ uninstall_dialogs_.erase(it); } +void AppServiceProxy::PauseApps( + const std::map<std::string, PauseData>& pause_data) { + if (!app_service_.is_connected()) + return; + + for (auto& data : pause_data) { + apps::mojom::AppType app_type = cache_.GetAppType(data.first); + constexpr bool kPaused = true; + UpdatePausedStatus(app_type, data.first, kPaused); + + // TODO(crbug.com/1011235): Add the app running checking. If the app is not + // running, don't create the pause dialog, pause the app directly. + if (app_type != apps::mojom::AppType::kArc) { + // TODO(crbug.com/1011235): Add AppService interface to apply icon + // effects. + continue; + } + + cache_.ForOneApp(data.first, [this, &data](const apps::AppUpdate& update) { + this->LoadIconForPauseDialog(update, data.second); + }); + } +} + +void AppServiceProxy::UnpauseApps(const std::set<std::string>& app_ids) { + if (!app_service_.is_connected()) + return; + + for (auto& app_id : app_ids) { + apps::mojom::AppType app_type = cache_.GetAppType(app_id); + constexpr bool kPaused = false; + UpdatePausedStatus(app_type, app_id, kPaused); + + // TODO(crbug.com/1011235): Add AppService interface to recover icon + // effects. + } +} + +void AppServiceProxy::OnPauseDialogClosed(apps::mojom::AppType app_type, + const std::string& app_id) { + // TODO(crbug.com/1011235): Add AppService interface to apply the icon effect + // and stop the running app. +} + void AppServiceProxy::OpenNativeSettings(const std::string& app_id) { if (app_service_.is_connected()) { cache_.ForOneApp(app_id, [this](const apps::AppUpdate& update) { @@ -404,4 +448,49 @@ std::make_unique<base::Value>(std::move(preferred_apps))); } +void AppServiceProxy::LoadIconForPauseDialog(const apps::AppUpdate& update, + const PauseData& pause_data) { + apps::mojom::IconKeyPtr icon_key = update.IconKey(); + constexpr bool kAllowPlaceholderIcon = false; + constexpr int32_t kPauseIconSize = 48; + LoadIconFromIconKey( + update.AppType(), update.AppId(), std::move(icon_key), + apps::mojom::IconCompression::kUncompressed, kPauseIconSize, + kAllowPlaceholderIcon, + base::BindOnce(&AppServiceProxy::OnLoadIconForPauseDialog, + weak_ptr_factory_.GetWeakPtr(), update.AppType(), + update.AppId(), update.Name(), pause_data)); +} + +void AppServiceProxy::OnLoadIconForPauseDialog( + apps::mojom::AppType app_type, + const std::string& app_id, + const std::string& app_name, + const PauseData& pause_data, + apps::mojom::IconValuePtr icon_value) { + if (icon_value->icon_compression != + apps::mojom::IconCompression::kUncompressed) { + OnPauseDialogClosed(app_type, app_id); + return; + } + + AppServiceProxy::CreatePauseDialog( + app_name, icon_value->uncompressed, pause_data, + base::BindOnce(&AppServiceProxy::OnPauseDialogClosed, + weak_ptr_factory_.GetWeakPtr(), app_type, app_id)); +} + +void AppServiceProxy::UpdatePausedStatus(apps::mojom::AppType app_type, + const std::string& app_id, + bool paused) { + std::vector<apps::mojom::AppPtr> apps; + apps::mojom::AppPtr app = apps::mojom::App::New(); + app->app_type = app_type; + app->app_id = app_id; + app->paused = (paused) ? apps::mojom::OptionalBool::kTrue + : apps::mojom::OptionalBool::kFalse; + apps.push_back(std::move(app)); + cache_.OnApps(std::move(apps)); +} + } // namespace apps
diff --git a/chrome/browser/apps/app_service/app_service_proxy.h b/chrome/browser/apps/app_service/app_service_proxy.h index ca32f83..37b8a4c 100644 --- a/chrome/browser/apps/app_service/app_service_proxy.h +++ b/chrome/browser/apps/app_service/app_service_proxy.h
@@ -5,13 +5,13 @@ #ifndef CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_H_ #define CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_H_ +#include <map> #include <memory> #include <set> #include "base/containers/unique_ptr_adapters.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/apps/app_service/uninstall_dialog.h" #include "chrome/services/app_service/public/cpp/app_registry_cache.h" #include "chrome/services/app_service/public/cpp/icon_cache.h" #include "chrome/services/app_service/public/cpp/icon_coalescer.h" @@ -35,6 +35,12 @@ namespace apps { class AppServiceImpl; +class UninstallDialog; + +struct PauseData { + int hours; + int minutes; +}; // Singleton (per Profile) proxy and cache of an App Service's apps. // @@ -46,6 +52,8 @@ public apps::IconLoader, public apps::mojom::Subscriber { public: + using OnPauseDialogClosedCallback = base::OnceCallback<void()>; + explicit AppServiceProxy(Profile* profile); ~AppServiceProxy() override; @@ -92,6 +100,23 @@ bool clear_site_data, bool report_abuse, UninstallDialog* uninstall_dialog); + + // Pauses apps. |pause_data|'s key is the app_id. |pause_data|'s PauseData + // is the time limit setting for the app, which is shown in the pause app + // dialog. AppService sets the paused status directly. If the app is running, + // AppService shows the pause app dialog. Otherwise, AppService applies the + // paused app icon effect directly. + void PauseApps(const std::map<std::string, PauseData>& pause_data); + + // Unpauses the apps from the paused status. AppService sets the paused status + // as false directly and removes the paused app icon effect. + void UnpauseApps(const std::set<std::string>& app_ids); + + // Called when the user clicks the 'OK' button of the pause app dialog. + // AppService stops the running app and applies the paused app icon effect. + void OnPauseDialogClosed(apps::mojom::AppType app_type, + const std::string& app_id); + void OpenNativeSettings(const std::string& app_id); void FlushMojoCallsForTesting(); @@ -170,6 +195,11 @@ apps::IconLoader* overriding_icon_loader_for_testing_; }; + static void CreatePauseDialog(const std::string& app_name, + gfx::ImageSkia image, + const PauseData& pause_data, + OnPauseDialogClosedCallback pause_callback); + void Initialize(); void AddAppIconSource(Profile* profile); @@ -184,6 +214,20 @@ apps::mojom::IntentFilterPtr intent_filter) override; void InitializePreferredApps(base::Value preferred_apps) override; + void LoadIconForPauseDialog(const apps::AppUpdate& update, + const PauseData& pause_data); + + // Callback invoked when the icon is loaded. + void OnLoadIconForPauseDialog(apps::mojom::AppType app_type, + const std::string& app_id, + const std::string& app_name, + const PauseData& pause_data, + apps::mojom::IconValuePtr icon_value); + + void UpdatePausedStatus(apps::mojom::AppType app_type, + const std::string& app_id, + bool paused); + // This proxy privately owns its instance of the App Service. This should not // be exposed except through the Mojo interface connected to |app_service_|. std::unique_ptr<apps::AppServiceImpl> app_service_impl_;
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 7c44181..a811a55f 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -919,8 +919,8 @@ if (!command_line->HasSwitch( ::switches::kEnableExperimentalAccessibilitySwitchAccess)) { if (enabled) { - LOG(WARNING) << "Switch access enabled but experimental accessibility " - << "switch access flag is not set."; + LOG(WARNING) << "Switch Access enabled but experimental accessibility " + << "Switch Access flag is not set."; } return; }
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h index 23d91d6b..dc8850d 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.h +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h
@@ -214,10 +214,10 @@ // Called when the Select-to-Speak extension state has changed. void OnSelectToSpeakStateChanged(ash::SelectToSpeakState state); - // Invoked to enable or disable switch access. + // Invoked to enable or disable Switch Access. void SetSwitchAccessEnabled(bool enabled); - // Returns if switch access is enabled. + // Returns if Switch Access is enabled. bool IsSwitchAccessEnabled() const; // Returns true if a braille display is connected to the system, otherwise
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service_browsertest.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service_browsertest.cc index 72848d60..a9885694 100644 --- a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service_browsertest.cc +++ b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service_browsertest.cc
@@ -10,17 +10,15 @@ #include "base/bind.h" #include "base/json/json_writer.h" #include "base/macros.h" -#include "chrome/browser/chromeos/child_accounts/child_account_test_utils.h" #include "chrome/browser/chromeos/child_accounts/parent_access_code/config_source.h" #include "chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.h" #include "chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_test_utils.h" -#include "chrome/browser/chromeos/policy/login_policy_test_base.h" #include "chrome/browser/chromeos/policy/user_policy_test_helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/supervised_user/logged_in_user_mixin.h" +#include "chrome/test/base/mixin_based_in_process_browser_test.h" #include "components/account_id/account_id.h" -#include "components/policy/core/browser/browser_policy_connector.h" -#include "components/policy/policy_constants.h" #include "components/prefs/pref_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -82,66 +80,52 @@ DISALLOW_COPY_AND_ASSIGN(TestParentAccessServiceObserver); }; -class ParentAccessServiceTest : public policy::LoginPolicyTestBase { +class ParentAccessServiceTest : public MixinBasedInProcessBrowserTest { public: ParentAccessServiceTest() - : test_observer_( - std::make_unique<TestParentAccessServiceObserver>(child_)) {} + : test_observer_(std::make_unique<TestParentAccessServiceObserver>( + logged_in_user_mixin_.GetAccountId())) {} ~ParentAccessServiceTest() override = default; - void SetUp() override { - // Recognize example.com (used by LoginPolicyTestBase) as non-enterprise - // account. - policy::BrowserPolicyConnector::SetNonEnterpriseDomainForTesting( - "example.com"); - - policy::LoginPolicyTestBase::SetUp(); - } - void SetUpOnMainThread() override { ASSERT_NO_FATAL_FAILURE(GetTestAccessCodeValues(&test_values_)); ParentAccessService::Get().AddObserver(test_observer_.get()); - policy::LoginPolicyTestBase::SetUpOnMainThread(); + MixinBasedInProcessBrowserTest::SetUpOnMainThread(); + logged_in_user_mixin_.SetUpOnMainThreadHelper(host_resolver(), this); } void TearDownOnMainThread() override { ParentAccessService::Get().RemoveObserver(test_observer_.get()); - policy::LoginPolicyTestBase::TearDownOnMainThread(); - } - - std::string GetIdToken() const override { - return test::GetChildAccountOAuthIdToken(); + MixinBasedInProcessBrowserTest::TearDownOnMainThread(); } protected: - void LogInChild() { - SkipToLoginScreen(); - LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); - } - // Updates the policy containing the Parent Access Code config. void UpdatePolicy(const base::DictionaryValue& dict) { + std::string config_string; + base::JSONWriter::Write(dict, &config_string); + + logged_in_user_mixin_.GetUserPolicyMixin() + ->RequestPolicyUpdate() + ->policy_payload() + ->mutable_parentaccesscodeconfig() + ->set_value(config_string); + const user_manager::UserManager* const user_manager = user_manager::UserManager::Get(); EXPECT_TRUE(user_manager->GetActiveUser()->IsChild()); Profile* child_profile = ProfileHelper::Get()->GetProfileByUser(user_manager->GetActiveUser()); - std::string config_string; - base::JSONWriter::Write(dict, &config_string); - - base::DictionaryValue policy; - policy.SetKey(policy::key::kParentAccessCodeConfig, - base::Value(config_string)); - user_policy_helper()->SetPolicyAndWait( - std::move(policy), base::DictionaryValue(), child_profile); + logged_in_user_mixin_.GetUserPolicyTestHelper()->RefreshPolicyAndWait( + child_profile); } // Performs |code| validation on ParentAccessService singleton using the // |validation time| and returns the result. bool ValidateAccessCode(const std::string& code, base::Time validation_time) { - return ParentAccessService::Get().ValidateParentAccessCode(child_, code, - validation_time); + return ParentAccessService::Get().ValidateParentAccessCode( + logged_in_user_mixin_.GetAccountId(), code, validation_time); } // Checks if ParentAccessServiceObserver and ValidateParentAccessCodeCallback @@ -152,8 +136,11 @@ EXPECT_EQ(failure_count, test_observer_->validation_results_.failure_count); } - const AccountId child_ = AccountId::FromUserEmail(kAccountId); AccessCodeValues test_values_; + chromeos::LoggedInUserMixin logged_in_user_mixin_{ + &mixin_host_, LoggedInUserMixin::LogInType::kChild, + embedded_test_server(), true /*should_launch_browser*/, + base::nullopt, false /*include_initial_user*/}; std::unique_ptr<TestParentAccessServiceObserver> test_observer_; private: @@ -161,8 +148,6 @@ }; IN_PROC_BROWSER_TEST_F(ParentAccessServiceTest, NoConfigAvailable) { - LogInChild(); - auto test_value = test_values_.begin(); EXPECT_FALSE(ValidateAccessCode(test_value->second, test_value->first)); @@ -170,8 +155,6 @@ } IN_PROC_BROWSER_TEST_F(ParentAccessServiceTest, NoValidConfigAvailable) { - LogInChild(); - std::vector<AccessCodeConfig> old_configs; old_configs.emplace_back(GetInvalidTestConfig()); UpdatePolicy(PolicyFromConfigs(GetInvalidTestConfig(), GetInvalidTestConfig(), @@ -184,8 +167,6 @@ } IN_PROC_BROWSER_TEST_F(ParentAccessServiceTest, ValidationWithFutureConfig) { - LogInChild(); - std::vector<AccessCodeConfig> old_configs; old_configs.emplace_back(GetInvalidTestConfig()); UpdatePolicy(PolicyFromConfigs(GetDefaultTestConfig(), GetInvalidTestConfig(), @@ -198,8 +179,6 @@ } IN_PROC_BROWSER_TEST_F(ParentAccessServiceTest, ValidationWithCurrentConfig) { - LogInChild(); - std::vector<AccessCodeConfig> old_configs; old_configs.emplace_back(GetInvalidTestConfig()); UpdatePolicy(PolicyFromConfigs(GetInvalidTestConfig(), GetDefaultTestConfig(), @@ -212,8 +191,6 @@ } IN_PROC_BROWSER_TEST_F(ParentAccessServiceTest, ValidationWithOldConfig) { - LogInChild(); - std::vector<AccessCodeConfig> old_configs; old_configs.emplace_back(GetInvalidTestConfig()); old_configs.emplace_back(GetDefaultTestConfig()); @@ -227,8 +204,6 @@ } IN_PROC_BROWSER_TEST_F(ParentAccessServiceTest, MultipleValidationAttempts) { - LogInChild(); - AccessCodeValues::iterator test_value = test_values_.begin(); // No config - validation should fail. @@ -251,8 +226,6 @@ } IN_PROC_BROWSER_TEST_F(ParentAccessServiceTest, NoObserver) { - LogInChild(); - ParentAccessService::Get().RemoveObserver(test_observer_.get()); UpdatePolicy( @@ -265,8 +238,6 @@ } IN_PROC_BROWSER_TEST_F(ParentAccessServiceTest, NoAccountId) { - LogInChild(); - ParentAccessService::Get().RemoveObserver(test_observer_.get()); UpdatePolicy( @@ -279,8 +250,6 @@ } IN_PROC_BROWSER_TEST_F(ParentAccessServiceTest, InvalidAccountId) { - LogInChild(); - ParentAccessService::Get().RemoveObserver(test_observer_.get()); UpdatePolicy(
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index b723aad..2bc4f68 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -577,6 +577,11 @@ // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun() // -- immediately before Profile creation(). + // PreProfileInit() is not always called if no browser process is started + // (e.g. during some browser tests). Set a boolean so that we do not try to + // destroy singletons that are initialized here. + pre_profile_init_called_ = true; + // Now that the file thread exists we can record our stats. BootTimesRecorder::Get()->RecordChromeMainStats(); LoginEventRecorder::Get()->SetDelegate(BootTimesRecorder::Get()); @@ -954,6 +959,10 @@ } // Shut down services before the browser process, etc are destroyed. +// NOTE: This may get called without PreProfileInit() (or other +// PreMainMessageLoopRun sub-stages) getting called, so be careful with +// shutdown calls and test |pre_profile_init_called_| if necessary. See +// crbug.com/702403 for details. void ChromeBrowserMainPartsChromeos::PostMainMessageLoopRun() { crostini_unsupported_action_notifier_.reset(); @@ -965,7 +974,8 @@ lock_screen_apps_state_controller_->Shutdown(); // This must be shut down before |arc_service_launcher_|. - NoteTakingHelper::Shutdown(); + if (pre_profile_init_called_) + NoteTakingHelper::Shutdown(); arc_service_launcher_->Shutdown(); @@ -979,7 +989,8 @@ shutdown_policy_forwarder_.reset(); // Destroy the application name notifier for Kiosk mode. - KioskModeIdleAppNameNotification::Shutdown(); + if (pre_profile_init_called_) + KioskModeIdleAppNameNotification::Shutdown(); // Shutdown the upgrade detector for Chrome OS. The upgrade detector // stops monitoring changes from the update engine. @@ -1003,7 +1014,8 @@ wake_on_wifi_manager_.reset(); fast_transition_observer_.reset(); network_throttling_observer_.reset(); - ScreenLocker::ShutDownClass(); + if (pre_profile_init_called_) + ScreenLocker::ShutDownClass(); low_disk_notification_.reset(); demo_mode_resources_remover_.reset(); adaptive_screen_brightness_manager_.reset(); @@ -1021,10 +1033,10 @@ if (LoginScreenExtensionUiHandler::Get(false /*can_create*/)) LoginScreenExtensionUiHandler::Shutdown(); - MagnificationManager::Shutdown(); - - audio::SoundsManager::Shutdown(); - + if (pre_profile_init_called_) { + MagnificationManager::Shutdown(); + audio::SoundsManager::Shutdown(); + } system::StatisticsProvider::GetInstance()->Shutdown(); DemoSession::ShutDownIfInitialized(); @@ -1035,10 +1047,14 @@ if (NetworkCertLoader::IsInitialized()) NetworkCertLoader::Get()->set_is_shutting_down(); + CHECK(g_browser_process); + CHECK(g_browser_process->platform_part()); + // Let the UserManager unregister itself as an observer of the CrosSettings // singleton before it is destroyed. This also ensures that the UserManager // has no URLRequest pending (see http://crbug.com/276659). - g_browser_process->platform_part()->user_manager()->Shutdown(); + if (g_browser_process->platform_part()->user_manager()) + g_browser_process->platform_part()->user_manager()->Shutdown(); // Let the DeviceDisablingManager unregister itself as an observer of the // CrosSettings singleton before it is destroyed. @@ -1052,7 +1068,8 @@ KioskAppManager::Shutdown(); // Make sure that there is no pending URLRequests. - UserSessionManager::GetInstance()->Shutdown(); + if (pre_profile_init_called_) + UserSessionManager::GetInstance()->Shutdown(); // Give BrowserPolicyConnectorChromeOS a chance to unregister any observers // on services that are going to be deleted later but before its Shutdown() @@ -1063,15 +1080,19 @@ // Shutdown the virtual keyboard UI before destroying ash::Shell or the // primary profile. - chrome_keyboard_controller_client_->Shutdown(); + if (chrome_keyboard_controller_client_) + chrome_keyboard_controller_client_->Shutdown(); // Must occur before BrowserProcessImpl::StartTearDown() destroys the // ProfileManager. - Profile* primary_user = ProfileManager::GetPrimaryUserProfile(); - if (primary_user) { - // See startup_settings_cache::ReadAppLocale() comment for why we do this. - startup_settings_cache::WriteAppLocale(primary_user->GetPrefs()->GetString( - language::prefs::kApplicationLocale)); + if (pre_profile_init_called_) { + Profile* primary_user = ProfileManager::GetPrimaryUserProfile(); + if (primary_user) { + // See startup_settings_cache::ReadAppLocale() comment for why we do this. + startup_settings_cache::WriteAppLocale( + primary_user->GetPrefs()->GetString( + language::prefs::kApplicationLocale)); + } } // Cleans up dbus services depending on ash. @@ -1092,9 +1113,10 @@ // |arc_service_launcher_| uses |scheduler_configuration_manager_|. scheduler_configuration_manager_.reset(); - AccessibilityManager::Shutdown(); - - input_method::Shutdown(); + if (pre_profile_init_called_) { + AccessibilityManager::Shutdown(); + input_method::Shutdown(); + } // Stops all in-flight OAuth2 token fetchers before the IO thread stops. DeviceOAuth2TokenServiceFactory::Shutdown(); @@ -1106,11 +1128,11 @@ quirks::QuirksManager::Shutdown(); - // Called after - // ChromeBrowserMainPartsLinux::PostMainMessageLoopRun() to be - // executed after execution of chrome::CloseAsh(), because some - // parts of WebUI depends on NetworkPortalDetector. - network_portal_detector::Shutdown(); + // Called after ChromeBrowserMainPartsLinux::PostMainMessageLoopRun() (which + // calls chrome::CloseAsh()) because some parts of WebUI depend on + // NetworkPortalDetector. + if (pre_profile_init_called_) + network_portal_detector::Shutdown(); g_browser_process->platform_part()->ShutdownSessionManager(); // Ash needs to be closed before UserManager is destroyed.
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h index 26e8a04..6e20fc02 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -174,6 +174,12 @@ dark_resume_controller_; std::unique_ptr<SessionTerminationManager> session_termination_manager_; + + // Set when PreProfileInit() is called. If PreMainMessageLoopRun() exits + // early, this will be false during PostMainMessageLoopRun(), etc. + // Used to prevent shutting down classes that were not initialized. + bool pre_profile_init_called_ = false; + std::unique_ptr<policy::LockToSingleUserManager> lock_to_single_user_manager_; std::unique_ptr<WilcoDtcSupportdManager> wilco_dtc_supportd_manager_; std::unique_ptr<LoginScreenExtensionsLifetimeManager>
diff --git a/chrome/browser/chromeos/extensions/info_private_api.cc b/chrome/browser/chromeos/extensions/info_private_api.cc index 0aaf258a..421770c73 100644 --- a/chrome/browser/chromeos/extensions/info_private_api.cc +++ b/chrome/browser/chromeos/extensions/info_private_api.cc
@@ -110,7 +110,7 @@ // Key which corresponds to the select-to-speak A11Y property in JS. const char kPropertySelectToSpeakEnabled[] = "a11ySelectToSpeakEnabled"; -// Key which corresponds to the switch access A11Y property in JS. +// Key which corresponds to the Switch Access A11Y property in JS. const char kPropertySwitchAccessEnabled[] = "a11ySwitchAccessEnabled"; // Key which corresponds to the send-function-keys property in JS.
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc index d09bc4b1..5c3ae6b0 100644 --- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc +++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -1616,7 +1616,7 @@ ShowSAMLInterstitial(); test::OobeJS().ExpectHiddenPath({"gaia-signin", "signin-frame-dialog"}); test::OobeJS().ExpectHiddenPath({"gaia-signin", "offline-gaia"}); - test::OobeJS().ExpectVisiblePath({"gaia-signin", "saml-interstitial"}); + test::OobeJS().ExpectVisiblePath({"gaia-signin", "gaia-step-contents"}); // Click the "change account" link on the SAML interstitial page. ClickChangeAccountOnSAMLInterstitialPage(); @@ -1626,7 +1626,7 @@ test::OobeJS().ExpectHasClass("non-transparent", {"gaia-signin", "signin-frame-container"}); test::OobeJS().ExpectHiddenPath({"gaia-signin", "offline-gaia"}); - test::OobeJS().ExpectHiddenPath({"gaia-signin", "saml-interstitial"}); + test::OobeJS().ExpectHiddenPath({"gaia-signin", "gaia-step-contents"}); } // Tests that clicking "Next" in the SAML interstitial page successfully
diff --git a/chrome/browser/chromeos/policy/user_policy_test_helper.cc b/chrome/browser/chromeos/policy/user_policy_test_helper.cc index da5eb108..8cf25b9 100644 --- a/chrome/browser/chromeos/policy/user_policy_test_helper.cc +++ b/chrome/browser/chromeos/policy/user_policy_test_helper.cc
@@ -75,7 +75,10 @@ const base::Value& recommended_policy, Profile* profile) { SetPolicy(mandatory_policy, recommended_policy); + RefreshPolicyAndWait(profile); +} +void UserPolicyTestHelper::RefreshPolicyAndWait(Profile* profile) { policy::ProfilePolicyConnector* const profile_connector = profile->GetProfilePolicyConnector(); policy::PolicyService* const policy_service =
diff --git a/chrome/browser/chromeos/policy/user_policy_test_helper.h b/chrome/browser/chromeos/policy/user_policy_test_helper.h index 2d7ec1b8..bcb60bfd 100644 --- a/chrome/browser/chromeos/policy/user_policy_test_helper.h +++ b/chrome/browser/chromeos/policy/user_policy_test_helper.h
@@ -39,12 +39,15 @@ // unnecessary to call this function. void WaitForInitialPolicy(Profile* profile); - // Update the policy test server with the given policy. Then refresh and wait - // for the new policy being applied to |profile|. + // Updates the policy test server with the given policy. Then calls + // RefreshPolicyAndWait(). void SetPolicyAndWait(const base::Value& mandatory_policy, const base::Value& recommended_policy, Profile* profile); + // Refreshes and waits for the new policy being applied to |profile|. + void RefreshPolicyAndWait(Profile* profile); + private: const std::string account_id_; chromeos::LocalPolicyTestServerMixin* local_policy_server_;
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc index 2eb864f..1175730 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
@@ -361,9 +361,9 @@ } std::vector<std::string> ids{printer_ids.begin(), printer_ids.end()}; - cups_wrapper_.QueryCups(ids, - base::BindOnce(&CupsPrintJobManagerImpl::UpdateJobs, - weak_ptr_factory_.GetWeakPtr())); + cups_wrapper_.QueryCupsPrintJobs( + ids, base::BindOnce(&CupsPrintJobManagerImpl::UpdateJobs, + weak_ptr_factory_.GetWeakPtr())); } // Process jobs from CUPS and perform notifications.
diff --git a/chrome/browser/chromeos/printing/cups_wrapper.cc b/chrome/browser/chromeos/printing/cups_wrapper.cc index 78dc3ab..d3f9128 100644 --- a/chrome/browser/chromeos/printing/cups_wrapper.cc +++ b/chrome/browser/chromeos/printing/cups_wrapper.cc
@@ -27,11 +27,14 @@ Backend& operator=(const Backend&) = delete; ~Backend(); - std::unique_ptr<QueryResult> QueryCups( + std::unique_ptr<QueryResult> QueryCupsPrintJobs( const std::vector<std::string>& printer_ids); void CancelJob(const std::string& printer_id, int job_id); + std::unique_ptr<::printing::PrinterStatus> QueryCupsPrinterStatus( + const std::string& printer_id); + private: ::printing::CupsConnection cups_connection_; @@ -47,7 +50,8 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } -std::unique_ptr<CupsWrapper::QueryResult> CupsWrapper::Backend::QueryCups( +std::unique_ptr<CupsWrapper::QueryResult> +CupsWrapper::Backend::QueryCupsPrintJobs( const std::vector<std::string>& printer_ids) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto result = std::make_unique<CupsWrapper::QueryResult>(); @@ -76,6 +80,17 @@ } } +std::unique_ptr<::printing::PrinterStatus> +CupsWrapper::Backend::QueryCupsPrinterStatus(const std::string& printer_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto result = std::make_unique<::printing::PrinterStatus>(); + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + if (!cups_connection_.GetPrinterStatus(printer_id, result.get())) + return nullptr; + return result; +} + CupsWrapper::CupsWrapper() : backend_(std::make_unique<Backend>()), backend_task_runner_(base::CreateSequencedTaskRunner( @@ -88,7 +103,7 @@ backend_task_runner_->DeleteSoon(FROM_HERE, backend_.release()); } -void CupsWrapper::QueryCups( +void CupsWrapper::QueryCupsPrintJobs( const std::vector<std::string>& printer_ids, base::OnceCallback<void(std::unique_ptr<CupsWrapper::QueryResult>)> callback) { @@ -97,8 +112,8 @@ // the same task runner. base::PostTaskAndReplyWithResult( backend_task_runner_.get(), FROM_HERE, - base::BindOnce(&Backend::QueryCups, base::Unretained(backend_.get()), - printer_ids), + base::BindOnce(&Backend::QueryCupsPrintJobs, + base::Unretained(backend_.get()), printer_ids), std::move(callback)); } @@ -112,4 +127,18 @@ printer_id, job_id)); } +void CupsWrapper::QueryCupsPrinterStatus( + const std::string& printer_id, + base::OnceCallback<void(std::unique_ptr<::printing::PrinterStatus>)> + callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // It's safe to pass unretained pointer here because we delete |backend_| on + // the same task runner. + base::PostTaskAndReplyWithResult( + backend_task_runner_.get(), FROM_HERE, + base::BindOnce(&Backend::QueryCupsPrinterStatus, + base::Unretained(backend_.get()), printer_id), + std::move(callback)); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/cups_wrapper.h b/chrome/browser/chromeos/printing/cups_wrapper.h index 2a58187..c23e57d 100644 --- a/chrome/browser/chromeos/printing/cups_wrapper.h +++ b/chrome/browser/chromeos/printing/cups_wrapper.h
@@ -39,13 +39,20 @@ // Queries CUPS for the current jobs for the given |printer_ids|. Passes // the result to |callback|. - void QueryCups( + void QueryCupsPrintJobs( const std::vector<std::string>& printer_ids, base::OnceCallback<void(std::unique_ptr<QueryResult>)> callback); // Cancels the print job on the blocking thread. void CancelJob(const std::string& printer_id, int job_id); + // Queries CUPS for the printer status for the given |printer_id|. Passes the + // result to |callback|. + void QueryCupsPrinterStatus( + const std::string& printer_id, + base::OnceCallback<void(std::unique_ptr<::printing::PrinterStatus>)> + callback); + private: class Backend; // The |backend_| handles all communication with CUPS.
diff --git a/chrome/browser/chromeos/printing/printers_map.cc b/chrome/browser/chromeos/printing/printers_map.cc index d63a389..f0e44a2 100644 --- a/chrome/browser/chromeos/printing/printers_map.cc +++ b/chrome/browser/chromeos/printing/printers_map.cc
@@ -11,7 +11,8 @@ bool IsProtocolSecure(const Printer& printer) { return !printer.HasNetworkProtocol() || - printer.GetProtocol() == Printer::kIpps; + printer.GetProtocol() == Printer::kIpps || + printer.GetProtocol() == Printer::kHttps; } } // namespace
diff --git a/chrome/browser/chromeos/printing/printers_map_unittest.cc b/chrome/browser/chromeos/printing/printers_map_unittest.cc index 1d6d46b..04bffc5 100644 --- a/chrome/browser/chromeos/printing/printers_map_unittest.cc +++ b/chrome/browser/chromeos/printing/printers_map_unittest.cc
@@ -184,14 +184,19 @@ http_printer.set_uri("http:printer"); printers_map.Insert(PrinterClass::kDiscovered, http_printer); - // Only IPPS, IPPUSB, and USB printers are returned. + Printer https_printer = Printer("https"); + https_printer.set_uri("https://printer"); + printers_map.Insert(PrinterClass::kDiscovered, https_printer); + + // Only HTTPS, IPPS, IPPUSB, and USB printers are returned. auto printers = printers_map.GetSecurePrinters(); - EXPECT_EQ(3u, printers.size()); + EXPECT_EQ(4u, printers.size()); EXPECT_TRUE(IsPrinterInPrinters(printers, ipps_printer)); EXPECT_TRUE(IsPrinterInPrinters(printers, usb_printer)); EXPECT_TRUE(IsPrinterInPrinters(printers, ippusb_printer)); + EXPECT_TRUE(IsPrinterInPrinters(printers, https_printer)); EXPECT_FALSE(IsPrinterInPrinters(printers, ipp_printer)); EXPECT_FALSE(IsPrinterInPrinters(printers, http_printer));
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc index 4fad139..2db0583 100644 --- a/chrome/browser/client_hints/client_hints_browsertest.cc +++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/run_loop.h" #include "base/stl_util.h" #include "base/strings/string_util.h" +#include "base/synchronization/lock.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_entropy_provider.h" #include "build/build_config.h" @@ -405,10 +406,12 @@ const GURL& redirect_url() const { return redirect_url_; } size_t count_user_agent_hint_headers_seen() const { + base::AutoLock lock(count_headers_lock_); return count_user_agent_hint_headers_seen_; } size_t count_client_hints_headers_seen() const { + base::AutoLock lock(count_headers_lock_); return count_client_hints_headers_seen_; } @@ -429,6 +432,7 @@ std::string intercept_iframe_resource_; bool intercept_to_http_equiv_iframe_ = false; + mutable base::Lock count_headers_lock_; private: // Intercepts only the main frame requests that contain @@ -584,6 +588,7 @@ for (size_t i = 0; i < blink::kClientHintsMappingsCount; ++i) { if (base::Contains(request.headers, blink::kClientHintsHeaderMapping[i])) { + base::AutoLock lock(count_headers_lock_); // The user agent hint is special: if (std::string(blink::kClientHintsHeaderMapping[i]) == "sec-ch-ua") { count_user_agent_hint_headers_seen_++;
diff --git a/chrome/browser/extensions/external_provider_impl_unittest.cc b/chrome/browser/extensions/external_provider_impl_unittest.cc index bbd2f29..c53d5db 100644 --- a/chrome/browser/extensions/external_provider_impl_unittest.cc +++ b/chrome/browser/extensions/external_provider_impl_unittest.cc
@@ -139,6 +139,7 @@ int(sizeof(prefs))); InitializeExtensionService(params); service_->updater()->Start(); + content::RunAllTasksUntilIdle(); } // ExtensionServiceTestBase overrides:
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index fcff95f..7f035fa 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -49,6 +49,11 @@ "expiry_milestone": 82 }, { + "name": "allow-ambient-eq", + "owners": [ "zentaro", "baileyberro" ], + "expiry_milestone": 85 + }, + { "name": "allow-disable-mouse-acceleration", "owners": [ "zentaro" ], "expiry_milestone": 82 @@ -2175,7 +2180,7 @@ { "name": "explore-sites", "owners": [ "chili", "dewittj" ], - "expiry_milestone": 83 + "expiry_milestone": 85 }, { "name": "extension-apis",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index e73feb8..cdab5f7c 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3169,6 +3169,10 @@ "Use the aggregated ML model to rank the non-app search results for " "non-empty queries."; +const char kAllowAmbientEQName[] = "Show Ambient EQ UI"; +const char kAllowAmbientEQDescription[] = + "Shows the UI to enable Ambient EQ on devices that support it."; + const char kAllowDisableMouseAccelerationName[] = "Allow disabling mouse acceleration"; const char kAllowDisableMouseAccelerationDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index c2d0d3bf..465843f 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1867,6 +1867,9 @@ extern const char kAggregatedMlSearchRankingName[]; extern const char kAggregatedMlSearchRankingDescription[]; +extern const char kAllowAmbientEQName[]; +extern const char kAllowAmbientEQDescription[]; + extern const char kAllowDisableMouseAccelerationName[]; extern const char kAllowDisableMouseAccelerationDescription[];
diff --git a/chrome/browser/lookalikes/lookalike_url_interstitial_page.cc b/chrome/browser/lookalikes/lookalike_url_interstitial_page.cc index 758d3a00b..f9efcdca 100644 --- a/chrome/browser/lookalikes/lookalike_url_interstitial_page.cc +++ b/chrome/browser/lookalikes/lookalike_url_interstitial_page.cc
@@ -90,8 +90,8 @@ const base::string16 hostname = security_interstitials::common_string_util::GetFormattedHostName( request_url()); - load_time_data->SetString("tabTitle", - l10n_util::GetStringUTF16(IDS_LOOKALIKE_URL_TITLE)); + load_time_data->SetString("tabTitle", l10n_util::GetStringFUTF16( + IDS_LOOKALIKE_URL_TITLE, hostname)); load_time_data->SetString( "heading", l10n_util::GetStringFUTF16(IDS_LOOKALIKE_URL_HEADING, hostname));
diff --git a/chrome/browser/media/router/media_router_metrics.h b/chrome/browser/media/router/media_router_metrics.h index 33292146..96fbfa2 100644 --- a/chrome/browser/media/router/media_router_metrics.h +++ b/chrome/browser/media/router/media_router_metrics.h
@@ -22,7 +22,7 @@ // NOTE: Do not renumber enums as that would confuse interpretation of // previously logged data. When making changes, also update the enum list -// in tools/metrics/histograms/histograms.xml to keep it in sync. +// in tools/metrics/histograms/enums.xml to keep it in sync. // NOTE: For metrics specific to the Media Router component extension, see // mojo/media_router_mojo_metrics.h. @@ -33,9 +33,10 @@ OVERFLOW_MENU = 1, CONTEXTUAL_MENU = 2, PAGE = 3, + APP_MENU = 4, // NOTE: Add entries only immediately above this line. - TOTAL_COUNT = 4 + TOTAL_COUNT = 5 }; // The possible outcomes from a route creation response.
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 2ce64c8..71b06f1a 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -584,24 +584,30 @@ // Always enable the HTTP cache. network_context_params->http_cache_enabled = true; + network_context_params->http_auth_static_network_context_params = + network::mojom::HttpAuthStaticNetworkContextParams::New(); + // Allow/disallow ambient authentication with default credentials based on the // profile type. // TODO(https://crbug.com/458508): Allow this behavior to be controllable by // policy. if (profile_->IsGuestSession()) { - network_context_params->allow_default_credentials = + network_context_params->http_auth_static_network_context_params + ->allow_default_credentials = base::FeatureList::IsEnabled( features::kEnableAmbientAuthenticationInGuestSession) ? net::HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS : net::HttpAuthPreferences::DISALLOW_DEFAULT_CREDENTIALS; } else if (profile_->IsIncognitoProfile()) { - network_context_params->allow_default_credentials = + network_context_params->http_auth_static_network_context_params + ->allow_default_credentials = base::FeatureList::IsEnabled( features::kEnableAmbientAuthenticationInIncognito) ? net::HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS : net::HttpAuthPreferences::DISALLOW_DEFAULT_CREDENTIALS; } else { - network_context_params->allow_default_credentials = + network_context_params->http_auth_static_network_context_params + ->allow_default_credentials = net::HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS; }
diff --git a/chrome/browser/net/profile_network_context_service.h b/chrome/browser/net/profile_network_context_service.h index 96a96b1..f634382 100644 --- a/chrome/browser/net/profile_network_context_service.h +++ b/chrome/browser/net/profile_network_context_service.h
@@ -94,6 +94,8 @@ ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest, Test); + friend class AmbientAuthenticationTest; + // Checks |quic_allowed_|, and disables QUIC if needed. void DisableQuicIfNotAllowed();
diff --git a/chrome/browser/net/profile_network_context_service_browsertest.cc b/chrome/browser/net/profile_network_context_service_browsertest.cc index 0aee056..6270cafd 100644 --- a/chrome/browser/net/profile_network_context_service_browsertest.cc +++ b/chrome/browser/net/profile_network_context_service_browsertest.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths_internal.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" @@ -37,6 +38,7 @@ #include "content/public/test/simple_url_loader_test_helper.h" #include "mojo/public/cpp/system/data_pipe_utils.h" #include "net/base/load_flags.h" +#include "net/http/http_auth_preferences.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" @@ -152,6 +154,64 @@ EXPECT_TRUE(base::Contains(encodings, "br")); } +enum class AmbientAuthenticationStateIncognito { ENABLED, DISABLED }; + +class AmbientAuthenticationTest : public InProcessBrowserTest { + public: + explicit AmbientAuthenticationTest( + AmbientAuthenticationStateIncognito state = + AmbientAuthenticationStateIncognito::ENABLED) { + scoped_feature_list_.InitWithFeatureState( + features::kEnableAmbientAuthenticationInIncognito, + state == AmbientAuthenticationStateIncognito::ENABLED); + } + + Profile* GetOffTheRecordProfile() { + Profile* regular_profile = browser()->profile(); + Profile* off_the_record_profile = regular_profile->GetOffTheRecordProfile(); + EXPECT_TRUE(regular_profile->HasOffTheRecordProfile()); + return off_the_record_profile; + } + + bool IsAmbientAuthAllowedForProfile(Profile* profile) { + ProfileNetworkContextService* profile_network_context_service = + ProfileNetworkContextServiceFactory::GetForContext(profile); + base::FilePath empty_relative_partition_path; + network::mojom::NetworkContextParamsPtr network_context_params_ptr = + profile_network_context_service->CreateNetworkContextParams( + /*in_memory=*/false, empty_relative_partition_path); + return network_context_params_ptr->http_auth_static_network_context_params + ->allow_default_credentials == + net::HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS; + } + + protected: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +class AmbientAuthenticationTestDisabled : public AmbientAuthenticationTest { + public: + explicit AmbientAuthenticationTestDisabled() + : AmbientAuthenticationTest( + AmbientAuthenticationStateIncognito::DISABLED) {} +}; + +IN_PROC_BROWSER_TEST_F(AmbientAuthenticationTest, + AllowDefaultCredentialsRegular) { + EXPECT_TRUE(IsAmbientAuthAllowedForProfile(browser()->profile())); +} + +IN_PROC_BROWSER_TEST_F(AmbientAuthenticationTest, + AllowDefaultCredentialsIncognito) { + EXPECT_TRUE(IsAmbientAuthAllowedForProfile(GetOffTheRecordProfile())); +} + +IN_PROC_BROWSER_TEST_F(AmbientAuthenticationTestDisabled, + DisallowDefaultCredentialsIncognito) { + EXPECT_TRUE(IsAmbientAuthAllowedForProfile(browser()->profile())); + EXPECT_FALSE(IsAmbientAuthAllowedForProfile(GetOffTheRecordProfile())); +} + // Test subclass that adds switches::kDiskCacheDir and switches::kDiskCacheSize // to the command line, to make sure they're respected. class ProfileNetworkContextServiceDiskCacheBrowsertest
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc b/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc index 517b626..54b3b91 100644 --- a/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc +++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc
@@ -105,21 +105,6 @@ return true; } -// Returns the OptimizationGuideNavigationData for |navigation_handle| if the -// OptimizationGuideWebContentsObserver is registered. -OptimizationGuideNavigationData* GetNavigationDataForNavigationHandle( - content::NavigationHandle* navigation_handle) { - OptimizationGuideWebContentsObserver* - optimization_guide_web_contents_observer = - OptimizationGuideWebContentsObserver::FromWebContents( - navigation_handle->GetWebContents()); - if (!optimization_guide_web_contents_observer) - return nullptr; - - return optimization_guide_web_contents_observer - ->GetOrCreateOptimizationGuideNavigationData(navigation_handle); -} - // Returns the page hint for the navigation, if applicable. It will use the // cached page hint stored in |navigation_handle| if we have already done the // computation to find the page hint in a previous request to the hints manager. @@ -129,7 +114,8 @@ content::NavigationHandle* navigation_handle, const optimization_guide::proto::Hint* loaded_hint) { OptimizationGuideNavigationData* navigation_data = - GetNavigationDataForNavigationHandle(navigation_handle); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle); // If we already know we had a page hint for the navigation, then just return // that. @@ -588,7 +574,8 @@ } OptimizationGuideNavigationData* navigation_data = - GetNavigationDataForNavigationHandle(navigation_handle); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle); if (navigation_data) { bool has_hint = hint_cache_->HasHint(url.host()); if (navigation_handle->HasCommitted()) { @@ -788,7 +775,8 @@ // Populate navigation data with hint information. OptimizationGuideNavigationData* navigation_data = - GetNavigationDataForNavigationHandle(navigation_handle); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle); if (navigation_data) { navigation_data->set_has_hint_after_commit(has_hint_in_cache);
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc b/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc index b0879e8..4a7780a 100644 --- a/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc +++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc
@@ -353,17 +353,6 @@ return navigation_handle; } - // Returns the optimization guide navigation data attached to - // |navigation_handle|. - OptimizationGuideNavigationData* GetOptimizationGuideNavigationData( - content::NavigationHandle* navigation_handle) { - OptimizationGuideWebContentsObserver* observer = - OptimizationGuideWebContentsObserver::FromWebContents( - navigation_handle->GetWebContents()); - return observer->GetOrCreateOptimizationGuideNavigationData( - navigation_handle); - } - OptimizationGuideHintsManager* hints_manager() const { return hints_manager_.get(); } @@ -737,7 +726,8 @@ true, 1); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); @@ -761,7 +751,8 @@ true, 1); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); EXPECT_TRUE(navigation_data->has_hint_before_commit().value()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_after_commit()); @@ -785,7 +776,8 @@ false, 1); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); EXPECT_FALSE(navigation_data->has_hint_before_commit().value()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_after_commit()); @@ -808,7 +800,8 @@ histogram_tester.ExpectTotalCount("OptimizationGuide.LoadedHint.Result", 0); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_after_commit()); @@ -1265,7 +1258,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_after_commit()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); @@ -1309,7 +1303,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_FALSE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); @@ -1356,7 +1351,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_FALSE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); @@ -1403,7 +1399,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_FALSE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); @@ -1450,7 +1447,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_FALSE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); @@ -1498,7 +1496,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_FALSE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); @@ -1542,7 +1541,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_TRUE(navigation_data->has_hint_before_commit().value()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ("someversion", navigation_data->serialized_hint_version_string()); @@ -1581,7 +1581,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_TRUE(navigation_data->has_hint_before_commit().value()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ("someversion", navigation_data->serialized_hint_version_string()); @@ -1621,7 +1622,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_TRUE(navigation_data->has_hint_before_commit().value()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ("someversion", navigation_data->serialized_hint_version_string()); @@ -1659,7 +1661,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_TRUE(navigation_data->has_hint_before_commit().value()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ("someversion", navigation_data->serialized_hint_version_string()); @@ -1698,7 +1701,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_TRUE(navigation_data->has_hint_before_commit().value()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ("someversion", navigation_data->serialized_hint_version_string()); @@ -1723,7 +1727,8 @@ // Purposely set the page hint to be null to show that we override the page // hint information from the navigation handle. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); navigation_data->set_page_hint(nullptr); optimization_guide::OptimizationTargetDecision optimization_target_decision; @@ -2050,7 +2055,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_TRUE(navigation_data->has_hint_before_commit().value()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ("someversion", navigation_data->serialized_hint_version_string()); @@ -2086,7 +2092,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_FALSE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); @@ -2121,7 +2128,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_EQ(base::nullopt, navigation_data->has_hint_before_commit()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ(base::nullopt, navigation_data->serialized_hint_version_string()); @@ -2184,7 +2192,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_TRUE(navigation_data->has_hint_before_commit().value()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ("someversion", navigation_data->serialized_hint_version_string()); @@ -2248,7 +2257,8 @@ optimization_type_decision); // Make sure navigation data is populated correctly. OptimizationGuideNavigationData* navigation_data = - GetOptimizationGuideNavigationData(navigation_handle.get()); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle.get()); EXPECT_TRUE(navigation_data->has_hint_before_commit().value()); EXPECT_TRUE(navigation_data->has_hint_after_commit().value()); EXPECT_EQ("someversion", navigation_data->serialized_hint_version_string());
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc index be6b6d7..4b02f36 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc
@@ -10,7 +10,6 @@ #include "chrome/browser/optimization_guide/optimization_guide_navigation_data.h" #include "chrome/browser/optimization_guide/optimization_guide_session_statistic.h" #include "chrome/browser/optimization_guide/optimization_guide_top_host_provider.h" -#include "chrome/browser/optimization_guide/optimization_guide_web_contents_observer.h" #include "chrome/browser/optimization_guide/prediction/prediction_manager.h" #include "chrome/browser/profiles/profile.h" #include "components/leveldb_proto/public/proto_database_provider.h" @@ -48,18 +47,13 @@ optimization_guide::proto::OptimizationTarget optimization_target, optimization_guide::OptimizationTargetDecision optimization_target_decision) { - OptimizationGuideWebContentsObserver* - optimization_guide_web_contents_observer = - OptimizationGuideWebContentsObserver::FromWebContents( - navigation_handle->GetWebContents()); - if (!optimization_guide_web_contents_observer) - return; - OptimizationGuideNavigationData* navigation_data = - optimization_guide_web_contents_observer - ->GetOrCreateOptimizationGuideNavigationData(navigation_handle); - navigation_data->SetDecisionForOptimizationTarget( - optimization_target, optimization_target_decision); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle); + if (navigation_data) { + navigation_data->SetDecisionForOptimizationTarget( + optimization_target, optimization_target_decision); + } } // Logs the |optimization_type_decision| for |optimization_type| in the current @@ -68,18 +62,13 @@ content::NavigationHandle* navigation_handle, optimization_guide::proto::OptimizationType optimization_type, optimization_guide::OptimizationTypeDecision optimization_type_decision) { - OptimizationGuideWebContentsObserver* - optimization_guide_web_contents_observer = - OptimizationGuideWebContentsObserver::FromWebContents( - navigation_handle->GetWebContents()); - if (!optimization_guide_web_contents_observer) - return; - OptimizationGuideNavigationData* navigation_data = - optimization_guide_web_contents_observer - ->GetOrCreateOptimizationGuideNavigationData(navigation_handle); - navigation_data->SetDecisionForOptimizationType(optimization_type, - optimization_type_decision); + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle); + if (navigation_data) { + navigation_data->SetDecisionForOptimizationType(optimization_type, + optimization_type_decision); + } } // Returns the OptimizationGuideDecision from |optimization_target_decision|. @@ -245,12 +234,6 @@ if (prediction_manager_) { optimization_target_decision = prediction_manager_->ShouldTargetNavigation( navigation_handle, optimization_target); - if (optimization_guide::features:: - ShouldOverrideOptimizationTargetDecisionForMetricsPurposes( - optimization_target)) { - optimization_target_decision = optimization_guide:: - OptimizationTargetDecision::kModelPredictionHoldback; - } } else { DCHECK(hints_manager_); optimization_guide::OptimizationTypeDecision
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc index 260da5f..20edad6 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc
@@ -817,57 +817,3 @@ kModelNotAvailableOnClient), 1); } - -class OptimizationGuideKeyedServiceModelPredictionHoldbackBrowserTest - : public OptimizationGuideKeyedServiceBrowserTest { - public: - OptimizationGuideKeyedServiceModelPredictionHoldbackBrowserTest() { - scoped_feature_list_.InitWithFeaturesAndParameters( - {base::test::ScopedFeatureList::FeatureAndParams( - optimization_guide::features::kOptimizationTargetPrediction, - {{"painful_page_load_metrics_only", "true"}}), - base::test::ScopedFeatureList::FeatureAndParams( - optimization_guide::features::kOptimizationHintsFetching, {{}})}, - {}); - } - ~OptimizationGuideKeyedServiceModelPredictionHoldbackBrowserTest() override = - default; - - void SetUpCommandLine(base::CommandLine* cmd) override { - cmd->AppendSwitchASCII(optimization_guide::switches::kFetchHintsOverride, - "whatever.com,somehost.com"); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -IN_PROC_BROWSER_TEST_F( - OptimizationGuideKeyedServiceModelPredictionHoldbackBrowserTest, - ModelPredictionHoldbackOverridesActualTargetDecision) { - PushHintsComponentAndWaitForCompletion(); - RegisterWithKeyedService(); - - ukm::TestAutoSetUkmRecorder ukm_recorder; - base::HistogramTester histogram_tester; - - ui_test_utils::NavigateToURL(browser(), url_with_hints()); - - EXPECT_EQ(RetryForHistogramUntilCountReached( - histogram_tester, "OptimizationGuide.LoadedHint.Result", 1), - 1); - // There should be a hint that matches this URL. - histogram_tester.ExpectUniqueSample("OptimizationGuide.LoadedHint.Result", - true, 1); - EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kFalse, - last_should_target_navigation_decision()); - EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kTrue, - last_can_apply_optimization_decision()); - EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kFalse, - last_consumer_decision()); - histogram_tester.ExpectUniqueSample( - "OptimizationGuide.TargetDecision.PainfulPageLoad", - static_cast<int>(optimization_guide::OptimizationTargetDecision:: - kModelPredictionHoldback), - 1); -}
diff --git a/chrome/browser/optimization_guide/optimization_guide_navigation_data.cc b/chrome/browser/optimization_guide/optimization_guide_navigation_data.cc index 9b87b906..7309989 100644 --- a/chrome/browser/optimization_guide/optimization_guide_navigation_data.cc +++ b/chrome/browser/optimization_guide/optimization_guide_navigation_data.cc
@@ -8,7 +8,9 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" +#include "chrome/browser/optimization_guide/optimization_guide_web_contents_observer.h" #include "components/optimization_guide/hints_processing_util.h" +#include "content/public/browser/navigation_handle.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "services/metrics/public/cpp/ukm_source.h" @@ -45,6 +47,10 @@ serialized_hint_version_string_(other.serialized_hint_version_string_), optimization_type_decisions_(other.optimization_type_decisions_), optimization_target_decisions_(other.optimization_target_decisions_), + optimization_target_model_versions_( + other.optimization_target_model_versions_), + optimization_target_model_prediction_scores_( + other.optimization_target_model_prediction_scores_), has_hint_before_commit_(other.has_hint_before_commit_), has_hint_after_commit_(other.has_hint_after_commit_), was_host_covered_by_fetch_at_navigation_start_( @@ -55,6 +61,20 @@ } } +// static +OptimizationGuideNavigationData* +OptimizationGuideNavigationData::GetFromNavigationHandle( + content::NavigationHandle* navigation_handle) { + OptimizationGuideWebContentsObserver* + optimization_guide_web_contents_observer = + OptimizationGuideWebContentsObserver::FromWebContents( + navigation_handle->GetWebContents()); + if (!optimization_guide_web_contents_observer) + return nullptr; + return optimization_guide_web_contents_observer + ->GetOrCreateOptimizationGuideNavigationData(navigation_handle); +} + void OptimizationGuideNavigationData::RecordMetrics(bool has_committed) const { RecordHintCacheMatch(has_committed); RecordOptimizationTypeAndTargetDecisions(); @@ -130,37 +150,54 @@ } void OptimizationGuideNavigationData::RecordOptimizationGuideUKM() const { - if (!serialized_hint_version_string_.has_value() || - serialized_hint_version_string_.value().empty()) - return; - - // Deserialize the serialized version string into its protobuffer. - std::string binary_version_pb; - if (!base::Base64Decode(serialized_hint_version_string_.value(), - &binary_version_pb)) - return; - - optimization_guide::proto::Version hint_version; - if (!hint_version.ParseFromString(binary_version_pb)) - return; - - // Record the UKM. + bool did_record_metric = false; ukm::SourceId ukm_source_id = ukm::ConvertToSourceId(navigation_id_, ukm::SourceIdType::NAVIGATION_ID); ukm::builders::OptimizationGuide builder(ukm_source_id); - bool did_record_metric = false; - if (hint_version.has_generation_timestamp() && - hint_version.generation_timestamp().seconds() > 0) { - did_record_metric = true; - builder.SetHintGenerationTimestamp( - hint_version.generation_timestamp().seconds()); + // Record model metrics. + for (const auto& optimization_target_model_version : + optimization_target_model_versions_) { + if (optimization_target_model_version.first == + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD) { + did_record_metric = true; + builder.SetPainfulPageLoadModelVersion( + optimization_target_model_version.second); + } } - if (hint_version.has_hint_source() && - hint_version.hint_source() != - optimization_guide::proto::HINT_SOURCE_UNKNOWN) { - did_record_metric = true; - builder.SetHintSource(static_cast<int>(hint_version.hint_source())); + for (const auto& optimization_target_model_prediction_score : + optimization_target_model_prediction_scores_) { + if (optimization_target_model_prediction_score.first == + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD) { + did_record_metric = true; + builder.SetPainfulPageLoadModelPredictionScore(static_cast<int64_t>( + 100 * optimization_target_model_prediction_score.second)); + } + } + + // Record hint metrics. + if (serialized_hint_version_string_.has_value() && + !serialized_hint_version_string_.value().empty()) { + // Deserialize the serialized version string into its protobuffer. + std::string binary_version_pb; + if (base::Base64Decode(serialized_hint_version_string_.value(), + &binary_version_pb)) { + optimization_guide::proto::Version hint_version; + if (hint_version.ParseFromString(binary_version_pb)) { + if (hint_version.has_generation_timestamp() && + hint_version.generation_timestamp().seconds() > 0) { + did_record_metric = true; + builder.SetHintGenerationTimestamp( + hint_version.generation_timestamp().seconds()); + } + if (hint_version.has_hint_source() && + hint_version.hint_source() != + optimization_guide::proto::HINT_SOURCE_UNKNOWN) { + did_record_metric = true; + builder.SetHintSource(static_cast<int>(hint_version.hint_source())); + } + } + } } // Only record UKM if a metric was recorded. @@ -199,3 +236,39 @@ optimization_guide::OptimizationTargetDecision decision) { optimization_target_decisions_[optimization_target] = decision; } + +base::Optional<int64_t> +OptimizationGuideNavigationData::GetModelVersionForOptimizationTarget( + optimization_guide::proto::OptimizationTarget optimization_target) const { + auto optimization_target_model_version_iter = + optimization_target_model_versions_.find(optimization_target); + if (optimization_target_model_version_iter == + optimization_target_model_versions_.end()) + return base::nullopt; + return optimization_target_model_version_iter->second; +} + +void OptimizationGuideNavigationData::SetModelVersionForOptimizationTarget( + optimization_guide::proto::OptimizationTarget optimization_target, + int64_t model_version) { + optimization_target_model_versions_[optimization_target] = model_version; +} + +base::Optional<double> +OptimizationGuideNavigationData::GetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OptimizationTarget optimization_target) const { + auto optimization_target_model_prediction_score_iter = + optimization_target_model_prediction_scores_.find(optimization_target); + if (optimization_target_model_prediction_score_iter == + optimization_target_model_prediction_scores_.end()) + return base::nullopt; + return optimization_target_model_prediction_score_iter->second; +} + +void OptimizationGuideNavigationData:: + SetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OptimizationTarget optimization_target, + double model_prediction_score) { + optimization_target_model_prediction_scores_[optimization_target] = + model_prediction_score; +}
diff --git a/chrome/browser/optimization_guide/optimization_guide_navigation_data.h b/chrome/browser/optimization_guide/optimization_guide_navigation_data.h index 5f6b411..575544bb 100644 --- a/chrome/browser/optimization_guide/optimization_guide_navigation_data.h +++ b/chrome/browser/optimization_guide/optimization_guide_navigation_data.h
@@ -26,6 +26,11 @@ OptimizationGuideNavigationData(const OptimizationGuideNavigationData& other); + // Returns the OptimizationGuideNavigationData for |navigation_handle|. Will + // return nullptr if one cannot be created for it for any reason. + static OptimizationGuideNavigationData* GetFromNavigationHandle( + content::NavigationHandle* navigation_handle); + // Records metrics based on data currently held in |this|. |has_committed| // indicates whether commit-time metrics should be recorded. void RecordMetrics(bool has_committed) const; @@ -61,6 +66,23 @@ optimization_guide::proto::OptimizationTarget optimization_target, optimization_guide::OptimizationTargetDecision decision); + // Returns the version of the model evaluated for |optimization_target|. + base::Optional<int64_t> GetModelVersionForOptimizationTarget( + optimization_guide::proto::OptimizationTarget optimization_target) const; + // Sets the |model_version| for |optimization_target|. + void SetModelVersionForOptimizationTarget( + optimization_guide::proto::OptimizationTarget optimization_target, + int64_t model_version); + + // Returns the prediction score of the model evaluated for + // |optimization_target|. + base::Optional<double> GetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OptimizationTarget optimization_target) const; + // Sets the |model_prediction_score| for |optimization_target|. + void SetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OptimizationTarget optimization_target, + double model_prediction_score); + // Whether the hint cache had a hint for the navigation before commit. base::Optional<bool> has_hint_before_commit() const { return has_hint_before_commit_; @@ -127,6 +149,17 @@ optimization_guide::OptimizationTargetDecision> optimization_target_decisions_; + // The version of the painful page load model that was evaluated for the + // page load. + base::flat_map<optimization_guide::proto::OptimizationTarget, int64_t> + optimization_target_model_versions_; + + // The score output after evaluating the painful page load model. If + // populated, this is 100x the fractional value output by the model + // evaluation. + base::flat_map<optimization_guide::proto::OptimizationTarget, double> + optimization_target_model_prediction_scores_; + // Whether the hint cache had a hint for the navigation before commit. base::Optional<bool> has_hint_before_commit_;
diff --git a/chrome/browser/optimization_guide/optimization_guide_navigation_data_unittest.cc b/chrome/browser/optimization_guide/optimization_guide_navigation_data_unittest.cc index e46a63fa..8b75578 100644 --- a/chrome/browser/optimization_guide/optimization_guide_navigation_data_unittest.cc +++ b/chrome/browser/optimization_guide/optimization_guide_navigation_data_unittest.cc
@@ -434,6 +434,87 @@ } TEST(OptimizationGuideNavigationDataTest, + RecordMetricsOptimizationTargetModelVersion) { + base::test::TaskEnvironment env; + + ukm::TestAutoSetUkmRecorder ukm_recorder; + + OptimizationGuideNavigationData data(/*navigation_id=*/3); + data.SetModelVersionForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD, 2); + data.RecordMetrics(/*has_committed=*/false); + + auto entries = ukm_recorder.GetEntriesByName( + ukm::builders::OptimizationGuide::kEntryName); + EXPECT_EQ(1u, entries.size()); + auto* entry = entries[0]; + EXPECT_TRUE(ukm_recorder.EntryHasMetric( + entry, + ukm::builders::OptimizationGuide::kPainfulPageLoadModelVersionName)); + ukm_recorder.ExpectEntryMetric( + entry, ukm::builders::OptimizationGuide::kPainfulPageLoadModelVersionName, + 2); +} + +TEST(OptimizationGuideNavigationDataTest, + RecordMetricsModelVersionForOptimizationTargetHasNoCorrespondingUkm) { + base::test::TaskEnvironment env; + + ukm::TestAutoSetUkmRecorder ukm_recorder; + + OptimizationGuideNavigationData data(/*navigation_id=*/3); + data.SetModelVersionForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_UNKNOWN, 2); + data.RecordMetrics(/*has_committed=*/false); + + // Make sure UKM not recorded for all empty values. + auto entries = ukm_recorder.GetEntriesByName( + ukm::builders::OptimizationGuide::kEntryName); + EXPECT_TRUE(entries.empty()); +} + +TEST(OptimizationGuideNavigationDataTest, + RecordMetricsOptimizationTargetModelPredictionScore) { + base::test::TaskEnvironment env; + + ukm::TestAutoSetUkmRecorder ukm_recorder; + + OptimizationGuideNavigationData data(/*navigation_id=*/3); + data.SetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD, 0.123); + data.RecordMetrics(/*has_committed=*/false); + + auto entries = ukm_recorder.GetEntriesByName( + ukm::builders::OptimizationGuide::kEntryName); + EXPECT_EQ(1u, entries.size()); + auto* entry = entries[0]; + EXPECT_TRUE(ukm_recorder.EntryHasMetric( + entry, ukm::builders::OptimizationGuide:: + kPainfulPageLoadModelPredictionScoreName)); + ukm_recorder.ExpectEntryMetric(entry, + ukm::builders::OptimizationGuide:: + kPainfulPageLoadModelPredictionScoreName, + 12); +} + +TEST(OptimizationGuideNavigationDataTest, + RecordMetricsModelPredicitonScoreOptimizationTargetHasNoCorrespondingUkm) { + base::test::TaskEnvironment env; + + ukm::TestAutoSetUkmRecorder ukm_recorder; + + OptimizationGuideNavigationData data(/*navigation_id=*/3); + data.SetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_UNKNOWN, 0.123); + data.RecordMetrics(/*has_committed=*/false); + + // Make sure UKM not recorded for all empty values. + auto entries = ukm_recorder.GetEntriesByName( + ukm::builders::OptimizationGuide::kEntryName); + EXPECT_TRUE(entries.empty()); +} + +TEST(OptimizationGuideNavigationDataTest, RecordMetricsMultipleOptimizationTypes) { base::HistogramTester histogram_tester; @@ -537,6 +618,14 @@ EXPECT_EQ(base::nullopt, data->has_hint_before_commit()); EXPECT_EQ(base::nullopt, data->has_hint_after_commit()); EXPECT_FALSE(data->has_page_hint_value()); + EXPECT_EQ( + base::nullopt, + data->GetModelVersionForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); + EXPECT_EQ( + base::nullopt, + data->GetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); data->set_serialized_hint_version_string("123abc"); data->SetDecisionForOptimizationType( @@ -552,6 +641,10 @@ page_hint.set_page_pattern("pagepattern"); data->set_page_hint( std::make_unique<optimization_guide::proto::PageHint>(page_hint)); + data->SetModelVersionForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD, 123); + data->SetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD, 0.12); OptimizationGuideNavigationData data_copy(*data); EXPECT_EQ(3, data_copy.navigation_id()); @@ -567,4 +660,12 @@ EXPECT_EQ("123abc", *(data_copy.serialized_hint_version_string())); EXPECT_TRUE(data_copy.has_page_hint_value()); EXPECT_EQ("pagepattern", data_copy.page_hint()->page_pattern()); + EXPECT_EQ( + 123, + *data_copy.GetModelVersionForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); + EXPECT_EQ( + 0.12, + *data_copy.GetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); }
diff --git a/chrome/browser/optimization_guide/optimization_guide_web_contents_observer.cc b/chrome/browser/optimization_guide/optimization_guide_web_contents_observer.cc index 5eb5712..7baaf520 100644 --- a/chrome/browser/optimization_guide/optimization_guide_web_contents_observer.cc +++ b/chrome/browser/optimization_guide/optimization_guide_web_contents_observer.cc
@@ -19,6 +19,14 @@ namespace { +bool WasHostCoveredByFetch(content::NavigationHandle* navigation_handle) { + return optimization_guide::HintsFetcher::WasHostCoveredByFetch( + Profile::FromBrowserContext( + navigation_handle->GetWebContents()->GetBrowserContext()) + ->GetPrefs(), + navigation_handle->GetURL().host()); +} + // Records if the host for the current navigation was successfully // covered by a HintsFetch. HintsFetching must be enabled and only HTTPS // navigations are logged. Returns whether navigation was covered by fetch. @@ -28,13 +36,7 @@ if (!optimization_guide::features::IsHintsFetchingEnabled()) return false; - bool was_host_covered_by_fetch = - optimization_guide::HintsFetcher::WasHostCoveredByFetch( - Profile::FromBrowserContext( - navigation_handle->GetWebContents()->GetBrowserContext()) - ->GetPrefs(), - navigation_handle->GetURL().GetOrigin().host()); - + bool was_host_covered_by_fetch = WasHostCoveredByFetch(navigation_handle); UMA_HISTOGRAM_BOOLEAN( "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch", was_host_covered_by_fetch); @@ -86,8 +88,6 @@ OptimizationGuideTopHostProvider::MaybeUpdateTopHostBlacklist( navigation_handle); - // Record the HintsFetcher coverage for the navigation, regardless if the - // keyed service is active or not. bool was_host_covered_by_fetch = RecordHintsFetcherCoverage(navigation_handle); @@ -124,6 +124,16 @@ content::NavigationHandle* navigation_handle) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // If the navigation committed, this will cover if the race with the + // navigation was able to cover the navigation or not. + if (navigation_handle->HasCommitted() && + navigation_handle->GetURL().SchemeIsHTTPOrHTTPS()) { + UMA_HISTOGRAM_BOOLEAN( + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + WasHostCoveredByFetch(navigation_handle)); + } + // Delete Optimization Guide information later, so that other // DidFinishNavigation methods can reliably use // GetOptimizationGuideNavigationData regardless of order of
diff --git a/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model.cc b/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model.cc index e7ea347..121ba5b 100644 --- a/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model.cc +++ b/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model.cc
@@ -123,14 +123,15 @@ optimization_guide::OptimizationTargetDecision DecisionTreePredictionModel::Predict( - const base::flat_map<std::string, float>& model_features) { + const base::flat_map<std::string, float>& model_features, + double* prediction_score) { SEQUENCE_CHECKER(sequence_checker_); - double result = 0.0; + *prediction_score = 0.0; // TODO(mcrouse): Add metrics to record if the model evaluation fails. - if (!EvaluateModel(*model_.get(), model_features, &result)) + if (!EvaluateModel(*model_.get(), model_features, prediction_score)) return optimization_guide::OptimizationTargetDecision::kUnknown; - if (result > model_->threshold().value()) + if (*prediction_score > model_->threshold().value()) return optimization_guide::OptimizationTargetDecision::kPageLoadMatches; return optimization_guide::OptimizationTargetDecision::kPageLoadDoesNotMatch; }
diff --git a/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model.h b/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model.h index c367a49..7fe0b051 100644 --- a/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model.h +++ b/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model.h
@@ -30,7 +30,8 @@ // PredictionModel implementation: optimization_guide::OptimizationTargetDecision Predict( - const base::flat_map<std::string, float>& model_features) override; + const base::flat_map<std::string, float>& model_features, + double* prediction_score) override; private: // Evaluates the provided model, either an ensemble or decision tree model,
diff --git a/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model_unittest.cc b/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model_unittest.cc index 44b0600..7e9b4c0 100644 --- a/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model_unittest.cc +++ b/chrome/browser/optimization_guide/prediction/decision_tree_prediction_model_unittest.cc
@@ -83,10 +83,14 @@ std::unique_ptr<PredictionModel> model = PredictionModel::Create(std::move(prediction_model), {"agg1"}); EXPECT_TRUE(model); + + double prediction_score; EXPECT_EQ(OptimizationTargetDecision::kPageLoadDoesNotMatch, - model->Predict({{"agg1", 1.0}})); + model->Predict({{"agg1", 1.0}}, &prediction_score)); + EXPECT_EQ(4., prediction_score); EXPECT_EQ(OptimizationTargetDecision::kPageLoadMatches, - model->Predict({{"agg1", 2.0}})); + model->Predict({{"agg1", 2.0}}, &prediction_score)); + EXPECT_EQ(8., prediction_score); } TEST(DecisionTreePredictionModel, InequalityLessThan) { @@ -111,10 +115,14 @@ std::unique_ptr<PredictionModel> model = PredictionModel::Create(std::move(prediction_model), {"agg1"}); EXPECT_TRUE(model); + + double prediction_score; EXPECT_EQ(OptimizationTargetDecision::kPageLoadDoesNotMatch, - model->Predict({{"agg1", 0.5}})); + model->Predict({{"agg1", 0.5}}, &prediction_score)); + EXPECT_EQ(4., prediction_score); EXPECT_EQ(OptimizationTargetDecision::kPageLoadMatches, - model->Predict({{"agg1", 2.0}})); + model->Predict({{"agg1", 2.0}}, &prediction_score)); + EXPECT_EQ(8., prediction_score); } TEST(DecisionTreePredictionModel, InequalityGreaterOrEqual) { @@ -139,10 +147,14 @@ std::unique_ptr<PredictionModel> model = PredictionModel::Create(std::move(prediction_model), {"agg1"}); EXPECT_TRUE(model); + + double prediction_score; EXPECT_EQ(OptimizationTargetDecision::kPageLoadMatches, - model->Predict({{"agg1", 0.5}})); + model->Predict({{"agg1", 0.5}}, &prediction_score)); + EXPECT_EQ(8., prediction_score); EXPECT_EQ(OptimizationTargetDecision::kPageLoadDoesNotMatch, - model->Predict({{"agg1", 1.0}})); + model->Predict({{"agg1", 1.0}}, &prediction_score)); + EXPECT_EQ(4., prediction_score); } TEST(DecisionTreePredictionModel, InequalityGreaterThan) { @@ -167,10 +179,14 @@ std::unique_ptr<PredictionModel> model = PredictionModel::Create(std::move(prediction_model), {"agg1"}); EXPECT_TRUE(model); + + double prediction_score; EXPECT_EQ(OptimizationTargetDecision::kPageLoadMatches, - model->Predict({{"agg1", 0.5}})); + model->Predict({{"agg1", 0.5}}, &prediction_score)); + EXPECT_EQ(8., prediction_score); EXPECT_EQ(OptimizationTargetDecision::kPageLoadDoesNotMatch, - model->Predict({{"agg1", 2.0}})); + model->Predict({{"agg1", 2.0}}, &prediction_score)); + EXPECT_EQ(4., prediction_score); } TEST(DecisionTreePredictionModel, MissingInequalityTest) { @@ -416,10 +432,14 @@ std::unique_ptr<PredictionModel> model = PredictionModel::Create(std::move(prediction_model), {"agg1"}); EXPECT_TRUE(model); + + double prediction_score; EXPECT_EQ(OptimizationTargetDecision::kPageLoadDoesNotMatch, - model->Predict({{"agg1", 1.0}})); + model->Predict({{"agg1", 1.0}}, &prediction_score)); + EXPECT_EQ(4., prediction_score); EXPECT_EQ(OptimizationTargetDecision::kPageLoadMatches, - model->Predict({{"agg1", 2.0}})); + model->Predict({{"agg1", 2.0}}, &prediction_score)); + EXPECT_EQ(8., prediction_score); } TEST(DecisionTreePredictionModel, EnsembleWithNoMembers) {
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager.cc b/chrome/browser/optimization_guide/prediction/prediction_manager.cc index 8c71e890..480840b1 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager.cc
@@ -12,6 +12,7 @@ #include "base/metrics/histogram_macros.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/engagement/site_engagement_service.h" +#include "chrome/browser/optimization_guide/optimization_guide_navigation_data.h" #include "chrome/browser/optimization_guide/optimization_guide_session_statistic.h" #include "chrome/browser/optimization_guide/prediction/prediction_model.h" #include "chrome/browser/optimization_guide/prediction/prediction_model_fetcher.h" @@ -182,7 +183,28 @@ base::flat_map<std::string, float> feature_map = BuildFeatureMap(navigation_handle, prediction_model->GetModelFeatures()); - return prediction_model->Predict(feature_map); + double prediction_score = 0.0; + optimization_guide::OptimizationTargetDecision target_decision = + prediction_model->Predict(feature_map, &prediction_score); + + OptimizationGuideNavigationData* navigation_data = + OptimizationGuideNavigationData::GetFromNavigationHandle( + navigation_handle); + if (navigation_data) { + navigation_data->SetModelVersionForOptimizationTarget( + optimization_target, prediction_model->GetVersion()); + navigation_data->SetModelPredictionScoreForOptimizationTarget( + optimization_target, prediction_score); + } + + if (optimization_guide::features:: + ShouldOverrideOptimizationTargetDecisionForMetricsPurposes( + optimization_target)) { + return optimization_guide::OptimizationTargetDecision:: + kModelPredictionHoldback; + } + + return target_decision; } void PredictionManager::OnEffectiveConnectionTypeChanged(
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc b/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc index edda059a..7a978a78 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc
@@ -7,10 +7,14 @@ #include <memory> #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/time/time.h" +#include "chrome/browser/optimization_guide/optimization_guide_navigation_data.h" +#include "chrome/browser/optimization_guide/optimization_guide_web_contents_observer.h" #include "chrome/browser/optimization_guide/prediction/prediction_model.h" #include "chrome/browser/optimization_guide/prediction/prediction_model_fetcher.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "components/optimization_guide/optimization_guide_features.h" #include "components/optimization_guide/proto/models.pb.h" #include "components/optimization_guide/top_host_provider.h" #include "content/public/test/mock_navigation_handle.h" @@ -75,12 +79,15 @@ ~TestPredictionModel() override = default; optimization_guide::OptimizationTargetDecision Predict( - const base::flat_map<std::string, float>& model_features) override { + const base::flat_map<std::string, float>& model_features, + double* prediction_score) override { + *prediction_score = 0.0; // Check to make sure the all model_features were provided. for (const auto& model_feature : GetModelFeatures()) { if (!model_features.contains(model_feature)) return OptimizationTargetDecision::kUnknown; } + *prediction_score = 0.6; model_evaluated_ = true; return OptimizationTargetDecision::kPageLoadMatches; } @@ -304,7 +311,8 @@ } TEST_F(PredictionManagerTest, OptimizationTargetNotRegisteredForNavigation) { - content::MockNavigationHandle navigation_handle; + OptimizationGuideWebContentsObserver::CreateForWebContents(web_contents()); + content::MockNavigationHandle navigation_handle(web_contents()); navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( @@ -319,11 +327,24 @@ EXPECT_EQ(OptimizationTargetDecision::kUnknown, prediction_manager()->ShouldTargetNavigation( &navigation_handle, proto::OPTIMIZATION_TARGET_UNKNOWN)); + // OptimizationGuideNavData should not be populated. + OptimizationGuideNavigationData* nav_data = + OptimizationGuideNavigationData::GetFromNavigationHandle( + &navigation_handle); + EXPECT_FALSE(nav_data + ->GetModelVersionForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_UNKNOWN) + .has_value()); + EXPECT_FALSE(nav_data + ->GetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_UNKNOWN) + .has_value()); } TEST_F(PredictionManagerTest, NoPredictionModelForRegisteredOptimizationTarget) { - content::MockNavigationHandle navigation_handle; + OptimizationGuideWebContentsObserver::CreateForWebContents(web_contents()); + content::MockNavigationHandle navigation_handle(web_contents()); navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->RegisterOptimizationTargets( @@ -332,10 +353,25 @@ OptimizationTargetDecision::kModelNotAvailableOnClient, prediction_manager()->ShouldTargetNavigation( &navigation_handle, proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); + + // OptimizationGuideNavData should not be populated. + OptimizationGuideNavigationData* nav_data = + OptimizationGuideNavigationData::GetFromNavigationHandle( + &navigation_handle); + EXPECT_FALSE( + nav_data + ->GetModelVersionForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD) + .has_value()); + EXPECT_FALSE( + nav_data + ->GetModelPredictionScoreForOptimizationTarget( + optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD) + .has_value()); } TEST_F(PredictionManagerTest, EvaluatePredictionModel) { - content::MockNavigationHandle navigation_handle; + content::MockNavigationHandle navigation_handle(web_contents()); navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( @@ -362,8 +398,6 @@ } TEST_F(PredictionManagerTest, UpdateModelWithSameVersion) { - content::MockNavigationHandle navigation_handle; - navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( BuildTestPredictionModelFetcher( PredictionModelFetcherEndState::kFetchFailed)); @@ -395,8 +429,9 @@ EXPECT_EQ(3, stored_prediction_model->GetVersion()); } -TEST_F(PredictionManagerTest, UpdateModelForUnregisteredTarget) { - content::MockNavigationHandle navigation_handle; +TEST_F(PredictionManagerTest, EvaluatePredictionModelPopulatesNavData) { + OptimizationGuideWebContentsObserver::CreateForWebContents(web_contents()); + content::MockNavigationHandle navigation_handle(web_contents()); navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( @@ -404,6 +439,82 @@ PredictionModelFetcherEndState:: kFetchSuccessWithModelsAndHostsModelFeatures)); + prediction_manager()->RegisterOptimizationTargets( + {proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD}); + + EXPECT_TRUE(prediction_model_fetcher()->models_fetched()); + + EXPECT_EQ( + OptimizationTargetDecision::kPageLoadMatches, + prediction_manager()->ShouldTargetNavigation( + &navigation_handle, proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); + + TestPredictionModel* test_prediction_model = + static_cast<TestPredictionModel*>( + prediction_manager()->GetPredictionModelForTesting( + proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); + EXPECT_TRUE(test_prediction_model); + EXPECT_TRUE(test_prediction_model->WasModelEvaluated()); + + OptimizationGuideNavigationData* nav_data = + OptimizationGuideNavigationData::GetFromNavigationHandle( + &navigation_handle); + EXPECT_EQ(2, *nav_data->GetModelVersionForOptimizationTarget( + proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); + EXPECT_EQ(0.6, *nav_data->GetModelPredictionScoreForOptimizationTarget( + proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); +} + +TEST_F(PredictionManagerTest, + EvaluatePredictionModelPopulatesNavDataEvenWithHoldback) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeaturesAndParameters( + {base::test::ScopedFeatureList::FeatureAndParams( + features::kOptimizationTargetPrediction, + {{"painful_page_load_metrics_only", "true"}})}, + {}); + + OptimizationGuideWebContentsObserver::CreateForWebContents(web_contents()); + content::MockNavigationHandle navigation_handle(web_contents()); + navigation_handle.set_url(GURL("https://foo.com")); + + prediction_manager()->SetPredictionModelFetcherForTesting( + BuildTestPredictionModelFetcher( + PredictionModelFetcherEndState:: + kFetchSuccessWithModelsAndHostsModelFeatures)); + + prediction_manager()->RegisterOptimizationTargets( + {proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD}); + + EXPECT_TRUE(prediction_model_fetcher()->models_fetched()); + + EXPECT_EQ( + OptimizationTargetDecision::kModelPredictionHoldback, + prediction_manager()->ShouldTargetNavigation( + &navigation_handle, proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); + + TestPredictionModel* test_prediction_model = + static_cast<TestPredictionModel*>( + prediction_manager()->GetPredictionModelForTesting( + proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); + EXPECT_TRUE(test_prediction_model); + EXPECT_TRUE(test_prediction_model->WasModelEvaluated()); + + OptimizationGuideNavigationData* nav_data = + OptimizationGuideNavigationData::GetFromNavigationHandle( + &navigation_handle); + EXPECT_EQ(2, *nav_data->GetModelVersionForOptimizationTarget( + proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); + EXPECT_EQ(0.6, *nav_data->GetModelPredictionScoreForOptimizationTarget( + proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD)); +} + +TEST_F(PredictionManagerTest, UpdateModelForUnregisteredTarget) { + prediction_manager()->SetPredictionModelFetcherForTesting( + BuildTestPredictionModelFetcher( + PredictionModelFetcherEndState:: + kFetchSuccessWithModelsAndHostsModelFeatures)); + prediction_manager()->RegisterOptimizationTargets({}); EXPECT_FALSE(prediction_model_fetcher()->models_fetched()); @@ -422,7 +533,7 @@ } TEST_F(PredictionManagerTest, UpdateModelWithUnsupportedOptimizationTarget) { - content::MockNavigationHandle navigation_handle; + content::MockNavigationHandle navigation_handle(web_contents()); navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( @@ -456,8 +567,6 @@ TEST_F(PredictionManagerTest, HasHostModelFeaturesForHost) { base::HistogramTester histogram_tester; - content::MockNavigationHandle navigation_handle; - navigation_handle.set_url(GURL("https://example1.com")); prediction_manager()->SetPredictionModelFetcherForTesting( BuildTestPredictionModelFetcher( @@ -488,7 +597,7 @@ TEST_F(PredictionManagerTest, NoHostModelFeaturesForHost) { base::HistogramTester histogram_tester; - content::MockNavigationHandle navigation_handle; + content::MockNavigationHandle navigation_handle(web_contents()); navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( @@ -529,8 +638,6 @@ TEST_F(PredictionManagerTest, UpdateHostModelFeaturesMissingHost) { base::HistogramTester histogram_tester; - content::MockNavigationHandle navigation_handle; - navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( BuildTestPredictionModelFetcher( @@ -553,8 +660,6 @@ TEST_F(PredictionManagerTest, UpdateHostModelFeaturesNoFeature) { base::HistogramTester histogram_tester; - content::MockNavigationHandle navigation_handle; - navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( BuildTestPredictionModelFetcher( @@ -577,8 +682,6 @@ TEST_F(PredictionManagerTest, UpdateHostModelFeaturesNoFeatureName) { base::HistogramTester histogram_tester; - content::MockNavigationHandle navigation_handle; - navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( BuildTestPredictionModelFetcher( @@ -603,8 +706,6 @@ TEST_F(PredictionManagerTest, UpdateHostModelFeaturesDoubleValue) { base::HistogramTester histogram_tester; - content::MockNavigationHandle navigation_handle; - navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( BuildTestPredictionModelFetcher( @@ -632,8 +733,6 @@ TEST_F(PredictionManagerTest, UpdateHostModelFeaturesIntValue) { base::HistogramTester histogram_tester; - content::MockNavigationHandle navigation_handle; - navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( BuildTestPredictionModelFetcher( @@ -663,8 +762,6 @@ TEST_F(PredictionManagerTest, UpdateHostModelFeaturesUpdateDataInMap) { base::HistogramTester histogram_tester; - content::MockNavigationHandle navigation_handle; - navigation_handle.set_url(GURL("https://foo.com")); prediction_manager()->SetPredictionModelFetcherForTesting( BuildTestPredictionModelFetcher(
diff --git a/chrome/browser/optimization_guide/prediction/prediction_model.h b/chrome/browser/optimization_guide/prediction/prediction_model.h index 24931f28..ada65f05 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_model.h +++ b/chrome/browser/optimization_guide/prediction/prediction_model.h
@@ -33,9 +33,11 @@ const base::flat_set<std::string>& host_model_features); // Returns the OptimizationTargetDecision by evaluating the |model_| - // using the provided |model_features|. + // using the provided |model_features|. |prediction_score| will be populated + // with the score output by the model. virtual optimization_guide::OptimizationTargetDecision Predict( - const base::flat_map<std::string, float>& model_features) = 0; + const base::flat_map<std::string, float>& model_features, + double* prediction_score) = 0; // Provide the version of the |model_| by |this|. int64_t GetVersion() const;
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 48604bb..737d430e 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/password_manager/account_storage/account_password_store_factory.h" +#include "chrome/browser/password_manager/field_info_manager_factory.h" #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/prerender/prerender_contents.h" #include "chrome/browser/profiles/profile.h" @@ -46,6 +47,7 @@ #include "components/password_manager/content/browser/password_manager_log_router_factory.h" #include "components/password_manager/content/browser/password_requirements_service_factory.h" #include "components/password_manager/core/browser/browser_save_password_progress_logger.h" +#include "components/password_manager/core/browser/field_info_manager.h" #include "components/password_manager/core/browser/hsts_query.h" #include "components/password_manager/core/browser/http_auth_manager.h" #include "components/password_manager/core/browser/http_auth_manager_impl.h" @@ -129,6 +131,7 @@ using autofill::mojom::FocusedFieldType; using password_manager::BadMessageReason; using password_manager::ContentPasswordManagerDriverFactory; +using password_manager::FieldInfoManager; using password_manager::PasswordManagerClientHelper; using password_manager::PasswordManagerDriver; using password_manager::PasswordManagerMetricsRecorder; @@ -1104,6 +1107,10 @@ return GetMainFrameURL() == chrome::kChromeSearchLocalNtpUrl; } +FieldInfoManager* ChromePasswordManagerClient::GetFieldInfoManager() const { + return FieldInfoManagerFactory::GetForBrowserContext(profile_); +} + // static void ChromePasswordManagerClient::BindCredentialManager( mojo::PendingReceiver<blink::mojom::CredentialManager> receiver,
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h index 44f7baf..447dd78 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.h +++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -153,6 +153,7 @@ void NavigateToManagePasswordsPage( password_manager::ManagePasswordsReferrer referrer) override; bool IsNewTabPage() const override; + password_manager::FieldInfoManager* GetFieldInfoManager() const override; // autofill::mojom::PasswordGenerationDriver overrides. void AutomaticGenerationAvailable(
diff --git a/chrome/browser/policy/browser_dm_token_storage.cc b/chrome/browser/policy/browser_dm_token_storage.cc index a6409781..e89d8d7 100644 --- a/chrome/browser/policy/browser_dm_token_storage.cc +++ b/chrome/browser/policy/browser_dm_token_storage.cc
@@ -59,6 +59,17 @@ return BrowserDMToken(Status::kEmpty, ""); } +BrowserDMToken::BrowserDMToken(const BrowserDMToken& other) = default; + +BrowserDMToken::BrowserDMToken(BrowserDMToken&& other) = default; + +BrowserDMToken& BrowserDMToken::operator=(const BrowserDMToken& other) = + default; + +BrowserDMToken& BrowserDMToken::operator=(BrowserDMToken&& other) = default; + +BrowserDMToken::~BrowserDMToken() = default; + const std::string& BrowserDMToken::value() const { // TODO(domfc): Uncomment DCHECK(is_valid()) after migrating code. // DCHECK(is_valid());
diff --git a/chrome/browser/policy/browser_dm_token_storage.h b/chrome/browser/policy/browser_dm_token_storage.h index 28a4671..cf456cc 100644 --- a/chrome/browser/policy/browser_dm_token_storage.h +++ b/chrome/browser/policy/browser_dm_token_storage.h
@@ -44,16 +44,23 @@ // enrollment token is present. class BrowserDMToken { public: + static BrowserDMToken CreateValidToken(const std::string& value); + static BrowserDMToken CreateInvalidToken(); + static BrowserDMToken CreateEmptyToken(); + + BrowserDMToken(const BrowserDMToken& other); + BrowserDMToken(BrowserDMToken&& other); + + BrowserDMToken& operator=(const BrowserDMToken& other); + BrowserDMToken& operator=(BrowserDMToken&& other); + ~BrowserDMToken(); + const std::string& value() const; bool is_valid() const; bool is_invalid() const; bool is_empty() const; - static BrowserDMToken CreateValidToken(const std::string& value); - static BrowserDMToken CreateInvalidToken(); - static BrowserDMToken CreateEmptyToken(); - private: enum class Status { kValid, kInvalid, kEmpty };
diff --git a/chrome/browser/previews/hints_fetcher_browsertest.cc b/chrome/browser/previews/hints_fetcher_browsertest.cc index 362ad74..ccc891b3 100644 --- a/chrome/browser/previews/hints_fetcher_browsertest.cc +++ b/chrome/browser/previews/hints_fetcher_browsertest.cc
@@ -1060,7 +1060,7 @@ net::EFFECTIVE_CONNECTION_TYPE_2G); // Navigate to a host not in the seeded site engagement service; it - // should be recorded as not covered by the hints fetcher. + // should be recorded as covered by the hints fetcher due to the race. base::flat_set<std::string> expected_hosts_2g; std::string host_2g("https://unseenhost_2g.com/"); expected_hosts_2g.insert(GURL(host_2g).host()); @@ -1079,10 +1079,21 @@ RetryForHistogramUntilCountReached( histogram_tester, optimization_guide::kLoadedHintLocalHistogramString, IsOptimizationGuideKeyedServiceEnabled() ? 2 : 1); + if (IsOptimizationGuideKeyedServiceEnabled()) { + RetryForHistogramUntilCountReached( + histogram_tester, + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + 1); + histogram_tester->ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + true, 1); + } } // Change ECT to a high value. Hints should not be fetched at the time of - // navigation. + // navigation as the ECT fast so the fetcher should not race. { g_browser_process->network_quality_tracker() ->ReportEffectiveConnectionTypeForTesting( @@ -1106,6 +1117,21 @@ RetryForHistogramUntilCountReached( histogram_tester, optimization_guide::kLoadedHintLocalHistogramString, IsOptimizationGuideKeyedServiceEnabled() ? 2 : 1); + if (IsOptimizationGuideKeyedServiceEnabled()) { + RetryForHistogramUntilCountReached( + histogram_tester, + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + 2); + histogram_tester->ExpectBucketCount( + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + true, 1); + histogram_tester->ExpectBucketCount( + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + false, 1); + } } // Change ECT back to a low value. Hints should be fetched at the time of @@ -1135,6 +1161,22 @@ RetryForHistogramUntilCountReached( histogram_tester, optimization_guide::kLoadedHintLocalHistogramString, IsOptimizationGuideKeyedServiceEnabled() ? 3 : 1); + + if (IsOptimizationGuideKeyedServiceEnabled()) { + RetryForHistogramUntilCountReached( + histogram_tester, + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + 3); + histogram_tester->ExpectBucketCount( + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + true, 2); + histogram_tester->ExpectBucketCount( + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + false, 1); + } } // Navigate again to a webpage with the @@ -1173,6 +1215,22 @@ RetryForHistogramUntilCountReached( histogram_tester, optimization_guide::kLoadedHintLocalHistogramString, IsOptimizationGuideKeyedServiceEnabled() ? 4 : 1); + + if (IsOptimizationGuideKeyedServiceEnabled()) { + RetryForHistogramUntilCountReached( + histogram_tester, + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + 4); + histogram_tester->ExpectBucketCount( + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + true, 3); + histogram_tester->ExpectBucketCount( + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + false, 1); + } } } @@ -1425,4 +1483,10 @@ RetryForHistogramUntilCountReached( histogram_tester, optimization_guide::kLoadedHintLocalHistogramString, IsOptimizationGuideKeyedServiceEnabled() ? 2 : 1); + // Only the SRP is navigated to and it should not be covered at navigation + // finish. + histogram_tester->ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch." + "AtCommit", + false, 1); }
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h index 756fa14..ff64a45 100644 --- a/chrome/browser/profiles/profile.h +++ b/chrome/browser/profiles/profile.h
@@ -453,9 +453,9 @@ static PrefStore* CreateExtensionPrefStore(Profile*, bool incognito_pref_store); - private: void NotifyOffTheRecordProfileCreated(Profile* off_the_record); + private: bool restored_last_session_; // Used to prevent the notification that this Profile is destroyed from
diff --git a/chrome/browser/reputation/local_heuristics.cc b/chrome/browser/reputation/local_heuristics.cc index 1c85d72..771154e1 100644 --- a/chrome/browser/reputation/local_heuristics.cc +++ b/chrome/browser/reputation/local_heuristics.cc
@@ -19,12 +19,12 @@ using MatchType = LookalikeUrlInterstitialPage::MatchType; const base::FeatureParam<bool> kEnableLookalikeTopSites{ - &security_state::features::kSafetyTipUI, "topsites", false}; + &security_state::features::kSafetyTipUI, "topsites", true}; const base::FeatureParam<bool> kEnableLookalikeEditDistance{ - &security_state::features::kSafetyTipUI, "editdistance", false}; + &security_state::features::kSafetyTipUI, "editdistance", true}; const base::FeatureParam<bool> kEnableLookalikeEditDistanceSiteEngagement{ &security_state::features::kSafetyTipUI, "editdistance_siteengagement", - false}; + true}; } // namespace
diff --git a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.css b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.css index 8a3a998..84fd6bd 100644 --- a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.css +++ b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.css
@@ -10,9 +10,3 @@ setup-pin-keyboard { margin-top: 17px; } - -#done-illustration { - height: 264px; - margin-top: 38px; /* 64px from subtitle baseline. */ - width: 264px; -}
diff --git a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.html b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.html index cb1394c..a6e4140 100644 --- a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.html +++ b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.html
@@ -109,9 +109,10 @@ class="focus-on-show" is-incognito-ui> </setup-pin-keyboard> - <img id="done-illustration" hidden="[[isStepHidden_(step_, 'done')]]" - srcset="images/pin_illustration_1x.svg 1x, - images/pin_illustration_2x.svg 2x"> + <img id="done-illustration" hidden="[[isStepHidden_(step_, 'done')]]" + class="oobe-illustration" + srcset="images/pin_illustration_1x.svg 1x, + images/pin_illustration_2x.svg 2x"> </div> <div slot="bottom-buttons" class="flex layout horizontal end-justified"> <oobe-text-button id="setupSkipButton" on-tap="onSkipButton_"
diff --git a/chrome/browser/resources/chromeos/login/marketing_opt_in.html b/chrome/browser/resources/chromeos/login/marketing_opt_in.html index 0d96b34..e8af493 100644 --- a/chrome/browser/resources/chromeos/login/marketing_opt_in.html +++ b/chrome/browser/resources/chromeos/login/marketing_opt_in.html
@@ -11,9 +11,8 @@ <link rel="stylesheet" href="oobe_flex_layout.css"> <oobe-dialog id="marketingOptInOverviewDialog" role="dialog" has-buttons aria-label="[[i18nDynamic(locale, 'marketingOptInScreenTitle')]]"> - <!-- TODO(https://crbug.com/852557): replace placeholder with real icon. --> - <hd-iron-icon slot="oobe-icon" icon1x="oobe-32:googleg" - icon2x="oobe-32:googleg"> + <hd-iron-icon slot="oobe-icon" icon1x="oobe-32:checkmark" + icon2x="oobe-32:checkmark"> </hd-iron-icon> <h1 slot="title"> [[i18nDynamic(locale, 'marketingOptInScreenTitle')]] @@ -23,8 +22,7 @@ </div> <div slot="footer" class="layout vertical"> <div class="marketing-option layout horizontal center"> - <!-- TODO(https://crbug.com/852557): replace placeholder with real icon. --> - <hd-iron-icon icon1x="oobe-32:googleg" icon2x="oobe-64:googleg"> + <hd-iron-icon icon1x="oobe-32:checkmark" icon2x="oobe-64:checkmark"> </hd-iron-icon> <div id="playUpdatesOptionLabel" class="flex"> [[i18nDynamic(locale, 'marketingOptInGetPlayUpdates')]] @@ -34,8 +32,7 @@ </cr-toggle> </div> <div class="marketing-option layout horizontal center"> - <!-- TODO(https://crbug.com/852557): replace placeholder with real icon. --> - <hd-iron-icon icon1x="oobe-32:googleg" icon2x="oobe-64:googleg"> + <hd-iron-icon icon1x="oobe-32:checkmark" icon2x="oobe-64:checkmark"> </hd-iron-icon> <div id="chromebookUpdatesOptionLabel" class="flex"> [[i18nRecursive(locale, 'marketingOptInGetChromebookUpdates',
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog_host.css b/chrome/browser/resources/chromeos/login/oobe_dialog_host.css index 6ce229b27..19c1865 100644 --- a/chrome/browser/resources/chromeos/login/oobe_dialog_host.css +++ b/chrome/browser/resources/chromeos/login/oobe_dialog_host.css
@@ -22,3 +22,9 @@ border-radius: 4px; box-shadow: 0 24px 24px rgba(0, 0, 0, .24), 0 0 24px rgba(0, 0, 0, .12); } + +.oobe-illustration { + max-height: -webkit-fill-available; + max-width: -webkit-fill-available; + object-fit: contain; +}
diff --git a/chrome/browser/resources/chromeos/login/oobe_flex_layout.css b/chrome/browser/resources/chromeos/login/oobe_flex_layout.css index e2bc08d..26195752 100644 --- a/chrome/browser/resources/chromeos/login/oobe_flex_layout.css +++ b/chrome/browser/resources/chromeos/login/oobe_flex_layout.css
@@ -116,9 +116,3 @@ right: 0; top: 0; } - -.oobe-illustration { - max-height: -webkit-fill-available; - max-width: -webkit-fill-available; - object-fit: contain; -}
diff --git a/chrome/browser/resources/chromeos/login/oobe_icons.html b/chrome/browser/resources/chromeos/login/oobe_icons.html index 8853479..0c7b02f 100644 --- a/chrome/browser/resources/chromeos/login/oobe_icons.html +++ b/chrome/browser/resources/chromeos/login/oobe_icons.html
@@ -53,6 +53,10 @@ <path fill="#1A73E8" fill-rule="nonzero"d="M29 20V0H3v20H0v3h32v-3h-3zm-10.333 0h-5.334v-1.333h5.334V20zM26 16H6V3h20v13z"></path> <path fill="#1A73E8" d="M16.97 8.129L16 5l-.97 3.129H12l2.47 1.836L13.53 13 16 11.123 18.47 13l-.94-3.035L20 8.129z"></path> </g> + <g id="checkmark" fill="none" fill-rule="evenodd"> + <path fill="#1A73E8" fill-rule="nonzero" d="M11.467 22.133l-5.6-5.6L4 18.4l7.467 7.467 16-16L25.6 8z"></path> + <path d="M0 0h32v32H0z"></path> + </g> </defs> </svg> </iron-iconset-svg> @@ -105,6 +109,10 @@ <path fill="#1A73E8" fill-rule="nonzero" d="M58 48V8H6v40H0v6h64v-6h-6zm-20.667 0H26.667v-2.667h10.666V48zM52 40H12V14h40v26z"></path> <path fill="#1A73E8" d="M33.94 24.258L32 18l-1.94 6.258H24l4.94 3.672L27.06 34 32 30.245 36.94 34l-1.88-6.07L40 24.258z"></path> </g> + <g id="checkmark" fill="none" fill-rule="evenodd"> + <path fill="#1A73E8" fill-rule="nonzero" d="M22.933 44.267l-11.2-11.2L8 36.8l14.933 14.933 32-32L51.2 16z"></path> + <path d="M0 0h64v64H0z"></path> + </g> </defs> </svg> </iron-iconset-svg>
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css index 71f2628..9d7bab8 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css
@@ -78,15 +78,6 @@ font-size: 13px; } -:host(.whitelist-error) .step-contents, -:host(.whitelist-error) .gaia-dialog { - visibility: hidden; -} - -:host(.whitelist-error) .step-loading { - visibility: hidden; -} - .step-loading { align-items: center; bottom: 0; @@ -109,14 +100,6 @@ visibility: hidden; } -:host(.whitelist-error) #gaia-whitelist-error { - visibility: visible; -} - -:host(:not(.saml-interstitial)) #gaia-step-contents { - display: none; -} - :host(.saml) #signin-frame-container { padding-top: 44px; }
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.html b/chrome/browser/resources/chromeos/login/screen_gaia_signin.html index a6dce40..27ec228 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.html +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.html
@@ -11,8 +11,7 @@ <oobe-dialog id="signin-frame-dialog" class="gaia-dialog" role="dialog" has-buttons no-header no-footer-padding show-buttons-overlay="[[!navigationEnabled_]]" - hidden="[[!isSigninFrameDialogVisible_(screenMode_, - pinDialogParameters_)]]"> + hidden="[[!eq_(step_, 'online-gaia')]]"> <div slot="footer" class="flex layout vertical"> <div id="signin-frame-container" class$="[[getSigninFrameContainerClass_(isLoadingUiShown_)]]"> @@ -40,31 +39,29 @@ </div> </oobe-dialog> <offline-gaia id="offline-gaia" class="gaia-dialog" - hidden="[[!isOfflineGaiaVisible_(screenMode_, isLoadingUiShown_, - pinDialogParameters_)]]"> + hidden="[[!eq_(step_, 'offline-gaia')]]"> </offline-gaia> <offline-ad-login id="offline-ad-auth" class="gaia-dialog" - hidden="[[!isOfflineAdAuthVisible_(screenMode_, isLoadingUiShown_, - pinDialogParameters_)]]" + hidden="[[!eq_(step_, 'ad')]]" i18n-values="ad-welcome-message:loginWelcomeMessage"> </offline-ad-login> <security-token-pin id="pinDialog" parameters="[[pinDialogParameters_]]" - hidden="[[!isPinDialogVisible_(pinDialogParameters_)]]" + hidden="[[!eq_(step_, 'pin')]]" on-cancel="onPinDialogCanceled_" on-completed="onPinDialogCompleted_"> </security-token-pin> - <div id="gaia-step-contents" class="step-contents"> + <div id="gaia-step-contents" class="step-contents" + hidden="[[!eq_(step_, 'saml-interstitial')]]"> <div id="gaia-signin-form-container"> - <saml-interstitial id="saml-interstitial" class="fit gaia-dialog" - hidden="[[!isSamlInterstitialVisible_( - screenMode_, isLoadingUiShown_, pinDialogParameters_)]]"> + <saml-interstitial id="saml-interstitial" class="fit gaia-dialog"> </saml-interstitial> </div> </div> <div id="gaia-loading" class="step-loading gaia-dialog" - hidden="[[!isLoadingUiShown_]]"> + hidden="[[!eq_(step_, 'loading')]]"> <throbber-notice i18n-values="text:gaiaLoading"></throbber-notice> </div> <notification-card id="gaia-whitelist-error" type="fail" class="gaia-dialog" + hidden="[[!eq_(step_, 'whitelist-error')]]" i18n-values="button-label:tryAgainButton; link-label:learnMoreButton"> </notification-card>
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js index 4ae3d091..8e7d7d8 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -42,16 +42,30 @@ const BUBBLE_VERTICAL_PADDING = -213; /** - * The modes this screen can be in. + * The authentication mode for the screen. * @enum {number} */ -const ScreenMode = { +const AuthMode = { DEFAULT: 0, // Default GAIA login flow. OFFLINE: 1, // GAIA offline login. SAML_INTERSTITIAL: 2, // Interstitial page before SAML redirection. AD_AUTH: 3 // Offline Active Directory login flow. }; +/** + * UI mode for the dialog. + * @enum {string} + */ +const DialogMode = { + GAIA: 'online-gaia', + OFFLINE_GAIA: 'offline-gaia', + OFFLINE_AD: 'ad', + LOADING: 'loading', + PIN_DIALOG: 'pin', + GAIA_WHITELIST_ERROR: 'whitelist-error', + SAML_INTERSTITIAL: 'saml-interstitial', +}; + Polymer({ is: 'gaia-signin', @@ -74,11 +88,20 @@ */ screenMode_: { type: Number, - value: ScreenMode.DEFAULT, + value: AuthMode.DEFAULT, observer: 'screenModeChanged_', }, /** + * Current step displayed. + * @private + */ + step_: { + type: String, + value: DialogMode.GAIA, + }, + + /** * Whether the loading UI is shown. * @private */ @@ -88,6 +111,15 @@ }, /** + * Whether the loading whitelist error UI is shown. + * @private + */ + isWhitelistErrorShown_: { + type: Boolean, + value: false, + }, + + /** * Whether the navigation controls are enabled. * @private */ @@ -155,6 +187,11 @@ }, }, + observers: [ + 'refreshDialogStep_(screenMode_, pinDialogParameters_, isLoadingUiShown_,' + + 'isWhitelistErrorShown_)' + ], + /** * Saved authenticator load params. * @type {?string} @@ -270,14 +307,14 @@ return function(e) { let currentFrame = null; switch (that.screenMode_) { - case ScreenMode.DEFAULT: - case ScreenMode.SAML_INTERSTITIAL: + case AuthMode.DEFAULT: + case AuthMode.SAML_INTERSTITIAL: currentFrame = that.authenticator_; break; - case ScreenMode.OFFLINE: + case AuthMode.OFFLINE: currentFrame = $that['offline-gaia']; break; - case ScreenMode.AD_AUTH: + case AuthMode.AD_AUTH: currentFrame = $that['offline-ad-auth']; break; } @@ -351,7 +388,7 @@ // Register handlers for the saml interstitial page events. this.$['saml-interstitial'].addEventListener( 'samlPageNextClicked', function() { - this.screenMode_ = ScreenMode.DEFAULT; + this.screenMode_ = AuthMode.DEFAULT; this.loadAuthenticator_(true /* doSamlRedirect */); }.bind(this)); this.$['saml-interstitial'].addEventListener( @@ -359,7 +396,7 @@ // The user requests to change the account. We must clear the email // field of the auth params. this.authenticatorParams_.email = ''; - this.screenMode_ = ScreenMode.DEFAULT; + this.screenMode_ = AuthMode.DEFAULT; this.loadAuthenticator_(false /* doSamlRedirect */); }.bind(this)); @@ -391,7 +428,7 @@ */ isAtTheBeginning_: function() { return !this.canGoBack_() && !this.isSaml_ && - !this.classList.contains('whitelist-error') && !this.authCompleted_; + !this.isWhitelistErrorShown_ && !this.authCompleted_; }, /** @@ -427,8 +464,7 @@ * @private */ canGoBack_: function() { - const isWhitelistError = this.classList.contains('whitelist-error'); - return this.lastBackMessageValue_ && !isWhitelistError && + return this.lastBackMessageValue_ && !this.isWhitelistErrorShown_ && !this.authCompleted_ && !this.isLoadingUiShown_ && !this.isSaml_; }, @@ -466,7 +502,7 @@ * @private */ isOffline_: function() { - return this.screenMode_ == ScreenMode.OFFLINE; + return this.screenMode_ == AuthMode.OFFLINE; }, /** @@ -496,7 +532,7 @@ isSigninFrameDialogVisible_: function(screenMode, pinDialogParameters) { // See the comment in getSigninFrameContainerClass_() for the explanation on // why our element shouldn't be hidden during loading. - return screenMode == ScreenMode.DEFAULT && pinDialogParameters === null; + return screenMode == AuthMode.DEFAULT && pinDialogParameters === null; }, /** @@ -523,7 +559,7 @@ */ isOfflineGaiaVisible_: function( screenMode, isLoadingUiShown, pinDialogParameters) { - return screenMode == ScreenMode.OFFLINE && !isLoadingUiShown && + return screenMode == AuthMode.OFFLINE && !isLoadingUiShown && pinDialogParameters === null; }, @@ -537,7 +573,7 @@ */ isSamlInterstitialVisible_: function( screenMode, isLoadingUiShown, pinDialogParameters) { - return screenMode == ScreenMode.SAML_INTERSTITIAL && !isLoadingUiShown && + return screenMode == AuthMode.SAML_INTERSTITIAL && !isLoadingUiShown && pinDialogParameters === null; }, @@ -551,7 +587,7 @@ */ isOfflineAdAuthVisible_: function( screenMode, isLoadingUiShown, pinDialogParameters) { - return screenMode == ScreenMode.AD_AUTH && !isLoadingUiShown && + return screenMode == AuthMode.AD_AUTH && !isLoadingUiShown && pinDialogParameters === null; }, @@ -720,7 +756,7 @@ behavior.onBeforeShow.call(this); }); - this.screenMode_ = ScreenMode.DEFAULT; + this.screenMode_ = AuthMode.DEFAULT; this.isLoadingUiShown_ = true; chrome.send('loginUIStateChanged', ['gaia-signin', true]); Oobe.getInstance().setSigninUIState(SIGNIN_UI_STATE.GAIA_SIGNIN); @@ -756,13 +792,13 @@ /** @private */ getActiveFrame_: function() { switch (this.screenMode_) { - case ScreenMode.DEFAULT: + case AuthMode.DEFAULT: return this.getSigninFrame_(); - case ScreenMode.OFFLINE: + case AuthMode.OFFLINE: return this.$['offline-gaia']; - case ScreenMode.AD_AUTH: + case AuthMode.AD_AUTH: return this.$['offline-ad-auth']; - case ScreenMode.SAML_INTERSTITIAL: + case AuthMode.SAML_INTERSTITIAL: return this.$['saml-interstitial']; } }, @@ -794,8 +830,8 @@ loadAuthExtension: function(data) { // Redirect the webview to the blank page in order to stop the SAML IdP // page from working in a background (see crbug.com/613245). - if (this.screenMode_ == ScreenMode.DEFAULT && - data.screenMode != ScreenMode.DEFAULT) { + if (this.screenMode_ == AuthMode.DEFAULT && + data.screenMode != AuthMode.DEFAULT) { this.authenticator_.resetWebview(); } @@ -824,7 +860,7 @@ params[name] = data[name]; } - params.doSamlRedirect = (this.screenMode_ == ScreenMode.SAML_INTERSTITIAL); + params.doSamlRedirect = (this.screenMode_ == AuthMode.SAML_INTERSTITIAL); params.menuGuestMode = data.guestSignin; params.menuKeyboardOptions = false; params.menuEnterpriseEnrollment = @@ -836,19 +872,19 @@ this.authenticatorParams_ = params; switch (this.screenMode_) { - case ScreenMode.DEFAULT: + case AuthMode.DEFAULT: this.loadAuthenticator_(false /* doSamlRedirect */); break; - case ScreenMode.OFFLINE: + case AuthMode.OFFLINE: this.loadOffline_(params); break; - case ScreenMode.AD_AUTH: + case AuthMode.AD_AUTH: this.loadAdAuth_(params); break; - case ScreenMode.SAML_INTERSTITIAL: + case AuthMode.SAML_INTERSTITIAL: this.$['saml-interstitial'].domain = data.enterpriseDisplayDomain; this.isLoadingUiShown_ = false; // This event is for the browser tests. @@ -868,7 +904,7 @@ const samlClass = 'saml-interstitial'; const containedSamlClass = this.classList.contains(samlClass); this.classList.toggle( - samlClass, this.screenMode_ == ScreenMode.SAML_INTERSTITIAL); + samlClass, this.screenMode_ == AuthMode.SAML_INTERSTITIAL); if (Oobe.getInstance().currentScreen.id != 'gaia-signin') return; // Switching between signin-frame-dialog and gaia-step-contents @@ -1232,7 +1268,7 @@ * @private */ onAuthCompleted_: function(credentials) { - if (this.screenMode_ == ScreenMode.AD_AUTH) { + if (this.screenMode_ == AuthMode.AD_AUTH) { this.email_ = credentials.username; chrome.send( 'completeAdAuthentication', @@ -1322,7 +1358,7 @@ * Reloads extension frame. */ doReload: function() { - if (this.screenMode_ != ScreenMode.DEFAULT) + if (this.screenMode_ != AuthMode.DEFAULT) return; this.authenticator_.reload(); this.isLoadingUiShown_ = true; @@ -1358,15 +1394,14 @@ cancel: function() { this.clearVideoTimer_(); - const isWhitelistError = this.classList.contains('whitelist-error'); // TODO(crbug.com/470893): Figure out whether/which of these exit conditions // are useful. - if (this.screenMode_ == ScreenMode.SAML_INTERSTITIAL || isWhitelistError || - this.authCompleted_) { + if (this.screenMode_ == AuthMode.SAML_INTERSTITIAL || + this.isWhitelistErrorShown_ || this.authCompleted_) { return; } - if (this.screenMode_ == ScreenMode.AD_AUTH) + if (this.screenMode_ == AuthMode.AD_AUTH) chrome.send('cancelAdAuthentication'); if (this.isClosable_()) @@ -1443,11 +1478,11 @@ // To make animations correct, we need to make sure Gaia is completely // reloaded. Otherwise ChromeOS overlays hide and Gaia page is shown // somewhere in the middle of animations. - if (this.screenMode_ == ScreenMode.DEFAULT) + if (this.screenMode_ == AuthMode.DEFAULT) this.authenticator_.resetWebview(); } - this.classList.toggle('whitelist-error', show); + this.isWhitelistErrorShown_ = show; this.isLoadingUiShown_ = !show; if (show) @@ -1478,7 +1513,7 @@ * @param {ACTIVE_DIRECTORY_ERROR_STATE} errorState */ invalidateAd: function(username, errorState) { - if (this.screenMode_ != ScreenMode.AD_AUTH) + if (this.screenMode_ != AuthMode.AD_AUTH) return; const adAuthUI = this.getActiveFrame_(); adAuthUI.userName = username; @@ -1555,5 +1590,47 @@ chrome.send('securityTokenPinEntered', [/*user_input=*/ e.detail]); }, + /** + * Simple equality comparison function. + */ + eq_: function(currentStep, expectedStep) { + return currentStep == expectedStep; + }, + + /** + * Updates current UI step based on internal state. + * @param {number} mode + * @param {OobeTypes.SecurityTokenPinDialogParameter} pinParams + * @param {boolean} isLoading + * @param {boolean} isWhitelistError + */ + refreshDialogStep_: function(mode, pinParams, isLoading, isWhitelistError) { + if (pinParams !== null) { + this.step_ = DialogMode.PIN_DIALOG; + return; + } + if (isLoading) { + this.step_ = DialogMode.LOADING; + return; + } + if (isWhitelistError) { + this.step_ = DialogMode.GAIA_WHITELIST_ERROR; + return; + } + switch (mode) { + case AuthMode.DEFAULT: + this.step_ = DialogMode.GAIA; + break; + case AuthMode.SAML_INTERSTITIAL: + this.step_ = DialogMode.SAML_INTERSTITIAL; + break; + case AuthMode.OFFLINE: + this.step_ = DialogMode.OFFLINE_GAIA; + break; + case AuthMode.AD_AUTH: + this.step_ = DialogMode.OFFLINE_AD; + break; + } + }, }); })();
diff --git a/chrome/browser/resources/chromeos/switch_access/menu_panel.js b/chrome/browser/resources/chromeos/switch_access/menu_panel.js index f1816108..ebea9667 100644 --- a/chrome/browser/resources/chromeos/switch_access/menu_panel.js +++ b/chrome/browser/resources/chromeos/switch_access/menu_panel.js
@@ -15,7 +15,7 @@ this.menuManager_; /** - * Reference to switch access. + * Reference to Switch Access. * @private {SwitchAccessInterface} */ this.switchAccess_;
diff --git a/chrome/browser/resources/chromeos/switch_access/switch_access.js b/chrome/browser/resources/chromeos/switch_access/switch_access.js index 4a89d32..fae8489 100644 --- a/chrome/browser/resources/chromeos/switch_access/switch_access.js +++ b/chrome/browser/resources/chromeos/switch_access/switch_access.js
@@ -17,8 +17,6 @@ /** @private */ constructor() { - console.log('Switch access is enabled'); - /** * User commands. * @private {Commands}
diff --git a/chrome/browser/resources/local_ntp/externs.js b/chrome/browser/resources/local_ntp/externs.js index bd71cf68..9ae815f 100644 --- a/chrome/browser/resources/local_ntp/externs.js +++ b/chrome/browser/resources/local_ntp/externs.js
@@ -390,7 +390,10 @@ window.chrome.embeddedSearch.searchBox.rtl; window.chrome.embeddedSearch.searchBox.startCapturingKeyStrokes; window.chrome.embeddedSearch.searchBox.stopCapturingKeyStrokes; -/** @param {string} input */ +/** + * @param {string} input + * @param {boolean} preventInlineAutocomplete + */ window.chrome.embeddedSearch.searchBox.queryAutocomplete; /** @param {boolean} clearResult */ window.chrome.embeddedSearch.searchBox.stopAutocomplete;
diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js index a70ef1d..d68ea76 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.js +++ b/chrome/browser/resources/local_ntp/local_ntp.js
@@ -268,7 +268,10 @@ */ let isDarkModeEnabled = false; -/** Used to prevent inline autocompleting recently deleted output. */ +/** + * Used to prevent the default match from requiring inline autocompletion when + * the user is deleting text in the input. + */ let isDeletingInput = false; /** @@ -1167,13 +1170,9 @@ selectMatchEl(assert($(IDS.REALBOX_MATCHES).firstElementChild)); } - // If the user is deleting content, don't quickly re-suggest the same - // output. - if (!isDeletingInput) { - const first = result.matches[0]; - if (first.allowedToBeDefaultMatch && first.inlineAutocompletion) { - updateRealboxOutput({inline: first.inlineAutocompletion}); - } + const first = result.matches[0]; + if (first.allowedToBeDefaultMatch && first.inlineAutocompletion) { + updateRealboxOutput({inline: first.inlineAutocompletion}); } } @@ -1542,7 +1541,8 @@ */ function queryAutocomplete(input) { lastInput = input; - window.chrome.embeddedSearch.searchBox.queryAutocomplete(input); + window.chrome.embeddedSearch.searchBox.queryAutocomplete( + input, isDeletingInput); } /**
diff --git a/chrome/browser/resources/tab_strip/tab.js b/chrome/browser/resources/tab_strip/tab.js index 780b6dde..a5eb54e 100644 --- a/chrome/browser/resources/tab_strip/tab.js +++ b/chrome/browser/resources/tab_strip/tab.js
@@ -121,8 +121,15 @@ this.setAttribute('draggable', true); this.toggleAttribute('crashed_', tab.crashed); - if (!this.tab_ || this.tab_.title !== tab.title) { + if (tab.title) { this.titleTextEl_.textContent = tab.title; + } else if ( + !tab.shouldHideThrobber && + (tab.networkState === TabNetworkState.WAITING || + tab.networkState === TabNetworkState.LOADING)) { + this.titleTextEl_.textContent = loadTimeData.getString('loadingTab'); + } else { + this.titleTextEl_.textContent = loadTimeData.getString('defaultTabTitle'); } this.titleTextEl_.setAttribute('aria-label', getAccessibleTitle(tab));
diff --git a/chrome/browser/resources/tab_strip/tab_swiper.js b/chrome/browser/resources/tab_strip/tab_swiper.js index 91819e2..9815625 100644 --- a/chrome/browser/resources/tab_strip/tab_swiper.js +++ b/chrome/browser/resources/tab_strip/tab_swiper.js
@@ -227,7 +227,7 @@ (event.timeStamp - this.currentPointerDownEvent_.timeStamp)) > SWIPE_VELOCITY_THRESHOLD; - if (pixelsSwiped === SWIPE_FINISH_THRESHOLD_PX) { + if (Math.abs(pixelsSwiped) === SWIPE_FINISH_THRESHOLD_PX) { // The user has swiped the max amount of pixels to swipe and the animation // has already completed all its keyframes, so just fire the onfinish // events on the animation.
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc index 48892e0..fc348da 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.cc
@@ -47,17 +47,11 @@ namespace { -const char** GetDMTokenForTestingStorage() { - static const char* dm_token_storage = ""; +BrowserDMToken* GetDMTokenForTestingStorage() { + static BrowserDMToken dm_token_storage = BrowserDMToken::CreateEmptyToken(); return &dm_token_storage; } -BrowserDMToken GetDMTokenForTesting() { - const char* dm_token = *GetDMTokenForTestingStorage(); - return dm_token && dm_token[0] ? BrowserDMToken::CreateValidToken(dm_token) - : BrowserDMToken::CreateEmptyToken(); -} - // Global pointer of factory function (RepeatingCallback) used to create // instances of DeepScanningDialogDelegate in tests. !is_null() only in tests. DeepScanningDialogDelegate::Factory* GetFactoryStorage() { @@ -405,7 +399,8 @@ } // static -void DeepScanningDialogDelegate::SetDMTokenForTesting(const char* dm_token) { +void DeepScanningDialogDelegate::SetDMTokenForTesting( + const BrowserDMToken& dm_token) { *GetDMTokenForTestingStorage() = dm_token; } @@ -482,7 +477,7 @@ // static BrowserDMToken DeepScanningDialogDelegate::GetDMToken() { - auto dm_token = GetDMTokenForTesting(); + BrowserDMToken* dm_token = GetDMTokenForTestingStorage(); #if !defined(OS_CHROMEOS) // This is not compiled on chromeos because @@ -490,13 +485,13 @@ // policy::BrowserDMTokenStorage::Get()->RetrieveDMToken() does not return a // valid token either. Once these are fixed the #if !defined can be removed. - if (dm_token.is_empty() && + if (dm_token->is_empty() && policy::ChromeBrowserCloudManagementController::IsEnabled()) { - dm_token = policy::BrowserDMTokenStorage::Get()->RetrieveBrowserDMToken(); + return policy::BrowserDMTokenStorage::Get()->RetrieveBrowserDMToken(); } #endif - return dm_token; + return *dm_token; } bool DeepScanningDialogDelegate::UploadData() {
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h index c4d5694..00d0416 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate.h
@@ -163,7 +163,8 @@ static void SetFactoryForTesting(Factory factory); // Overrides the DM token used for testing purposes. - static void SetDMTokenForTesting(const char* dm_token); + static void SetDMTokenForTesting( + const policy::BrowserDMTokenStorage::BrowserDMToken& dm_token); // Returns true if the given file type is supported for scanning. static bool FileTypeSupported(const bool for_malware_scan,
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc index de9413f..5ec5a02 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_dialog_delegate_unittest.cc
@@ -39,6 +39,18 @@ constexpr char kTestPortPatternUrl[] = "*:1234"; constexpr char kTestQueryPatternUrl[] = "*?q=5678"; +class ScopedSetDMToken { + public: + explicit ScopedSetDMToken( + const policy::BrowserDMTokenStorage::BrowserDMToken& dm_token) { + DeepScanningDialogDelegate::SetDMTokenForTesting(dm_token); + } + ~ScopedSetDMToken() { + DeepScanningDialogDelegate::SetDMTokenForTesting( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateEmptyToken()); + } +}; + class BaseTest : public testing::Test { public: BaseTest() : profile_manager_(TestingBrowserProcess::GetGlobal()) { @@ -46,14 +58,14 @@ profile_ = profile_manager_.CreateTestingProfile("test-user"); } - void SetDMToken(const char* dm_token) { - DeepScanningDialogDelegate::SetDMTokenForTesting(dm_token); + void EnableFeature(const base::Feature& feature) { + scoped_feature_list_.Reset(); + scoped_feature_list_.InitAndEnableFeature(feature); } - void EnableFeatures(const std::vector<base::Feature>& features) { + void DisableFeature(const base::Feature& feature) { scoped_feature_list_.Reset(); - scoped_feature_list_.InitWithFeatures(features, - std::vector<base::Feature>()); + scoped_feature_list_.InitAndDisableFeature(feature); } void SetDlpPolicy(CheckContentComplianceValues state) { @@ -96,6 +108,10 @@ using DeepScanningDialogDelegateIsEnabledTest = BaseTest; TEST_F(DeepScanningDialogDelegateIsEnabledTest, NoFeatureNoDMTokenNoPref) { + DisableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateInvalidToken()); + DeepScanningDialogDelegate::Data data; EXPECT_FALSE(DeepScanningDialogDelegate::IsEnabled(profile(), GURL(), &data)); EXPECT_FALSE(data.do_dlp_scan); @@ -103,7 +119,61 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, NoDMTokenNoPref) { - EnableFeatures({kDeepScanningOfUploads}); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateInvalidToken()); + + DeepScanningDialogDelegate::Data data; + EXPECT_FALSE(DeepScanningDialogDelegate::IsEnabled(profile(), GURL(), &data)); + EXPECT_FALSE(data.do_dlp_scan); + EXPECT_FALSE(data.do_malware_scan); +} + +TEST_F(DeepScanningDialogDelegateIsEnabledTest, NoDMToken) { + EnableFeature(kDeepScanningOfUploads); + SetDlpPolicy(CHECK_UPLOADS_AND_DOWNLOADS); + SetMalwarePolicy(SEND_UPLOADS_AND_DOWNLOADS); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateInvalidToken()); + + DeepScanningDialogDelegate::Data data; + EXPECT_FALSE(DeepScanningDialogDelegate::IsEnabled(profile(), GURL(), &data)); + EXPECT_FALSE(data.do_dlp_scan); + EXPECT_FALSE(data.do_malware_scan); +} + +TEST_F(DeepScanningDialogDelegateIsEnabledTest, NoFeatureNoPref) { + DisableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); + + DeepScanningDialogDelegate::Data data; + EXPECT_FALSE(DeepScanningDialogDelegate::IsEnabled(profile(), GURL(), &data)); + EXPECT_FALSE(data.do_dlp_scan); + EXPECT_FALSE(data.do_malware_scan); +} + +TEST_F(DeepScanningDialogDelegateIsEnabledTest, NoFeatureNoDMToken) { + DisableFeature(kDeepScanningOfUploads); + SetDlpPolicy(CHECK_UPLOADS_AND_DOWNLOADS); + SetMalwarePolicy(SEND_UPLOADS_AND_DOWNLOADS); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateInvalidToken()); + + DeepScanningDialogDelegate::Data data; + EXPECT_FALSE(DeepScanningDialogDelegate::IsEnabled(profile(), GURL(), &data)); + EXPECT_FALSE(data.do_dlp_scan); + EXPECT_FALSE(data.do_malware_scan); +} + +TEST_F(DeepScanningDialogDelegateIsEnabledTest, NoFeature) { + DisableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); + SetDlpPolicy(CHECK_UPLOADS_AND_DOWNLOADS); + SetMalwarePolicy(SEND_UPLOADS_AND_DOWNLOADS); DeepScanningDialogDelegate::Data data; EXPECT_FALSE(DeepScanningDialogDelegate::IsEnabled(profile(), GURL(), &data)); @@ -112,8 +182,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, DlpNoPref) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); DeepScanningDialogDelegate::Data data; EXPECT_FALSE(DeepScanningDialogDelegate::IsEnabled(profile(), GURL(), &data)); @@ -122,8 +194,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, DlpNoPref2) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetDlpPolicy(CHECK_NONE); DeepScanningDialogDelegate::Data data; @@ -133,8 +207,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, DlpNoPref3) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetDlpPolicy(CHECK_DOWNLOADS); DeepScanningDialogDelegate::Data data; @@ -144,8 +220,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, DlpEnabled) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetDlpPolicy(CHECK_UPLOADS); DeepScanningDialogDelegate::Data data; @@ -155,8 +233,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, DlpEnabled2) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetDlpPolicy(CHECK_UPLOADS_AND_DOWNLOADS); DeepScanningDialogDelegate::Data data; @@ -167,8 +247,10 @@ TEST_F(DeepScanningDialogDelegateIsEnabledTest, DlpDisabledByList) { GURL url(kTestUrl); - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetDlpPolicy(CHECK_UPLOADS); AddUrlToList(prefs::kURLsToNotCheckComplianceOfUploadedContent, url); @@ -179,8 +261,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, DlpDisabledByListWithPatterns) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetDlpPolicy(CHECK_UPLOADS); AddUrlToList(prefs::kURLsToNotCheckComplianceOfUploadedContent, kTestUrl); AddUrlToList(prefs::kURLsToNotCheckComplianceOfUploadedContent, @@ -265,8 +349,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, MalwareNoPref) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); DeepScanningDialogDelegate::Data data; EXPECT_FALSE(DeepScanningDialogDelegate::IsEnabled(profile(), GURL(), &data)); @@ -275,8 +361,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, MalwareNoPref2) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetMalwarePolicy(DO_NOT_SCAN); DeepScanningDialogDelegate::Data data; @@ -286,8 +374,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, MalwareNoPref4) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetMalwarePolicy(SEND_DOWNLOADS); DeepScanningDialogDelegate::Data data; @@ -297,8 +387,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, MalwareNoList) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetMalwarePolicy(SEND_UPLOADS); DeepScanningDialogDelegate::Data data; @@ -308,8 +400,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, MalwareNoList2) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetMalwarePolicy(SEND_UPLOADS_AND_DOWNLOADS); DeepScanningDialogDelegate::Data data; @@ -320,8 +414,10 @@ TEST_F(DeepScanningDialogDelegateIsEnabledTest, MalwareEnabled) { GURL url(kTestUrl); - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetMalwarePolicy(SEND_UPLOADS_AND_DOWNLOADS); AddUrlToList(prefs::kURLsToCheckForMalwareOfUploadedContent, url); @@ -333,8 +429,10 @@ TEST_F(DeepScanningDialogDelegateIsEnabledTest, NoScanInIncognito) { GURL url(kTestUrl); - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetDlpPolicy(CHECK_UPLOADS_AND_DOWNLOADS); SetMalwarePolicy(SEND_UPLOADS_AND_DOWNLOADS); AddUrlToList(prefs::kURLsToCheckForMalwareOfUploadedContent, url); @@ -348,8 +446,10 @@ } TEST_F(DeepScanningDialogDelegateIsEnabledTest, MalwareEnabledWithPatterns) { - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); + ScopedSetDMToken scoped_dm_token( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)); SetMalwarePolicy(SEND_UPLOADS_AND_DOWNLOADS); AddUrlToList(prefs::kURLsToCheckForMalwareOfUploadedContent, kTestUrl); AddUrlToList(prefs::kURLsToCheckForMalwareOfUploadedContent, @@ -452,8 +552,7 @@ void SetUp() override { BaseTest::SetUp(); - EnableFeatures({kDeepScanningOfUploads}); - SetDMToken(kDmToken); + EnableFeature(kDeepScanningOfUploads); SetDlpPolicy(CHECK_UPLOADS); SetMalwarePolicy(SEND_UPLOADS); @@ -474,6 +573,9 @@ base::RunLoop run_loop_; std::unique_ptr<content::WebContents> web_contents_; + ScopedSetDMToken scoped_dm_token_{ + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + kDmToken)}; // Paths in this map will be consider to have failed deep scan checks. // The actual failure response is given for each path.
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc b/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc index accc3da..8cfc46669 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc +++ b/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc
@@ -27,6 +27,7 @@ #include "components/policy/policy_constants.h" #include "components/prefs/pref_service.h" #include "components/sync/driver/profile_sync_service.h" +#include "components/sync/driver/sync_driver_switches.h" #include "components/ukm/test_ukm_recorder.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "testing/gmock/include/gmock/gmock.h" @@ -130,6 +131,14 @@ IN_PROC_BROWSER_TEST_F(ClickToCallBrowserTest, ContextMenu_DevicesAvailable_SyncTurnedOff) { + if (base::FeatureList::IsEnabled(kSharingUseDeviceInfo) && + base::FeatureList::IsEnabled(kSharingDeriveVapidKey) && + base::FeatureList::IsEnabled(switches::kSyncDeviceInfoInTransportMode)) { + // Turning off sync will have no effect when Click to Call is available on + // sign-in. + return; + } + Init(sync_pb::SharingSpecificFields::CLICK_TO_CALL, sync_pb::SharingSpecificFields::UNKNOWN); auto devices = sharing_service()->GetDeviceCandidates(
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_browsertest.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_browsertest.cc index 57b0418..ce5374d 100644 --- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_browsertest.cc +++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/test/scoped_feature_list.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" +#include "chrome/browser/sharing/features.h" #include "chrome/browser/sharing/shared_clipboard/feature_flags.h" #include "chrome/browser/sharing/sharing_browsertest.h" #include "chrome/browser/sharing/sharing_constants.h" @@ -18,6 +19,7 @@ #include "chrome/browser/sharing/sharing_sync_preference.h" #include "chrome/browser/sync/test/integration/sessions_helper.h" #include "components/sync/driver/profile_sync_service.h" +#include "components/sync/driver/sync_driver_switches.h" #include "url/gurl.h" namespace { @@ -126,6 +128,14 @@ } IN_PROC_BROWSER_TEST_F(SharedClipboardBrowserTest, ContextMenu_SyncTurnedOff) { + if (base::FeatureList::IsEnabled(kSharingUseDeviceInfo) && + base::FeatureList::IsEnabled(kSharingDeriveVapidKey) && + base::FeatureList::IsEnabled(switches::kSyncDeviceInfoInTransportMode)) { + // Turning off sync will have no effect when Shared Clipboard is available + // on sign-in. + return; + } + Init(sync_pb::SharingSpecificFields::SHARED_CLIPBOARD, sync_pb::SharingSpecificFields::UNKNOWN); auto devices = sharing_service()->GetDeviceCandidates(
diff --git a/chrome/browser/sharing/sharing_service.cc b/chrome/browser/sharing/sharing_service.cc index 066c79eb..0ea4d6f 100644 --- a/chrome/browser/sharing/sharing_service.cc +++ b/chrome/browser/sharing/sharing_service.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/sharing/sharing_fcm_sender.h" #include "chrome/browser/sharing/sharing_message_handler.h" #include "chrome/browser/sharing/sharing_metrics.h" +#include "chrome/browser/sharing/sharing_service_factory.h" #include "chrome/browser/sharing/sharing_sync_preference.h" #include "chrome/browser/sharing/sharing_utils.h" #include "chrome/browser/sharing/sms/sms_fetch_request_handler.h" @@ -410,19 +411,35 @@ } bool SharingService::IsSyncEnabled() const { - return sync_service_ && - sync_service_->GetTransportState() == - syncer::SyncService::TransportState::ACTIVE && - sync_service_->GetActiveDataTypes().HasAll(GetRequiredSyncDataTypes()); + if (!sync_service_) + return false; + + bool is_sync_enabled = + sync_service_->GetTransportState() == + syncer::SyncService::TransportState::ACTIVE && + sync_service_->GetActiveDataTypes().HasAll(GetRequiredSyncDataTypes()); + // TODO(crbug.com/1012226): Remove local sync check when we have dedicated + // Sharing data type. + if (base::FeatureList::IsEnabled(kSharingDeriveVapidKey)) + is_sync_enabled &= !sync_service_->IsLocalSyncEnabled(); + return is_sync_enabled; } bool SharingService::IsSyncDisabled() const { - return sync_service_ && (sync_service_->GetTransportState() == - syncer::SyncService::TransportState::DISABLED || - (sync_service_->GetTransportState() == - syncer::SyncService::TransportState::ACTIVE && - !sync_service_->GetActiveDataTypes().HasAll( - GetRequiredSyncDataTypes()))); + if (!sync_service_) + return false; + + bool is_sync_disabled = + sync_service_->GetTransportState() == + syncer::SyncService::TransportState::DISABLED || + (sync_service_->GetTransportState() == + syncer::SyncService::TransportState::ACTIVE && + !sync_service_->GetActiveDataTypes().HasAll(GetRequiredSyncDataTypes())); + // TODO(crbug.com/1012226): Remove local sync check when we have dedicated + // Sharing data type. + if (base::FeatureList::IsEnabled(kSharingDeriveVapidKey)) + is_sync_disabled |= sync_service_->IsLocalSyncEnabled(); + return is_sync_disabled; } syncer::ModelTypeSet SharingService::GetRequiredSyncDataTypes() const {
diff --git a/chrome/browser/sharing/sharing_service_unittest.cc b/chrome/browser/sharing/sharing_service_unittest.cc index abcd825..ccc774bf 100644 --- a/chrome/browser/sharing/sharing_service_unittest.cc +++ b/chrome/browser/sharing/sharing_service_unittest.cc
@@ -566,6 +566,24 @@ GetSharingService()->GetStateForTesting()); } +TEST_F(SharingServiceTest, DeviceUnregistrationLocalSyncEnabled) { + // Enable the registration feature and transport mode required features. + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{kSharingDeviceRegistration, kSharingUseDeviceInfo, + kSharingDeriveVapidKey}, + /*disabled_features=*/{}); + test_sync_service_.SetTransportState( + syncer::SyncService::TransportState::ACTIVE); + test_sync_service_.SetActiveDataTypes({syncer::DEVICE_INFO}); + test_sync_service_.SetLocalSyncEnabled(true); + + // Create new SharingService instance with sync disabled at constructor. + GetSharingService(); + EXPECT_EQ(1, sharing_device_registration_->unregistration_attempts()); + EXPECT_EQ(SharingService::State::DISABLED, + GetSharingService()->GetStateForTesting()); +} + TEST_F(SharingServiceTest, DeviceRegisterAndUnregister) { // Enable the feature. scoped_feature_list_.InitAndEnableFeature(kSharingDeviceRegistration); @@ -659,6 +677,29 @@ GetSharingService(); } +TEST_F(SharingServiceTest, NoDevicesWhenLocalSyncEnabled) { + // Enable the registration feature and transport mode required features. + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{kSharingDeviceRegistration, kSharingUseDeviceInfo, + kSharingDeriveVapidKey}, + /*disabled_features=*/{}); + test_sync_service_.SetTransportState( + syncer::SyncService::TransportState::ACTIVE); + test_sync_service_.SetActiveDataTypes({syncer::DEVICE_INFO}); + test_sync_service_.SetLocalSyncEnabled(true); + + std::string id = base::GenerateGUID(); + std::unique_ptr<syncer::DeviceInfo> device_info = + CreateFakeDeviceInfo(id, kDeviceName); + fake_device_info_sync_service.GetDeviceInfoTracker()->Add(device_info.get()); + + std::vector<std::unique_ptr<syncer::DeviceInfo>> candidates = + GetSharingService()->GetDeviceCandidates( + sync_pb::SharingSpecificFields::CLICK_TO_CALL); + + ASSERT_EQ(0u, candidates.size()); +} + TEST_F(SharingServiceTest, NoDevicesWhenSyncDisabled) { scoped_feature_list_.InitAndEnableFeature(kSharingDeviceRegistration); test_sync_service_.SetTransportState(
diff --git a/chrome/browser/supervised_user/logged_in_user_mixin.cc b/chrome/browser/supervised_user/logged_in_user_mixin.cc index 77c4d21..d9a180a 100644 --- a/chrome/browser/supervised_user/logged_in_user_mixin.cc +++ b/chrome/browser/supervised_user/logged_in_user_mixin.cc
@@ -46,8 +46,10 @@ FakeGaiaMixin::kFakeUserGaiaId)), ConvertUserType(type)), login_manager_(mixin_host, GetInitialUsers(user_, include_initial_user)), - policy_server_(mixin_host), - user_policy_(mixin_host, user_.account_id, &policy_server_), + local_policy_server_(mixin_host), + user_policy_(mixin_host, user_.account_id, &local_policy_server_), + user_policy_helper_(user_.account_id.GetUserEmail(), + &local_policy_server_), embedded_test_server_setup_(mixin_host, embedded_test_server), fake_gaia_(mixin_host, embedded_test_server) { // By default, LoginManagerMixin will set up user session manager not to @@ -67,6 +69,10 @@ // account.google.com requests would never reach fake GAIA server without // this. host_resolver->AddRule("*", "127.0.0.1"); + // Call RequestPolicyUpdate() to set up policy, which prevents the call to + // LogInUser() below from hanging indefinitely when there's no initial user + // and wait_for_active_session is true. + GetUserPolicyMixin()->RequestPolicyUpdate(); LogInUser(issue_any_scope_token, wait_for_active_session); // Set the private |browser_| member in InProcessBrowserTest. // Otherwise calls to InProcessBrowserTest::browser() returns null and leads
diff --git a/chrome/browser/supervised_user/logged_in_user_mixin.h b/chrome/browser/supervised_user/logged_in_user_mixin.h index 98bdeff..f33e75dd 100644 --- a/chrome/browser/supervised_user/logged_in_user_mixin.h +++ b/chrome/browser/supervised_user/logged_in_user_mixin.h
@@ -12,6 +12,7 @@ #include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/login/test/login_manager_mixin.h" #include "chrome/browser/chromeos/login/test/user_policy_mixin.h" +#include "chrome/browser/chromeos/policy/user_policy_test_helper.h" class AccountId; @@ -99,19 +100,24 @@ LoginManagerMixin* GetLoginManagerMixin() { return &login_manager_; } LocalPolicyTestServerMixin* GetLocalPolicyTestServerMixin() { - return &policy_server_; + return &local_policy_server_; } UserPolicyMixin* GetUserPolicyMixin() { return &user_policy_; } + policy::UserPolicyTestHelper* GetUserPolicyTestHelper() { + return &user_policy_helper_; + } + const AccountId& GetAccountId() { return user_.account_id; } private: LoginManagerMixin::TestUserInfo user_; LoginManagerMixin login_manager_; - LocalPolicyTestServerMixin policy_server_; + LocalPolicyTestServerMixin local_policy_server_; UserPolicyMixin user_policy_; + policy::UserPolicyTestHelper user_policy_helper_; EmbeddedTestServerSetupMixin embedded_test_server_setup_; FakeGaiaMixin fake_gaia_;
diff --git a/chrome/browser/sync/test/integration/local_sync_test.cc b/chrome/browser/sync/test/integration/local_sync_test.cc index 719d2bb..195658c 100644 --- a/chrome/browser/sync/test/integration/local_sync_test.cc +++ b/chrome/browser/sync/test/integration/local_sync_test.cc
@@ -10,6 +10,8 @@ #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h" +#include "chrome/browser/sharing/sharing_service.h" +#include "chrome/browser/sharing/sharing_service_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" #include "chrome/browser/ui/browser.h" @@ -76,6 +78,9 @@ // Verify certain features are disabled. EXPECT_FALSE(send_tab_to_self::IsUserSyncTypeActive(browser()->profile())); + EXPECT_EQ(SharingService::State::DISABLED, + SharingServiceFactory::GetForBrowserContext(browser()->profile()) + ->GetStateForTesting()); } #endif // defined(OS_WIN)
diff --git a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc index e7a1033..00af0583 100644 --- a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
@@ -30,6 +30,9 @@ syncer::SECURITY_EVENTS, syncer::AUTOFILL_WALLET_DATA); allowed_types.PutAll(syncer::ControlTypes()); + if (base::FeatureList::IsEnabled(switches::kSyncDeviceInfoInTransportMode)) { + allowed_types.Put(syncer::DEVICE_INFO); + } return allowed_types; }
diff --git a/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc b/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc index c8b2e1a1..0e6441b 100644 --- a/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc
@@ -27,6 +27,9 @@ syncer::SECURITY_EVENTS, syncer::AUTOFILL_WALLET_DATA); allowed_types.PutAll(syncer::ControlTypes()); + if (base::FeatureList::IsEnabled(switches::kSyncDeviceInfoInTransportMode)) { + allowed_types.Put(syncer::DEVICE_INFO); + } return allowed_types; }
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index eec91acb..b50bb721 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -1035,7 +1035,7 @@ } if (theme_colors.empty()) return; - provider->AddMixer()->AddSet({kColorSetCustomTheme, std::move(theme_colors)}); + provider->AddMixer().AddSet({kColorSetCustomTheme, std::move(theme_colors)}); } // private:
diff --git a/chrome/browser/themes/browser_theme_pack_unittest.cc b/chrome/browser/themes/browser_theme_pack_unittest.cc index f315f5c..9638fd8 100644 --- a/chrome/browser/themes/browser_theme_pack_unittest.cc +++ b/chrome/browser/themes/browser_theme_pack_unittest.cc
@@ -741,10 +741,10 @@ // Tests to make sure that existing colors within the color provider are not // overwritten or lost in the absence of any user provided theme values. ui::ColorProvider provider; - provider.AddMixer()->AddSet({ui::kColorSetTest0, - {{kColorToolbar, SK_ColorRED}, - {kColorOmniboxText, SK_ColorGREEN}, - {kColorOmniboxBackground, SK_ColorBLUE}}}); + provider.AddMixer().AddSet({ui::kColorSetTest0, + {{kColorToolbar, SK_ColorRED}, + {kColorOmniboxText, SK_ColorGREEN}, + {kColorOmniboxBackground, SK_ColorBLUE}}}); theme_pack().AddCustomThemeColorMixers(&provider); EXPECT_EQ(SK_ColorRED, provider.GetColor(kColorToolbar)); EXPECT_EQ(SK_ColorGREEN, provider.GetColor(kColorOmniboxText)); @@ -755,10 +755,10 @@ // Tests to make sure that only provided theme values are replicated into the // color provider. ui::ColorProvider provider; - provider.AddMixer()->AddSet({ui::kColorSetTest0, - {{kColorToolbar, SK_ColorRED}, - {kColorOmniboxText, SK_ColorGREEN}, - {kColorOmniboxBackground, SK_ColorBLUE}}}); + provider.AddMixer().AddSet({ui::kColorSetTest0, + {{kColorToolbar, SK_ColorRED}, + {kColorOmniboxText, SK_ColorGREEN}, + {kColorOmniboxBackground, SK_ColorBLUE}}}); std::string color_json = R"({ "toolbar": [0, 20, 40], "omnibox_text": [60, 80, 100] })"; LoadColorJSON(color_json); @@ -772,10 +772,10 @@ // Tests to make sure that all available colors are properly loaded into the // color provider. ui::ColorProvider provider; - provider.AddMixer()->AddSet({ui::kColorSetTest0, - {{kColorToolbar, SK_ColorRED}, - {kColorOmniboxText, SK_ColorGREEN}, - {kColorOmniboxBackground, SK_ColorBLUE}}}); + provider.AddMixer().AddSet({ui::kColorSetTest0, + {{kColorToolbar, SK_ColorRED}, + {kColorOmniboxText, SK_ColorGREEN}, + {kColorOmniboxBackground, SK_ColorBLUE}}}); std::string color_json = R"({ "toolbar": [0, 20, 40], "omnibox_text": [60, 80, 100], "omnibox_background": [120, 140, 160] })";
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index dc7f0e7..241bf4d 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2627,6 +2627,8 @@ "views/apps/app_info_dialog/app_info_permissions_panel.h", "views/apps/app_info_dialog/app_info_summary_panel.cc", "views/apps/app_info_dialog/app_info_summary_panel.h", + "views/apps/app_pause_dialog_view.cc", + "views/apps/app_pause_dialog_view.h", "views/apps/app_uninstall_dialog_view.cc", "views/apps/app_uninstall_dialog_view.h", "views/apps/chrome_native_app_window_views.cc",
diff --git a/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescription.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescription.java index 23182f4..aef401f 100644 --- a/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescription.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescription.java
@@ -17,7 +17,6 @@ import android.widget.RadioButton; import android.widget.RelativeLayout; import android.widget.TextView; - import java.util.List; /**
diff --git a/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescriptionLayout.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescriptionLayout.java index aaf1f78c..39e0ada 100644 --- a/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescriptionLayout.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescriptionLayout.java
@@ -7,6 +7,7 @@ import android.content.Context; import android.util.AttributeSet; import android.view.View; +import android.view.ViewGroup; import android.widget.RadioGroup; import androidx.annotation.Nullable; @@ -16,11 +17,13 @@ /** * Manages a group of exclusive RadioButtonWithDescriptions, automatically inserting a margin in - * between the rows to prevent them from squishing together. + * between the rows to prevent them from squishing together. Has the option to set an accessory view + * on any given RadioButtonWithDescription. Only one accessory view per layout is supported. * * ------------------------------------------------- * | O | MESSAGE #1 | * description_1 | + * [optional] accessory view | * | O | MESSAGE #N | * description_n | * ------------------------------------------------- @@ -63,6 +66,7 @@ private final int mMarginBetweenRows; private final List<RadioButtonWithDescription> mRadioButtonsWithDescriptions; private OnCheckedChangeListener mOnCheckedChangeListener; + private View mAccessoryView; public RadioButtonWithDescriptionLayout(Context context) { this(context, null); @@ -130,6 +134,31 @@ updateMargins(); } + private View removeAttachedAccessoryView(View view) { + // Remove the view from it's parent if it has one. + if (view.getParent() != null) { + ViewGroup previousGroup = (ViewGroup) view.getParent(); + previousGroup.removeView(view); + } + return view; + } + + /** + * Attach the given accessory view to the given RadioButtonWithDescription. The attachmentPoint + * must be a direct child of this. + * + * @param accessoryView The accessory view to be attached. + * @param attachmentPoint The RadioButtonWithDescription that the accessory view will be + * attached to. + */ + public void attachAccessoryView( + View accessoryView, RadioButtonWithDescription attachmentPoint) { + removeAttachedAccessoryView(accessoryView); + int attachmentPointIndex = indexOfChild(attachmentPoint); + assert attachmentPointIndex >= 0 : "attachmentPoint view must a child of layout."; + addView(accessoryView, attachmentPointIndex + 1); + } + /** Sets margins between each of the radio buttons. */ private void updateMargins() { int childCount = getChildCount();
diff --git a/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescriptionLayoutTest.java b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescriptionLayoutTest.java index 8b86081..9f9fdef 100644 --- a/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescriptionLayoutTest.java +++ b/chrome/browser/ui/android/widget/java/src/org/chromium/chrome/browser/ui/widget/RadioButtonWithDescriptionLayoutTest.java
@@ -11,6 +11,7 @@ import android.support.test.rule.UiThreadTestRule; import android.view.View; import android.view.ViewGroup.MarginLayoutParams; +import android.widget.TextView; import org.junit.Assert; import org.junit.Before; @@ -187,4 +188,51 @@ Assert.assertEquals(i == 1, child.isChecked()); } } + + @Test + @SmallTest + @UiThreadTest + public void testAccessoryViewAdded() { + final RadioButtonWithDescriptionLayout layout = + new RadioButtonWithDescriptionLayout(mContext); + + List<RadioButtonWithDescriptionLayout.Option> options = new ArrayList<>(); + options.add(new RadioButtonWithDescriptionLayout.Option("a", "a_desc", null)); + options.add(new RadioButtonWithDescriptionLayout.Option("b", "b_desc", null)); + options.add(new RadioButtonWithDescriptionLayout.Option("c", "c_desc", null)); + layout.addOptions(options); + + RadioButtonWithDescription firstButton = (RadioButtonWithDescription) layout.getChildAt(0); + final TextView accessoryTextView = new TextView(mContext); + layout.attachAccessoryView(accessoryTextView, firstButton); + Assert.assertEquals( + "The accessory view should be right after the position of it's attachment host.", + accessoryTextView, layout.getChildAt(1)); + } + + @Test + @SmallTest + @UiThreadTest + public void testAccessoryViewAddedThenReadded() { + final RadioButtonWithDescriptionLayout layout = + new RadioButtonWithDescriptionLayout(mContext); + + List<RadioButtonWithDescriptionLayout.Option> options = new ArrayList<>(); + options.add(new RadioButtonWithDescriptionLayout.Option("a", "a_desc", null)); + options.add(new RadioButtonWithDescriptionLayout.Option("b", "b_desc", null)); + options.add(new RadioButtonWithDescriptionLayout.Option("c", "c_desc", null)); + layout.addOptions(options); + + RadioButtonWithDescription firstButton = (RadioButtonWithDescription) layout.getChildAt(0); + RadioButtonWithDescription lastButton = + (RadioButtonWithDescription) layout.getChildAt(layout.getChildCount() - 1); + final TextView accessoryTextView = new TextView(mContext); + layout.attachAccessoryView(accessoryTextView, firstButton); + layout.attachAccessoryView(accessoryTextView, lastButton); + Assert.assertNotEquals( + "The accessory view shouldn't be in the first position it was inserted at.", + accessoryTextView, layout.getChildAt(1)); + Assert.assertEquals("The accessory view should be at the new position it was placed at.", + accessoryTextView, layout.getChildAt(layout.getChildCount() - 1)); + } }
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc index 76d6b13..ed420c6 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -228,13 +228,13 @@ wallpaper_controller_client_.reset(); vpn_list_forwarder_.reset(); - // Initialized in PostProfileInit: + // Initialized in PostProfileInit (which may not get called in some tests). network_portal_notification_controller_.reset(); display_settings_handler_.reset(); media_client_.reset(); login_screen_client_.reset(); - // Initialized in PreProfileInit: + // Initialized in PreProfileInit (which may not get called in some tests). system_tray_client_.reset(); session_controller_client_.reset(); ime_controller_client_.reset(); @@ -245,8 +245,8 @@ app_list_client_.reset(); ash_shell_init_.reset(); cast_config_controller_media_router_.reset(); - - chromeos::NetworkConnect::Shutdown(); + if (chromeos::NetworkConnect::IsInitialized()) + chromeos::NetworkConnect::Shutdown(); network_connect_delegate_.reset(); }
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 0d4126c6..82b53694 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -58,7 +58,7 @@ BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(window); if (!browser_view) - return true; + return false; content::WebContents* contents = browser_view->browser()->tab_strip_model()->GetActiveWebContents(); if (!contents)
diff --git a/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc b/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc index 8f30b7f..001e4af 100644 --- a/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc +++ b/chrome/browser/ui/ash/keyboard_shortcut_viewer_metadata_unittest.cc
@@ -23,15 +23,15 @@ namespace { // The total number of Ash accelerators. -constexpr int kAshAcceleratorsTotalNum = 109; +constexpr int kAshAcceleratorsTotalNum = 110; // The hash of Ash accelerators. -constexpr char kAshAcceleratorsHash[] = "8b62c1607085b5ca6a65ef43b97deac0"; +constexpr char kAshAcceleratorsHash[] = "1287cacd678f63ab151fbf25383ac19c"; #if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Internal builds add an extra accelerator for the Feedback app. // The total number of Chrome accelerators (available on Chrome OS). -constexpr int kChromeAcceleratorsTotalNum = 92; +constexpr int kChromeAcceleratorsTotalNum = 93; // The hash of Chrome accelerators (available on Chrome OS). -constexpr char kChromeAcceleratorsHash[] = "15a6c673dc62825b04e80036ad690514"; +constexpr char kChromeAcceleratorsHash[] = "73c842a72d77e7b9e69e92a6ee7900d3"; #else // The total number of Chrome accelerators (available on Chrome OS). constexpr int kChromeAcceleratorsTotalNum = 92;
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc index 52b84e0f..b532fde 100644 --- a/chrome/browser/ui/browser_focus_uitest.cc +++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -600,7 +600,7 @@ } // Tests that focus goes where expected when using reload on a crashed tab. -#if (defined(OS_CHROMEOS) || defined(OS_LINUX)) && !defined(NDEBUG) +#if defined(OS_CHROMEOS) || defined(OS_LINUX) // Hangy, http://crbug.com/50025. #define MAYBE_FocusOnReloadCrashedTab DISABLED_FocusOnReloadCrashedTab #else
diff --git a/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm b/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm index 1be7698..d0ccb41 100644 --- a/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm +++ b/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm
@@ -20,7 +20,7 @@ namespace { -IMP g_original_populatemenu_implementation = nullptr; +base::mac::ScopedObjCClassSwizzler* g_populatemenu_swizzler = nullptr; // |g_filtered_entries_array| is only set during testing (see // +[ChromeSwizzleServicesMenuUpdater storeFilteredEntriesForTestingInArray:]). @@ -98,8 +98,8 @@ } // Pass the filtered array along to the _NSServicesMenuUpdater. - g_original_populatemenu_implementation(self, _cmd, menu, remainingEntries, - display); + g_populatemenu_swizzler->InvokeOriginal<void, NSMenu*, NSArray*, BOOL>( + self, _cmd, menu, remainingEntries, display); } + (void)storeFilteredEntriesForTestingInArray:(NSMutableArray*)array { @@ -145,8 +145,7 @@ Class swizzleClass = [ChromeSwizzleServicesMenuUpdater class]; static base::NoDestructor<base::mac::ScopedObjCClassSwizzler> servicesMenuFilter(targetClass, swizzleClass, targetSelector); - g_original_populatemenu_implementation = - servicesMenuFilter->GetOriginalImplementation(); + g_populatemenu_swizzler = servicesMenuFilter.get(); }); }
diff --git a/chrome/browser/ui/search/search_ipc_router.cc b/chrome/browser/ui/search/search_ipc_router.cc index 64c39cd7..ab6aba1 100644 --- a/chrome/browser/ui/search/search_ipc_router.cc +++ b/chrome/browser/ui/search/search_ipc_router.cc
@@ -441,6 +441,7 @@ void SearchIPCRouter::QueryAutocomplete( const base::string16& input, + bool prevent_inline_autocomplete, chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback) { if (!policy_->ShouldProcessQueryAutocomplete(is_active_tab_)) { std::move(callback).Run(chrome::mojom::AutocompleteResult::New( @@ -449,7 +450,8 @@ return; } - delegate_->QueryAutocomplete(input, std::move(callback)); + delegate_->QueryAutocomplete(input, prevent_inline_autocomplete, + std::move(callback)); } void SearchIPCRouter::StopAutocomplete(bool clear_result) {
diff --git a/chrome/browser/ui/search/search_ipc_router.h b/chrome/browser/ui/search/search_ipc_router.h index c737c15..900c22a 100644 --- a/chrome/browser/ui/search/search_ipc_router.h +++ b/chrome/browser/ui/search/search_ipc_router.h
@@ -158,6 +158,7 @@ virtual void QueryAutocomplete( const base::string16& input, + bool prevent_inline_autocomplete, chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback) = 0; virtual void StopAutocomplete(bool clear_result) = 0; @@ -317,6 +318,7 @@ void ConfirmThemeChanges() override; void QueryAutocomplete( const base::string16& input, + bool prevent_inline_autocomplete, chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback) override; void StopAutocomplete(bool clear_result) override;
diff --git a/chrome/browser/ui/search/search_ipc_router_unittest.cc b/chrome/browser/ui/search/search_ipc_router_unittest.cc index d1278c5..621a6216 100644 --- a/chrome/browser/ui/search/search_ipc_router_unittest.cc +++ b/chrome/browser/ui/search/search_ipc_router_unittest.cc
@@ -108,9 +108,10 @@ void(uint8_t line, chrome::mojom::EmbeddedSearch::DeleteAutocompleteMatchCallback callback)); - MOCK_METHOD2( + MOCK_METHOD3( QueryAutocomplete, void(const base::string16& input, + bool prevent_inline_autocomplete, chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback)); MOCK_METHOD1(StopAutocomplete, void(bool)); MOCK_METHOD1(BlocklistPromo, void(const std::string& promo_id)); @@ -1079,13 +1080,13 @@ NavigateAndCommitActiveTab(GURL("chrome-search://foo/bar")); SetupMockDelegateAndPolicy(); MockSearchIPCRouterPolicy* policy = GetSearchIPCRouterPolicy(); - EXPECT_CALL(*mock_delegate(), QueryAutocomplete(_, _)).Times(0); + EXPECT_CALL(*mock_delegate(), QueryAutocomplete(_, _, _)).Times(0); EXPECT_CALL(*policy, ShouldProcessQueryAutocomplete(_)) .Times(1) .WillOnce(Return(false)); GetSearchIPCRouter().QueryAutocomplete( - base::string16(), + base::string16(), false, base::Bind([](chrome::mojom::AutocompleteResultPtr result) {})); }
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc index 485fc08..ce5afaf0 100644 --- a/chrome/browser/ui/search/search_tab_helper.cc +++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -585,6 +585,7 @@ void SearchTabHelper::QueryAutocomplete( const base::string16& input, + bool prevent_inline_autocomplete, chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback) { if (!search::DefaultSearchProviderIsGoogle(profile())) { std::move(callback).Run(chrome::mojom::AutocompleteResult::New( @@ -619,6 +620,8 @@ input, metrics::OmniboxEventProto::NTP_REALBOX, ChromeAutocompleteSchemeClassifier(profile())); autocomplete_input.set_from_omnibox_focus(input.empty()); + autocomplete_input.set_prevent_inline_autocomplete( + prevent_inline_autocomplete); autocomplete_controller_->Start(autocomplete_input); }
diff --git a/chrome/browser/ui/search/search_tab_helper.h b/chrome/browser/ui/search/search_tab_helper.h index 124a611..bb06782 100644 --- a/chrome/browser/ui/search/search_tab_helper.h +++ b/chrome/browser/ui/search/search_tab_helper.h
@@ -140,6 +140,7 @@ void OnConfirmThemeChanges() override; void QueryAutocomplete( const base::string16& input, + bool prevent_inline_autocomplete, chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback) override; void DeleteAutocompleteMatch(
diff --git a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc index a09e54d..1c7a4a3 100644 --- a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc +++ b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc
@@ -67,7 +67,9 @@ }, scan_succeeds); - safe_browsing::DeepScanningDialogDelegate::SetDMTokenForTesting("dm_token"); + safe_browsing::DeepScanningDialogDelegate::SetDMTokenForTesting( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + "dm_token")); safe_browsing::DeepScanningDialogDelegate::SetFactoryForTesting( base::BindRepeating( &safe_browsing::FakeDeepScanningDialogDelegate::Create,
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index e0e5eca..7e662c3f 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/defaults.h" #include "chrome/browser/media/router/media_router_feature.h" +#include "chrome/browser/media/router/media_router_metrics.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -443,6 +444,10 @@ if (!uma_action_recorded_) UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Cast", delta); LogMenuAction(MENU_ACTION_CAST); + // TODO(takumif): Look into moving this metrics logging to a single + // location, like MediaRouterDialogController::ShowMediaRouterDialog(). + media_router::MediaRouterMetrics::RecordMediaRouterDialogOrigin( + media_router::MediaRouterDialogOpenOrigin::APP_MENU); break; // Edit menu.
diff --git a/chrome/browser/ui/views/accelerator_table_unittest.cc b/chrome/browser/ui/views/accelerator_table_unittest.cc index 8427440..0c26fbb 100644 --- a/chrome/browser/ui/views/accelerator_table_unittest.cc +++ b/chrome/browser/ui/views/accelerator_table_unittest.cc
@@ -64,7 +64,8 @@ // 321568. if (ash_entry.action == ash::WINDOW_MINIMIZE || ash_entry.action == ash::SHOW_TASK_MANAGER || - ash_entry.action == ash::OPEN_GET_HELP) + ash_entry.action == ash::OPEN_GET_HELP || + ash_entry.action == ash::MINIMIZE_TOP_WINDOW_ON_BACK) continue; // The following actions are duplicated in both ash and browser accelerator
diff --git a/chrome/browser/ui/views/apps/app_pause_dialog_view.cc b/chrome/browser/ui/views/apps/app_pause_dialog_view.cc new file mode 100644 index 0000000..88aafe5 --- /dev/null +++ b/chrome/browser/ui/views/apps/app_pause_dialog_view.cc
@@ -0,0 +1,106 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/apps/app_pause_dialog_view.h" + +#include <memory> +#include <utility> + +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" +#include "chrome/grit/chromium_strings.h" +#include "chrome/grit/generated_resources.h" +#include "components/constrained_window/constrained_window_views.h" +#include "components/strings/grit/components_strings.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/image/image_skia_operations.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" + +// static +void apps::AppServiceProxy::CreatePauseDialog( + const std::string& app_name, + gfx::ImageSkia image, + const apps::PauseData& pause_data, + apps::AppServiceProxy::OnPauseDialogClosedCallback closed_callback) { + constrained_window::CreateBrowserModalDialogViews( + new AppPauseDialogView(app_name, image, pause_data, + std::move(closed_callback)), + nullptr) + ->Show(); +} + +AppPauseDialogView::AppPauseDialogView( + const std::string& app_name, + gfx::ImageSkia image, + const apps::PauseData& pause_data, + apps::AppServiceProxy::OnPauseDialogClosedCallback closed_callback) + : BubbleDialogDelegateView(nullptr, views::BubbleBorder::NONE), + closed_callback_(std::move(closed_callback)) { + ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + provider->GetDialogInsetsForContentType(views::TEXT, views::TEXT), + provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL))); + + auto* icon_view = AddChildView(std::make_unique<views::ImageView>()); + icon_view->SetImage(image); + + base::string16 pause_hours = l10n_util::GetPluralStringFUTF16( + IDS_APP_PAUSE_HEADING_HOURS, pause_data.hours); + base::string16 pause_minutes = l10n_util::GetPluralStringFUTF16( + IDS_APP_PAUSE_HEADING_MINUTES, pause_data.minutes); + + base::string16 heading_text; + if (pause_data.hours != 0 && pause_data.minutes != 0) { + heading_text = l10n_util::GetStringFUTF16( + IDS_APP_PAUSE_HEADING_HOURS_AND_MINUTES, base::UTF8ToUTF16(app_name), + pause_hours, pause_minutes); + } else if (pause_data.hours != 0) { + heading_text = + l10n_util::GetStringFUTF16(IDS_APP_PAUSE_HEADING_HOURS_ONLY, + base::UTF8ToUTF16(app_name), pause_hours); + } else if (pause_data.minutes != 0) { + heading_text = + l10n_util::GetStringFUTF16(IDS_APP_PAUSE_HEADING_MINUTES_ONLY, + base::UTF8ToUTF16(app_name), pause_minutes); + } + + auto* label = AddChildView(std::make_unique<views::Label>(heading_text)); + label->SetMultiLine(true); + label->SetHorizontalAlignment(gfx::ALIGN_LEFT); +} + +AppPauseDialogView::~AppPauseDialogView() = default; + +bool AppPauseDialogView::Accept() { + std::move(closed_callback_).Run(); + return true; +} + +gfx::Size AppPauseDialogView::CalculatePreferredSize() const { + const int default_width = views::LayoutProvider::Get()->GetDistanceMetric( + DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH) - + margins().width(); + return gfx::Size(default_width, GetHeightForWidth(default_width)); +} + +int AppPauseDialogView::GetDialogButtons() const { + return ui::DIALOG_BUTTON_OK; +} + +ui::ModalType AppPauseDialogView::GetModalType() const { + return ui::MODAL_TYPE_SYSTEM; +} + +base::string16 AppPauseDialogView::GetWindowTitle() const { + return l10n_util::GetStringUTF16(IDS_APP_PAUSE_PROMPT_TITLE); +} + +bool AppPauseDialogView::ShouldShowCloseButton() const { + return false; +}
diff --git a/chrome/browser/ui/views/apps/app_pause_dialog_view.h b/chrome/browser/ui/views/apps/app_pause_dialog_view.h new file mode 100644 index 0000000..724828f --- /dev/null +++ b/chrome/browser/ui/views/apps/app_pause_dialog_view.h
@@ -0,0 +1,41 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_APPS_APP_PAUSE_DIALOG_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_APPS_APP_PAUSE_DIALOG_VIEW_H_ + +#include "base/macros.h" + +#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "ui/views/bubble/bubble_dialog_delegate_view.h" + +namespace gfx { +class ImageSkia; +} + +// The app pause dialog. Once the user clicks the 'OK' button, this class calls +// the callback to notify AppService, which pauses the app. +class AppPauseDialogView : public views::BubbleDialogDelegateView { + public: + AppPauseDialogView( + const std::string& app_name, + gfx::ImageSkia image, + const apps::PauseData& pause_data, + apps::AppServiceProxy::OnPauseDialogClosedCallback callback); + ~AppPauseDialogView() override; + + // views::BubbleDialogDelegateView: + bool Accept() override; + gfx::Size CalculatePreferredSize() const override; + int GetDialogButtons() const override; + ui::ModalType GetModalType() const override; + base::string16 GetWindowTitle() const override; + bool ShouldShowCloseButton() const override; + + private: + // Callback when the dialog closes after the user has clicked the OK. + apps::AppServiceProxy::OnPauseDialogClosedCallback closed_callback_; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_APPS_APP_PAUSE_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/views/omnibox/omnibox_color_mixer.cc b/chrome/browser/ui/views/omnibox/omnibox_color_mixer.cc index 2a06c9f9..623d1b6 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_color_mixer.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_color_mixer.cc
@@ -13,55 +13,47 @@ #include "ui/gfx/color_utils.h" void AddOmniboxColorMixer(ui::ColorProvider* provider, bool high_contrast) { - ui::ColorMixer* mixer = provider->AddMixer(); + ui::ColorMixer& mixer = provider->AddMixer(); const float minimum_contrast = high_contrast ? 6.0f : color_utils::kMinimumReadableContrastRatio; // Omnibox background colors. - mixer->AddRecipe(kColorOmniboxBackground) - .AddTransform(ui::GetResultingPaintColor( - ui::FromTransformInput(), ui::FromInputColor(kColorToolbar))); - mixer->AddRecipe(kColorOmniboxBackgroundHovered) - .AddTransform(ui::BlendTowardMaxContrast( - ui::FromResultColor(kColorOmniboxBackground), 0x0A)); + mixer[kColorOmniboxBackground].AddTransform(ui::GetResultingPaintColor( + ui::FromTransformInput(), ui::FromInputColor(kColorToolbar))); + mixer[kColorOmniboxBackgroundHovered].AddTransform(ui::BlendTowardMaxContrast( + ui::FromResultColor(kColorOmniboxBackground), 0x0A)); // Omnibox text colors. - mixer->AddRecipe(kColorOmniboxText) - .AddTransform(ui::GetResultingPaintColor( - ui::FromTransformInput(), - ui::FromResultColor(kColorOmniboxBackground))); + mixer[kColorOmniboxText].AddTransform(ui::GetResultingPaintColor( + ui::FromTransformInput(), ui::FromResultColor(kColorOmniboxBackground))); { - auto& selected_text = - mixer->AddRecipe(kColorOmniboxResultsTextSelected) - .AddTransform(ui::FromResultColor(kColorOmniboxText)); + auto& selected_text = mixer[kColorOmniboxResultsTextSelected].AddTransform( + ui::FromResultColor(kColorOmniboxText)); if (high_contrast) selected_text.AddTransform(ui::ContrastInvert(ui::FromTransformInput())); } - mixer->AddRecipe(kColorOmniboxSelectedKeyword) - .AddTransform(ui::SelectBasedOnDarkInput( - ui::FromResultColor(kColorOmniboxBackground), - ui::FromColor(gfx::kGoogleGrey100), - ui::FromResultColor(kColorOmniboxResultsUrl))); + mixer[kColorOmniboxSelectedKeyword].AddTransform( + ui::SelectBasedOnDarkInput(ui::FromResultColor(kColorOmniboxBackground), + ui::FromColor(gfx::kGoogleGrey100), + ui::FromResultColor(kColorOmniboxResultsUrl))); // Bubble outline colors. - mixer->AddRecipe(kColorOmniboxBubbleOutline) - .AddTransform(ui::SelectBasedOnDarkInput( - ui::FromResultColor(kColorOmniboxBackground), - ui::FromColor(gfx::kGoogleGrey100), - ui::FromColor(SkColorSetA(gfx::kGoogleGrey900, 0x24)))); - mixer->AddRecipe(kColorOmniboxBubbleOutlineExperimentalKeywordMode) - .AddTransform(ui::FromResultColor(kColorOmniboxSelectedKeyword)); + mixer[kColorOmniboxBubbleOutline].AddTransform(ui::SelectBasedOnDarkInput( + ui::FromResultColor(kColorOmniboxBackground), + ui::FromColor(gfx::kGoogleGrey100), + ui::FromColor(SkColorSetA(gfx::kGoogleGrey900, 0x24)))); + mixer[kColorOmniboxBubbleOutlineExperimentalKeywordMode].AddTransform( + ui::FromResultColor(kColorOmniboxSelectedKeyword)); // Results background colors. - mixer->AddRecipe(kColorOmniboxResultsBackground) - .AddTransform( - ui::GetColorWithMaxContrast(ui::FromResultColor(kColorOmniboxText))); - mixer->AddRecipe(kColorOmniboxResultsBackgroundHovered) - .AddTransform(ui::BlendTowardMaxContrast( + mixer[kColorOmniboxResultsBackground].AddTransform( + ui::GetColorWithMaxContrast(ui::FromResultColor(kColorOmniboxText))); + mixer[kColorOmniboxResultsBackgroundHovered].AddTransform( + ui::BlendTowardMaxContrast( ui::FromResultColor(kColorOmniboxResultsBackground), gfx::kGoogleGreyAlpha200)); - mixer->AddRecipe(kColorOmniboxResultsBackgroundSelected) - .AddTransform(ui::BlendTowardMaxContrast( + mixer[kColorOmniboxResultsBackgroundSelected].AddTransform( + ui::BlendTowardMaxContrast( ui::GetColorWithMaxContrast( ui::FromResultColor(kColorOmniboxResultsTextSelected)), gfx::kGoogleGreyAlpha300)); @@ -74,12 +66,11 @@ ui::DeriveDefaultIconColor(ui::FromResultColor(text_id)), ui::FromResultColor(background_id), base::nullopt, minimum_contrast); }; - mixer->AddRecipe(kColorOmniboxResultsIcon) - .AddTransform( - results_icon(kColorOmniboxText, kColorOmniboxResultsBackground)); - mixer->AddRecipe(kColorOmniboxResultsIconSelected) - .AddTransform(results_icon(kColorOmniboxResultsTextSelected, - kColorOmniboxResultsBackgroundSelected)); + mixer[kColorOmniboxResultsIcon].AddTransform( + results_icon(kColorOmniboxText, kColorOmniboxResultsBackground)); + mixer[kColorOmniboxResultsIconSelected].AddTransform( + results_icon(kColorOmniboxResultsTextSelected, + kColorOmniboxResultsBackgroundSelected)); } // Dimmed text colors. @@ -95,16 +86,14 @@ base::nullopt, minimum_contrast), minimum_contrast); }; - mixer->AddRecipe(kColorOmniboxResultsTextDimmed) - .AddTransform(blend_with_clamped_contrast( - kColorOmniboxText, kColorOmniboxResultsBackgroundHovered)); - mixer->AddRecipe(kColorOmniboxResultsTextDimmedSelected) - .AddTransform(blend_with_clamped_contrast( - kColorOmniboxResultsTextSelected, - kColorOmniboxResultsBackgroundSelected)); - mixer->AddRecipe(kColorOmniboxTextDimmed) - .AddTransform(blend_with_clamped_contrast( - kColorOmniboxText, kColorOmniboxBackgroundHovered)); + mixer[kColorOmniboxResultsTextDimmed].AddTransform( + blend_with_clamped_contrast(kColorOmniboxText, + kColorOmniboxResultsBackgroundHovered)); + mixer[kColorOmniboxResultsTextDimmedSelected].AddTransform( + blend_with_clamped_contrast(kColorOmniboxResultsTextSelected, + kColorOmniboxResultsBackgroundSelected)); + mixer[kColorOmniboxTextDimmed].AddTransform(blend_with_clamped_contrast( + kColorOmniboxText, kColorOmniboxBackgroundHovered)); } // Results URL colors. @@ -117,10 +106,10 @@ ui::FromColor(gfx::kGoogleBlue900)), minimum_contrast); }; - mixer->AddRecipe(kColorOmniboxResultsUrl) - .AddTransform(url_color(kColorOmniboxResultsBackgroundHovered)); - mixer->AddRecipe(kColorOmniboxResultsUrlSelected) - .AddTransform(url_color(kColorOmniboxResultsBackgroundSelected)); + mixer[kColorOmniboxResultsUrl].AddTransform( + url_color(kColorOmniboxResultsBackgroundHovered)); + mixer[kColorOmniboxResultsUrlSelected].AddTransform( + url_color(kColorOmniboxResultsBackgroundSelected)); } // Security chip colors. @@ -136,12 +125,11 @@ ui::FromResultColor(kColorOmniboxBackgroundHovered), base::nullopt, minimum_contrast)); }; - mixer->AddRecipe(kColorOmniboxSecurityChipDangerous) - .AddTransform(security_chip_color(ui::FromColor(gfx::kGoogleRed600))); - mixer->AddRecipe(kColorOmniboxSecurityChipSecure) - .AddTransform(security_chip_color(ui::DeriveDefaultIconColor( - ui::FromResultColor(kColorOmniboxText)))); + mixer[kColorOmniboxSecurityChipDangerous].AddTransform( + security_chip_color(ui::FromColor(gfx::kGoogleRed600))); + mixer[kColorOmniboxSecurityChipSecure].AddTransform(security_chip_color( + ui::DeriveDefaultIconColor(ui::FromResultColor(kColorOmniboxText)))); } - mixer->AddRecipe(kColorOmniboxSecurityChipDefault) - .AddTransform(ui::FromResultColor(kColorOmniboxSecurityChipSecure)); + mixer[kColorOmniboxSecurityChipDefault].AddTransform( + ui::FromResultColor(kColorOmniboxSecurityChipSecure)); }
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc index ae29293..f8c67aa 100644 --- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
@@ -167,7 +167,10 @@ break; case UIStatus::kEnabled: feature_list_.InitWithFeaturesAndParameters( - {{security_state::features::kSafetyTipUI, {}}, + {{security_state::features::kSafetyTipUI, + {{"topsites", "false"}, + {"editdistance", "false"}, + {"editdistance_siteengagement", "false"}}}, {features::kLookalikeUrlNavigationSuggestionsUI, {{"topsites", "true"}}}}, {}); @@ -610,9 +613,11 @@ const GURL kLookalikeUrl = GetURL("googlé.sk"); SetEngagementScore(browser(), kLookalikeUrl, kLowEngagement); NavigateToURL(browser(), kLookalikeUrl, WindowOpenDisposition::CURRENT_TAB); - histograms.ExpectBucketCount( - kHistogramName, security_state::SafetyTipStatus::kLookalike, - ui_status() == UIStatus::kEnabledWithAllFeatures ? 1 : 0); + + // Record metrics for lookalike domains unless explicitly disabled. + histograms.ExpectBucketCount(kHistogramName, + security_state::SafetyTipStatus::kLookalike, + ui_status() == UIStatus::kEnabled ? 0 : 1); histograms.ExpectTotalCount(kHistogramName, 3); }
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.cc b/chrome/browser/ui/views/tabs/tab_group_header.cc index f904721..36b3e54 100644 --- a/chrome/browser/ui/views/tabs/tab_group_header.cc +++ b/chrome/browser/ui/views/tabs/tab_group_header.cc
@@ -155,7 +155,7 @@ title_->SetVisible(false); constexpr int kEmptyChipSize = 14; - const int y = (height() - kEmptyChipSize) / 2; + const int y = (GetLayoutConstant(TAB_HEIGHT) - kEmptyChipSize) / 2; title_chip_->SetBounds(TabGroupUnderline::GetStrokeInset(), y, kEmptyChipSize, kEmptyChipSize); @@ -184,7 +184,8 @@ const int text_vertical_inset = 1; const int text_horizontal_inset = corner_radius + text_vertical_inset; - const int y = (height() - text_height) / 2 - text_vertical_inset; + const int y = + (GetLayoutConstant(TAB_HEIGHT) - text_height) / 2 - text_vertical_inset; title_chip_->SetBounds(TabGroupUnderline::GetStrokeInset(), y, text_width + 2 * text_horizontal_inset,
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index e790fc4..93f7e29 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -97,6 +97,16 @@ #endif } +std::unique_ptr<views::View> CreateAlertView(const TabAlertState& state) { + auto alert_state_label = std::make_unique<views::Label>( + base::string16(), CONTEXT_BODY_TEXT_LARGE, views::style::STYLE_PRIMARY); + alert_state_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + alert_state_label->SetMultiLine(true); + alert_state_label->SetVisible(true); + alert_state_label->SetText(chrome::GetTabAlertStateText(state)); + return alert_state_label; +} + } // namespace // static @@ -635,19 +645,6 @@ return ui::DIALOG_BUTTON_NONE; } -std::unique_ptr<views::View> TabHoverCardBubbleView::CreateFootnoteView() { - if (!alert_state_.has_value()) - return nullptr; - - auto alert_state_label = std::make_unique<views::Label>( - base::string16(), CONTEXT_BODY_TEXT_LARGE, views::style::STYLE_PRIMARY); - alert_state_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - alert_state_label->SetMultiLine(true); - alert_state_label->SetVisible(true); - alert_state_label->SetText(chrome::GetTabAlertStateText(*alert_state_)); - return alert_state_label; -} - void TabHoverCardBubbleView::Layout() { View::Layout(); title_fade_label_->SetBoundsRect(title_label_->bounds()); @@ -727,8 +724,10 @@ title_fade_label_->SetText(title_label_->GetText()); title_label_->SetText(title); - if (alert_state_ != old_alert_state) - GetBubbleFrameView()->SetFootnoteView(CreateFootnoteView()); + if (alert_state_ != old_alert_state) { + GetBubbleFrameView()->SetFootnoteView( + alert_state_.has_value() ? CreateAlertView(*alert_state_) : nullptr); + } domain_fade_label_->SetText(domain_label_->GetText()); domain_label_->SetText(domain);
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h index 281ceb0..bd1e8eaa 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
@@ -54,7 +54,6 @@ void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override; ax::mojom::Role GetAccessibleWindowRole() override; int GetDialogButtons() const override; - std::unique_ptr<views::View> CreateFootnoteView() override; void Layout() override; void set_last_mouse_exit_timestamp(
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc index 350c1d5..fbe88956 100644 --- a/chrome/browser/ui/views/tabs/tab_style_views.cc +++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -75,6 +75,24 @@ // effects and consider only the current tab's state. SeparatorOpacities GetSeparatorOpacities(bool for_layout) const; + // Returns a single separator's opacity based on whether it is the + // logically |leading| separator. |for_layout| has the same meaning as in + // GetSeparatorOpacities(). + float GetSeparatorOpacity(bool for_layout, bool leading) const; + + // Helper that returns an interpolated opacity if the tab or its neighbor + // |other_tab| is mid-hover-animation. Used in almost all cases when a + // separator is shown, since hovering is independent of tab state. + // |for_layout| has the same meaning as in GetSeparatorOpacities(). + float GetHoverInterpolatedSeparatorOpacity(bool for_layout, + const Tab* other_tab) const; + + // Helper that returns an interpolated opacity if the tab is + // mid-bounds-animation. Used only for the first and last tabs, since those + // are the primary cases where separator opacity is likely to change during + // a bounds animation. + float GetBoundsInterpolatedSeparatorOpacity() const; + // Returns whether we shoould extend the hit test region for Fitts' Law. bool ShouldExtendHitTest() const; @@ -536,73 +554,22 @@ TabStyle::SeparatorOpacities GM2TabStyle::GetSeparatorOpacities( bool for_layout) const { - // Something should visually separate tabs from each other and any adjacent - // new tab button. Normally, active and hovered tabs draw distinct shapes - // (via different background colors) and thus need no separators, while - // background tabs need separators between them. - float leading_opacity, trailing_opacity; - if (tab_->IsActive()) { - leading_opacity = trailing_opacity = 0; - } else { - const Tab* subsequent_tab = tab_->controller()->GetAdjacentTab(tab_, 1); - const Tab* previous_tab = tab_->controller()->GetAdjacentTab(tab_, -1); + // Adjacent slots should be visually separated from each other. This can be + // achieved in multiple ways: + // - Contrasting background colors for tabs, due to: + // - Active state + // - Selected state + // - Hovered state + // - Theming (affected by all the above, plus the neutral state) + // - Manually painting a separator. + // The separator should be the last resort, if none of the above states + // apply. It's also needed if multiple adjacent views are selected, in which + // case the uniform selected color does not provide enough contrast. + // In addition, separators should smoothly fade in and out between states, + // particularly during the hover animation. - // Fade out the intervening separator while this tab or an adjacent tab is - // hovered, which prevents sudden opacity changes when scrubbing the mouse - // across the tabstrip. If that adjacent tab is active, don't consider its - // hover animation value, otherwise the separator on this tab will disappear - // while that tab is being dragged. - auto adjacent_hover_value = [for_layout](const Tab* tab) { - if (for_layout || !tab || tab->IsActive()) - return 0.f; - auto* tab_style = static_cast<const GM2TabStyle*>(tab->tab_style()); - return float{tab_style->GetHoverAnimationValue()}; - }; - const float hover_value = GetHoverAnimationValue(); - trailing_opacity = - 1.f - std::max(hover_value, adjacent_hover_value(subsequent_tab)); - leading_opacity = - 1.f - std::max(hover_value, adjacent_hover_value(previous_tab)); - - if (tab_->IsSelected()) { - // Since this tab is selected, its shape will be visible against adjacent - // unselected tabs, so remove the separator in those cases. - if (previous_tab && !previous_tab->IsSelected()) - leading_opacity = 0; - if (subsequent_tab && !subsequent_tab->IsSelected()) - trailing_opacity = 0; - } else if (tab_->controller()->HasVisibleBackgroundTabShapes()) { - // Since this tab is unselected, adjacent selected tabs will normally - // paint atop it, covering the separator. But if the user drags those - // selected tabs away, the exposed region looks like the window frame; and - // since background tab shapes are visible, there should be no separator. - // TODO(pkasting): https://crbug.com/876599 When a tab is animating - // into this gap, we should adjust its separator opacities as well. - if (previous_tab && previous_tab->IsSelected()) - leading_opacity = 0; - if (subsequent_tab && subsequent_tab->IsSelected()) - trailing_opacity = 0; - } - } - - // For the first or (when tab shapes are visible) last tab in the strip, fade - // the leading or trailing separator based on how close to the target bounds - // this tab is. In the steady state, this hides the leading separator; it - // fades out the separators as tabs animate into these positions, after they - // pass by the other tabs; and it snaps the separators to full visibility - // immediately when animating away from these positions, which seems - // desirable. - const gfx::Rect target_bounds = - tab_->controller()->GetTabAnimationTargetBounds(tab_); - const int tab_width = std::max(tab_->width(), target_bounds.width()); - const float target_opacity = - float{std::min(std::abs(tab_->x() - target_bounds.x()), tab_width)} / - tab_width; - if (tab_->controller()->IsFirstVisibleTab(tab_)) - leading_opacity = target_opacity; - if (tab_->controller()->IsLastVisibleTab(tab_) && - tab_->controller()->HasVisibleBackgroundTabShapes()) - trailing_opacity = target_opacity; + float leading_opacity = GetSeparatorOpacity(for_layout, true); + float trailing_opacity = GetSeparatorOpacity(for_layout, false); // Return the opacities in physical order, rather than logical. if (base::i18n::IsRTL()) @@ -610,6 +577,115 @@ return {leading_opacity, trailing_opacity}; } +float GM2TabStyle::GetSeparatorOpacity(bool for_layout, bool leading) const { + // If the current tab is active, never show the separator. + if (tab_->IsActive()) + return 0.0f; + + const Tab* adjacent_tab = + tab_->controller()->GetAdjacentTab(tab_, leading ? -1 : 1); + + const Tab* left_tab = leading ? adjacent_tab : tab_; + const Tab* right_tab = leading ? tab_ : adjacent_tab; + const bool adjacent_to_header = + right_tab && right_tab->group().has_value() && + (!left_tab || left_tab->group() != right_tab->group()); + + // If the current tab is selected, default to hiding the separator. Only show + // the separator if it's adjacent to other selected tabs. + if (tab_->IsSelected()) { + // If the adjacent view is actually a group header, hide the separator since + // group headers currently cannot be selected. + // TODO(crbug.com/1017822): Update this if headers become selectable. + if (adjacent_to_header) + return 0.0f; + + if (adjacent_tab && adjacent_tab->IsSelected()) + return GetHoverInterpolatedSeparatorOpacity(for_layout, adjacent_tab); + + return 0.0f; + } + + // Otherwise, default to showing the separator, respecting the hover + // animation. Only hide the separator if it's in the first slot, or in + // certain cases if the tab has a visible background (see below). + + // If the adjacent view is actually a group header, show the separator since + // the group header takes up a slot. + // TODO(crbug.com/1017822): Update this if headers become selectable. + if (adjacent_to_header) + return GetHoverInterpolatedSeparatorOpacity(for_layout, nullptr); + + // If the tab has a visible background even when not selected or active, there + // are additional cases where the separators can be hidden. + if (tab_->controller()->HasVisibleBackgroundTabShapes()) { + // If the tab with a visible background is in an end slot, hide the + // separator because it doesn't need additional contrast with the tab strip + // or the new tab button. This value isn't interpolated like the others + // because the separator was likely already hidden: if it's animating into + // an end slot, then the tab was probably next to a selected dragging tab + // (see the condition below). + if (!adjacent_tab) + return 0.0f; + + // If the adjacent tab is selected, any separator on the current tab will be + // "hidden" beneath the adjacent tab's background. Normally tabs will still + // have a separator, in case the adjacent tab is dragged away and it reveals + // an empty gap. However, tabs with visible backgrounds already have + // sufficient contrast against the empty gap, so this contingency isn't + // needed. Therefore, the separator is hidden only for tabs with visible + // backgrounds. + // TODO(crbug.com/876599): This value should be interpolated because the + // separator may be going from shown (the default) to hidden (when animating + // past an empty gap like this). This should behave similarly to + // GetBoundsInterpolatedSeparatorOpacity(), but not just for the end slots. + if (adjacent_tab->IsSelected()) + return 0.0f; + } + + // If the tab does not have a visible background and is in the first slot, + // make sure the opacity is interpolated correctly when it animates into + // position, since the separator is likely going from shown (the default) to + // hidden (in the first slot). See GetBoundsInterpolatedSeparatorOpacity(). + if (!adjacent_tab && leading) + return GetBoundsInterpolatedSeparatorOpacity(); + + return GetHoverInterpolatedSeparatorOpacity(for_layout, adjacent_tab); +} + +float GM2TabStyle::GetHoverInterpolatedSeparatorOpacity( + bool for_layout, + const Tab* other_tab) const { + // Fade out the intervening separator while this tab or an adjacent tab is + // hovered, which prevents sudden opacity changes when scrubbing the mouse + // across the tabstrip. If that adjacent tab is active, don't consider its + // hover animation value, otherwise the separator on this tab will disappear + // while that tab is being dragged. + auto adjacent_hover_value = [for_layout](const Tab* other_tab) { + if (for_layout || !other_tab || other_tab->IsActive()) + return 0.0f; + auto* tab_style = static_cast<const GM2TabStyle*>(other_tab->tab_style()); + return float{tab_style->GetHoverAnimationValue()}; + }; + const float hover_value = GetHoverAnimationValue(); + return 1.0f - std::max(hover_value, adjacent_hover_value(other_tab)); +} + +float GM2TabStyle::GetBoundsInterpolatedSeparatorOpacity() const { + // When the bounds of a tab are animating, fade the separator based on how + // close to the target bounds this tab is. This function is only called + // when the target bounds are an end slot. That means this function will fade + // the separators in or out as a tab animtes into the end slot, but it will + // not be called if the tab is animating out of the end slot. In that case, + // the separator will snap to full opacity immediately, which is visually + // consistent with other bounds animations. + const gfx::Rect target_bounds = + tab_->controller()->GetTabAnimationTargetBounds(tab_); + const int tab_width = std::max(tab_->width(), target_bounds.width()); + return float{std::min(std::abs(tab_->x() - target_bounds.x()), tab_width)} / + tab_width; +} + bool GM2TabStyle::ShouldExtendHitTest() const { const views::Widget* widget = tab_->GetWidget(); return widget->IsMaximized() || widget->IsFullscreen();
diff --git a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc index 1c5b605..ed3cdc84 100644 --- a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -19,7 +19,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "base/values.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/camera_presence_notifier.h" #include "chrome/browser/chromeos/login/users/avatar/user_image_manager.h" @@ -39,7 +38,6 @@ #include "components/user_manager/user_image/user_image.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" #include "content/public/browser/web_ui.h" #include "content/public/common/url_constants.h" #include "net/base/data_url.h"
diff --git a/chrome/browser/ui/webui/settings/profile_info_handler.cc b/chrome/browser/ui/webui/settings/profile_info_handler.cc index 6e0af7ba..139f203 100644 --- a/chrome/browser/ui/webui/settings/profile_info_handler.cc +++ b/chrome/browser/ui/webui/settings/profile_info_handler.cc
@@ -14,12 +14,10 @@ #include "ui/base/webui/web_ui_util.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/ui/webui/chromeos/user_image_source.h" #include "components/account_id/account_id.h" #include "components/user_manager/user_manager.h" -#include "content/public/browser/notification_service.h" #else #include "chrome/browser/profiles/profile_avatar_icon_util.h" #include "chrome/browser/profiles/profile_statistics.h"
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc index ce95eecb..83923229 100644 --- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc +++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
@@ -14,7 +14,6 @@ #include "base/value_conversions.h" #include "base/values.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/gaia_info_update_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_attributes_entry.h" @@ -31,7 +30,6 @@ #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" #include "content/public/browser/web_ui.h" #include "google_apis/gaia/gaia_auth_util.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index f31d12ee..95ccbe20 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -17,7 +17,6 @@ #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/content_settings/web_site_settings_uma_util.h" #include "chrome/browser/engagement/site_engagement_service.h" @@ -28,7 +27,6 @@ #include "chrome/browser/permissions/permission_manager.h" #include "chrome/browser/permissions/permission_uma_util.h" #include "chrome/browser/permissions/permission_util.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/serial/serial_chooser_context.h" #include "chrome/browser/serial/serial_chooser_context_factory.h" #include "chrome/browser/ui/browser.h" @@ -50,7 +48,6 @@ #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/common/origin_util.h" @@ -338,9 +335,7 @@ SiteSettingsHandler::SiteSettingsHandler(Profile* profile, web_app::AppRegistrar& app_registrar) - : profile_(profile), - app_registrar_(app_registrar), - pref_change_registrar_(nullptr) {} + : profile_(profile), app_registrar_(app_registrar) {} SiteSettingsHandler::~SiteSettingsHandler() { if (cookies_tree_model_) @@ -452,11 +447,6 @@ if (profile_->HasOffTheRecordProfile()) ObserveSourcesForProfile(profile_->GetOffTheRecordProfile()); - notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, - content::NotificationService::AllSources()); - notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); - // Here we only subscribe to the HostZoomMap for the default storage partition // since we don't allow the user to manage the zoom levels for apps. // We're only interested in zoom-levels that are persisted, since the user @@ -487,12 +477,12 @@ void SiteSettingsHandler::OnJavascriptDisallowed() { observer_.RemoveAll(); chooser_observer_.RemoveAll(); - notification_registrar_.RemoveAll(); host_zoom_map_subscription_.reset(); pref_change_registrar_->Remove(prefs::kBlockAutoplayEnabled); #if defined(OS_CHROMEOS) pref_change_registrar_->Remove(prefs::kEnableDRM); #endif + observed_profiles_.RemoveAll(); } void SiteSettingsHandler::OnGetUsageInfo() { @@ -558,31 +548,16 @@ } } -void SiteSettingsHandler::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case chrome::NOTIFICATION_PROFILE_DESTROYED: { - Profile* profile = content::Source<Profile>(source).ptr(); - if (!profile_->IsSameProfile(profile)) - break; - SendIncognitoStatus(profile, /*was_destroyed=*/true); +void SiteSettingsHandler::OnOffTheRecordProfileCreated( + Profile* off_the_record) { + FireWebUIListener("onIncognitoStatusChanged", base::Value(true)); + ObserveSourcesForProfile(off_the_record); +} - if (profile->IsOffTheRecord()) - StopObservingSourcesForProfile(profile); - break; - } - - case chrome::NOTIFICATION_PROFILE_CREATED: { - Profile* profile = content::Source<Profile>(source).ptr(); - if (!profile_->IsSameProfile(profile)) - break; - SendIncognitoStatus(profile, /*was_destroyed=*/false); - - ObserveSourcesForProfile(profile); - break; - } - } +void SiteSettingsHandler::OnProfileWillBeDestroyed(Profile* profile) { + if (profile->IsOffTheRecord()) + FireWebUIListener("onIncognitoStatusChanged", base::Value(false)); + StopObservingSourcesForProfile(profile); } void SiteSettingsHandler::OnChooserObjectPermissionChanged( @@ -1207,22 +1182,8 @@ void SiteSettingsHandler::HandleUpdateIncognitoStatus( const base::ListValue* args) { AllowJavascript(); - SendIncognitoStatus(profile_, /*was_destroyed=*/false); -} - -void SiteSettingsHandler::SendIncognitoStatus(Profile* profile, - bool was_destroyed) { - if (!IsJavascriptAllowed()) - return; - - // When an incognito profile is destroyed, it sends out the destruction - // message before destroying, so HasOffTheRecordProfile for profile_ won't - // return false until after the profile actually been destroyed. - bool incognito_enabled = - profile_->HasOffTheRecordProfile() && - !(was_destroyed && profile == profile_->GetOffTheRecordProfile()); - - FireWebUIListener("onIncognitoStatusChanged", base::Value(incognito_enabled)); + FireWebUIListener("onIncognitoStatusChanged", + base::Value(profile_->HasOffTheRecordProfile())); } void SiteSettingsHandler::HandleFetchZoomLevels(const base::ListValue* args) { @@ -1390,6 +1351,8 @@ auto* serial_context = SerialChooserContextFactory::GetForProfile(profile); if (!chooser_observer_.IsObserving(serial_context)) chooser_observer_.Add(serial_context); + + observed_profiles_.Add(profile); } void SiteSettingsHandler::StopObservingSourcesForProfile(Profile* profile) { @@ -1404,6 +1367,8 @@ auto* serial_context = SerialChooserContextFactory::GetForProfile(profile); if (chooser_observer_.IsObserving(serial_context)) chooser_observer_.Remove(serial_context); + + observed_profiles_.Remove(profile); } void SiteSettingsHandler::TreeNodesAdded(ui::TreeModel* model,
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.h b/chrome/browser/ui/webui/settings/site_settings_handler.h index 9e61c989..b60de36 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.h +++ b/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -14,18 +14,16 @@ #include "base/scoped_observer.h" #include "chrome/browser/browsing_data/cookies_tree_model.h" #include "chrome/browser/permissions/chooser_context_base.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" #include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "components/content_settings/core/browser/content_settings_observer.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/browser/host_zoom_map.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "ppapi/buildflags/buildflags.h" -class Profile; - class PrefChangeRegistrar; namespace base { @@ -37,7 +35,7 @@ // Chrome "ContentSettings" settings page UI handler. class SiteSettingsHandler : public SettingsPageUIHandler, public content_settings::Observer, - public content::NotificationObserver, + public ProfileObserver, public ChooserContextBase::PermissionObserver, public CookiesTreeModel::Observer { public: @@ -79,10 +77,9 @@ ContentSettingsType content_type, const std::string& resource_identifier) override; - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + // ProfileObserver: + void OnOffTheRecordProfileCreated(Profile* off_the_record) override; + void OnProfileWillBeDestroyed(Profile* profile) override; // ChooserContextBase::PermissionObserver implementation: void OnChooserObjectPermissionChanged( @@ -246,7 +243,7 @@ Profile* profile_; web_app::AppRegistrar& app_registrar_; - content::NotificationRegistrar notification_registrar_; + ScopedObserver<Profile, ProfileObserver> observed_profiles_{this}; // Keeps track of events related to zooming. std::unique_ptr<content::HostZoomMap::Subscription>
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc index 74ee718..e3aa490 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" #include "chrome/browser/browsing_data/mock_browsing_data_cookie_helper.h" #include "chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/test_extension_system.h" @@ -48,7 +47,6 @@ #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/ukm/test_ukm_recorder.h" #include "content/public/browser/navigation_controller.h" -#include "content/public/browser/notification_service.h" #include "content/public/browser/web_ui_data_source.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_web_ui.h" @@ -396,10 +394,6 @@ } virtual void DestroyIncognitoProfile() { - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PROFILE_DESTROYED, - content::Source<Profile>(static_cast<Profile*>(incognito_profile_)), - content::NotificationService::NoDetails()); profile_.SetOffTheRecordProfile(nullptr); ASSERT_FALSE(profile_.HasOffTheRecordProfile()); incognito_profile_ = nullptr;
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc index 76043fc..5c55d08 100644 --- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc +++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc
@@ -472,6 +472,8 @@ static constexpr LocalizedString kStrings[] = { {"tabListTitle", IDS_ACCNAME_TAB_LIST}, {"closeTab", IDS_ACCNAME_CLOSE}, + {"defaultTabTitle", IDS_DEFAULT_TAB_TITLE}, + {"loadingTab", IDS_TAB_LOADING_TITLE}, {"tabCrashed", IDS_TAB_AX_LABEL_CRASHED_FORMAT}, {"tabNetworkError", IDS_TAB_AX_LABEL_NETWORK_ERROR_FORMAT}, {"audioPlaying", IDS_TAB_AX_LABEL_AUDIO_PLAYING_FORMAT},
diff --git a/chrome/chrome_cleaner/constants/chrome_cleaner_switches.cc b/chrome/chrome_cleaner/constants/chrome_cleaner_switches.cc index be2b268..bfd5288 100644 --- a/chrome/chrome_cleaner/constants/chrome_cleaner_switches.cc +++ b/chrome/chrome_cleaner/constants/chrome_cleaner_switches.cc
@@ -78,6 +78,10 @@ // Specify the time to wait between logs upload retries, in minutes. const char kLogUploadRetryIntervalSwitch[] = "logs-upload-retry-interval"; +// The Mojo pipe token for IPC communication between the Software Reporter and +// Chrome. Dropped in M80. +const char kChromeMojoPipeTokenSwitch[] = "chrome-mojo-pipe-token"; + // Prevent the crash client from uploading crash reports. const char kNoCrashUploadSwitch[] = "no-crash-upload";
diff --git a/chrome/chrome_cleaner/constants/chrome_cleaner_switches.h b/chrome/chrome_cleaner/constants/chrome_cleaner_switches.h index 644c626..48096c9 100644 --- a/chrome/chrome_cleaner/constants/chrome_cleaner_switches.h +++ b/chrome/chrome_cleaner/constants/chrome_cleaner_switches.h
@@ -54,6 +54,13 @@ extern const char kRunWithoutSandboxForTestingSwitch[]; #endif +// Deprecated switches that were set by older Chrome versions. +// These must still be handled until we drop support for those versions. + +// The Mojo pipe token for IPC communication between the Software Reporter and +// Chrome. Dropped in M80. +extern const char kChromeMojoPipeTokenSwitch[]; + } // namespace chrome_cleaner #endif // CHROME_CHROME_CLEANER_CONSTANTS_CHROME_CLEANER_SWITCHES_H_
diff --git a/chrome/chrome_cleaner/engines/broker/cleaner_sandbox_interface_unittest.cc b/chrome/chrome_cleaner/engines/broker/cleaner_sandbox_interface_unittest.cc index 8e2c1ede..494d513 100644 --- a/chrome/chrome_cleaner/engines/broker/cleaner_sandbox_interface_unittest.cc +++ b/chrome/chrome_cleaner/engines/broker/cleaner_sandbox_interface_unittest.cc
@@ -327,6 +327,49 @@ EXPECT_FALSE(base::PathExists(file_path)); } +TEST_F(CleanerSandboxInterfaceDeleteFileTest, QuotedPath) { + base::ScopedTempDir temp; + ASSERT_TRUE(temp.CreateUniqueTempDir()); + base::FilePath file_path = temp.GetPath().Append(L"temp_file.exe"); + + ASSERT_TRUE(chrome_cleaner::CreateFileInFolder( + file_path.DirName(), file_path.BaseName().value().c_str())); + + const base::FilePath quoted_path(L"\"" + file_path.value() + L"\""); + + // RemoveNow should reject the file name because it starts with an invalid + // character. This needs to match the behaviour of SandboxOpenFileReadOnly, + // which is tested in ScannerSandboxInterface_OpenReadOnlyFile.BasicFile, + // since the same path could be passed to both. + chrome_cleaner::VerifyRemoveNowFailure(quoted_path, file_remover_.get()); + EXPECT_TRUE(base::PathExists(file_path)); +} + +TEST_F(CleanerSandboxInterfaceDeleteFileTest, QuotedFilename) { + base::ScopedTempDir temp; + ASSERT_TRUE(temp.CreateUniqueTempDir()); + base::FilePath file_path = temp.GetPath().Append(L"temp_file.exe"); + + ASSERT_TRUE(chrome_cleaner::CreateFileInFolder( + file_path.DirName(), file_path.BaseName().value().c_str())); + + const base::FilePath quoted_path = + temp.GetPath().Append(L"\"temp_file.exe\""); + + // RemoveNow should return true because the file name is valid, but refers to + // a file that already doesn't exist. The important thing is that the quotes + // aren't interpreted, which would cause '"temp_file.exe"' and + // 'temp_file.exe' to refer to the same thing. + // + // This needs to match the behaviour of SandboxOpenFileReadOnly, which is + // tested in ScannerSandboxInterface_OpenReadOnlyFile.BasicFile, since the + // same path could be passed to both. It would also be ok if both RemoveNow + // and OpenFileReadOnly interpreted the quotes, as long as their behaviour + // matches. + chrome_cleaner::VerifyRemoveNowSuccess(quoted_path, file_remover_.get()); + EXPECT_TRUE(base::PathExists(file_path)); +} + TEST_F(CleanerSandboxInterfaceDeleteFileTest, DeleteAlternativeStream) { base::ScopedTempDir temp; ASSERT_TRUE(temp.CreateUniqueTempDir());
diff --git a/chrome/chrome_cleaner/engines/broker/scanner_sandbox_interface_unittest.cc b/chrome/chrome_cleaner/engines/broker/scanner_sandbox_interface_unittest.cc index b706537..156d7df 100644 --- a/chrome/chrome_cleaner/engines/broker/scanner_sandbox_interface_unittest.cc +++ b/chrome/chrome_cleaner/engines/broker/scanner_sandbox_interface_unittest.cc
@@ -607,6 +607,24 @@ handle = SandboxOpenReadOnlyFile(base::FilePath(path_with_space), FILE_ATTRIBUTE_NORMAL); EXPECT_TRUE(handle.IsValid()); + + // Make sure quotes aren't interpreted. The same path might be passed to + // SandboxDeleteFile, which doesn't interpret quotes. + const base::FilePath quoted_path(L"\"" + file_path.value() + L"\""); + handle = SandboxOpenReadOnlyFile(quoted_path, FILE_ATTRIBUTE_NORMAL); + EXPECT_FALSE(handle.IsValid()) + << "SandboxOpenReadOnlyFile is interpreting quotes around path names; " + "this will cause problems if the same path is passed to DeleteFile " + "(see CleanerSandboxInterfaceDeleteFileTest.QuotedPath)"; + + const base::FilePath partly_quoted_path = + temp.GetPath().Append(L"\"temp_file.exe\""); + handle = SandboxOpenReadOnlyFile(partly_quoted_path, FILE_ATTRIBUTE_NORMAL); + EXPECT_FALSE(handle.IsValid()) + << "SandboxOpenReadOnlyFile is interpreting quotes around path " + "components; this will cause problems if the same path is passed to " + "DeleteFile (see " + "CleanerSandboxInterfaceDeleteFileTest.QuotedFilename)"; } TEST_F(ScannerSandboxInterface_OpenReadOnlyFile, NoFile) {
diff --git a/chrome/chrome_cleaner/ipc/BUILD.gn b/chrome/chrome_cleaner/ipc/BUILD.gn index 83c6e79..be33dde 100644 --- a/chrome/chrome_cleaner/ipc/BUILD.gn +++ b/chrome/chrome_cleaner/ipc/BUILD.gn
@@ -31,7 +31,7 @@ deps = [ ":mojo_task_runner", "//base", - "//components/chrome_cleaner/public/interfaces", + "//chrome/chrome_cleaner/mojom:chrome_prompt_interface", "//mojo/public/cpp/platform", "//mojo/public/cpp/system", ] @@ -106,11 +106,11 @@ "//base/test:test_support", "//chrome/chrome_cleaner:buildflags", "//chrome/chrome_cleaner/logging:common", + "//chrome/chrome_cleaner/mojom:chrome_prompt_interface", "//chrome/chrome_cleaner/mojom:mojo_sandbox_hooks_test_interface", "//chrome/chrome_cleaner/os:common_os", "//chrome/chrome_cleaner/test:test_util", "//components/chrome_cleaner/public/constants", - "//components/chrome_cleaner/public/interfaces", "//components/chrome_cleaner/public/proto", "//components/chrome_cleaner/public/proto:test_only_proto", "//components/chrome_cleaner/test:test_name_helper",
diff --git a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h index 36d7e90..996e1e3 100644 --- a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h +++ b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h
@@ -14,7 +14,7 @@ #include "base/strings/string16.h" #include "chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h" #include "chrome/chrome_cleaner/ipc/mojo_task_runner.h" -#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h" +#include "chrome/chrome_cleaner/mojom/chrome_prompt.mojom.h" namespace chrome_cleaner {
diff --git a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc index 0d503b45..e4a9a1a 100644 --- a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc +++ b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc
@@ -18,8 +18,8 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "chrome/chrome_cleaner/ipc/ipc_test_util.h" #include "chrome/chrome_cleaner/logging/scoped_logging.h" +#include "chrome/chrome_cleaner/mojom/chrome_prompt.mojom.h" #include "chrome/chrome_cleaner/test/test_util.h" -#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h" #include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h" #include "components/chrome_cleaner/test/test_name_helper.h" #include "mojo/public/cpp/bindings/binding.h"
diff --git a/chrome/chrome_cleaner/mojom/BUILD.gn b/chrome/chrome_cleaner/mojom/BUILD.gn index 96157e68..680e1ed 100644 --- a/chrome/chrome_cleaner/mojom/BUILD.gn +++ b/chrome/chrome_cleaner/mojom/BUILD.gn
@@ -18,6 +18,26 @@ } } +chrome_cleaner_mojom("chrome_prompt_interface") { + sources = [ + "chrome_prompt.mojom", + ] + + deps = [ + ":footprints_interface", + ] + + # NOTE: We avoid scrambling message IDs here because these messages cross an + # IPC boundary to an external program built from a different source tree. + scramble_message_ids = false +} + +chrome_cleaner_mojom("footprints_interface") { + sources = [ + "footprints.mojom", + ] +} + chrome_cleaner_mojom("engine_sandbox_interface") { sources = [ "cleaner_engine_requests.mojom", @@ -29,7 +49,7 @@ "windows_handle.mojom", ] deps = [ - "//components/chrome_cleaner/public/interfaces", + ":footprints_interface", "//mojo/public/mojom/base", ] }
diff --git a/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom b/chrome/chrome_cleaner/mojom/chrome_prompt.mojom similarity index 78% rename from components/chrome_cleaner/public/interfaces/chrome_prompt.mojom rename to chrome/chrome_cleaner/mojom/chrome_prompt.mojom index f475fcdd..f799afe8 100644 --- a/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom +++ b/chrome/chrome_cleaner/mojom/chrome_prompt.mojom
@@ -4,15 +4,23 @@ module chrome_cleaner.mojom; -// IMPORTANT NOTE: Avoid adding dependencies to typemapped .mojom files. -// Enabling typemaps currently (as of July 2017) requires indirectly depending -// on all existing typemap definitions. The Chrome Cleaner is built -// independently from Chromium and would like to avoid these dependencies. +// This interface was used to communicate between Chrome and the Chrome Cleanup +// until M80, when it was replaced by +// components/chrome_cleaner/public/proto/chrome_prompt.proto. It must be +// supported until we drop support for Chrome M79 and earlier. + +// IMPORTANT NOTE: Avoid adding dependencies to typemapped .mojom files outside +// the chrome/chrome_cleaner directory. Enabling typemaps currently (as of +// July 2017) requires indirectly depending on all existing typemap +// definitions. The Chrome Cleaner is built independently from Chromium and +// would like to avoid these dependencies. // Once it's possible to specify a limited subset of typemaps to use, be // careful not to add dependencies to [Native] mojo structures. The wire format // for [Native] structs is not guaranteed to be consistent between versions. +import "chrome/chrome_cleaner/mojom/footprints.mojom"; + [Extensible] enum PromptAcceptance { UNSPECIFIED = 0, @@ -27,21 +35,6 @@ NUM_VALUES, }; -struct FilePath { - array<uint16> value; -}; - -struct RegistryKey { - // A string formatted for display to the user. - // Example: HKCU:32\software\unwanted_software - array<uint16> value; -}; - -struct ExtensionId { - // A 32-character extension ID. - array<uint16> value; -}; - // Service provided by Chrome to prompt the user to start a cleanup if the // Chrome Cleanup Tool detects unwanted software on the system. interface ChromePrompt {
diff --git a/chrome/chrome_cleaner/mojom/cleaner_engine_requests.mojom b/chrome/chrome_cleaner/mojom/cleaner_engine_requests.mojom index 3164121..a05dddbd 100644 --- a/chrome/chrome_cleaner/mojom/cleaner_engine_requests.mojom +++ b/chrome/chrome_cleaner/mojom/cleaner_engine_requests.mojom
@@ -4,8 +4,8 @@ module chrome_cleaner.mojom; +import "chrome/chrome_cleaner/mojom/footprints.mojom"; import "chrome/chrome_cleaner/mojom/string16_embedded_nulls.mojom"; -import "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom"; import "mojo/public/mojom/base/string16.mojom"; // Passes requests that can mutate the system from the low-privilege sandbox
diff --git a/chrome/chrome_cleaner/mojom/engine_file_requests.mojom b/chrome/chrome_cleaner/mojom/engine_file_requests.mojom index beba962e..066b9f4 100644 --- a/chrome/chrome_cleaner/mojom/engine_file_requests.mojom +++ b/chrome/chrome_cleaner/mojom/engine_file_requests.mojom
@@ -4,7 +4,7 @@ module chrome_cleaner.mojom; -import "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom"; +import "chrome/chrome_cleaner/mojom/footprints.mojom"; // Handles returned by FindFirstFile aren't real handles, so we can't pass them // through mojo as handles, since they can't be duplicated.
diff --git a/chrome/chrome_cleaner/mojom/engine_requests.mojom b/chrome/chrome_cleaner/mojom/engine_requests.mojom index 276805d0..b15bee4 100644 --- a/chrome/chrome_cleaner/mojom/engine_requests.mojom +++ b/chrome/chrome_cleaner/mojom/engine_requests.mojom
@@ -4,9 +4,9 @@ module chrome_cleaner.mojom; +import "chrome/chrome_cleaner/mojom/footprints.mojom"; import "chrome/chrome_cleaner/mojom/string16_embedded_nulls.mojom"; import "chrome/chrome_cleaner/mojom/windows_handle.mojom"; -import "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom"; import "mojo/public/mojom/base/process_id.mojom"; import "mojo/public/mojom/base/string16.mojom";
diff --git a/chrome/chrome_cleaner/mojom/engine_sandbox.mojom b/chrome/chrome_cleaner/mojom/engine_sandbox.mojom index 687549b..64636ab 100644 --- a/chrome/chrome_cleaner/mojom/engine_sandbox.mojom +++ b/chrome/chrome_cleaner/mojom/engine_sandbox.mojom
@@ -4,11 +4,11 @@ module chrome_cleaner.mojom; +import "chrome/chrome_cleaner/mojom/footprints.mojom"; import "chrome/chrome_cleaner/mojom/cleaner_engine_requests.mojom"; import "chrome/chrome_cleaner/mojom/engine_requests.mojom"; import "chrome/chrome_cleaner/mojom/engine_file_requests.mojom"; import "chrome/chrome_cleaner/mojom/pup.mojom"; -import "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom"; // All result_code parameters and return values in these interfaces are either // an EngineResultCode or, if higher than EngineResultCode::kEngineInternal, an
diff --git a/chrome/chrome_cleaner/mojom/footprints.mojom b/chrome/chrome_cleaner/mojom/footprints.mojom new file mode 100644 index 0000000..a80607f6 --- /dev/null +++ b/chrome/chrome_cleaner/mojom/footprints.mojom
@@ -0,0 +1,20 @@ +// 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. + +module chrome_cleaner.mojom; + +struct FilePath { + array<uint16> value; +}; + +struct RegistryKey { + // A string formatted for display to the user. + // Example: HKCU:32\software\unwanted_software + array<uint16> value; +}; + +struct ExtensionId { + // A 32-character extension ID. + array<uint16> value; +};
diff --git a/chrome/chrome_cleaner/mojom/pup.mojom b/chrome/chrome_cleaner/mojom/pup.mojom index b0e7f53..3bab939 100644 --- a/chrome/chrome_cleaner/mojom/pup.mojom +++ b/chrome/chrome_cleaner/mojom/pup.mojom
@@ -4,8 +4,7 @@ module chrome_cleaner.mojom; -// chrome_prompt included for the FilePath struct. -import "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom"; +import "chrome/chrome_cleaner/mojom/footprints.mojom"; // Typemapped to chrome_cleaner::UwS::TraceLocation enumeration from // chrome_cleaner/logging/proto/shared_data.proto.
diff --git a/chrome/chrome_cleaner/mojom/typemaps/DEPS b/chrome/chrome_cleaner/mojom/typemaps/DEPS index b4c64d8..813ef00 100644 --- a/chrome/chrome_cleaner/mojom/typemaps/DEPS +++ b/chrome/chrome_cleaner/mojom/typemaps/DEPS
@@ -1,4 +1,10 @@ include_rules = [ + # Unlike the rest of chrome/chrome_cleaner this might be built on non-Windows + # platforms because it's included from the global + # chromium_bindings_configuration.gni. So it needs macros from + # build/build_config.h to check the platform. + '+build', + # Allow unit tests to set up a mojo embedder. '+mojo/core/embedder', ]
diff --git a/components/chrome_cleaner/public/typemaps/chrome_prompt.typemap b/chrome/chrome_cleaner/mojom/typemaps/footprints.typemap similarity index 63% rename from components/chrome_cleaner/public/typemaps/chrome_prompt.typemap rename to chrome/chrome_cleaner/mojom/typemaps/footprints.typemap index 3f6702b..2c15653 100644 --- a/components/chrome_cleaner/public/typemaps/chrome_prompt.typemap +++ b/chrome/chrome_cleaner/mojom/typemaps/footprints.typemap
@@ -2,16 +2,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//components/chrome_cleaner/public/interfaces/chrome_prompt.mojom" +mojom = "//chrome/chrome_cleaner/mojom/footprints.mojom" public_headers = [ "//base/files/file_path.h", "//base/strings/string16.h", ] -traits_headers = [ - "//components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.h", -] +traits_headers = + [ "//chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.h" ] sources = [ - "//components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.cc", + "//chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.cc", ] type_mappings = [
diff --git a/components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.cc b/chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.cc similarity index 96% rename from components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.cc rename to chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.cc index a55242c..165f744c 100644 --- a/components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.cc +++ b/chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.h" +#include "chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.h" #include "build/build_config.h" namespace mojo {
diff --git a/components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.h b/chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.h similarity index 78% rename from components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.h rename to chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.h index e1b52e6b..f31aea93 100644 --- a/components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.h +++ b/chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_CHROME_CLEANER_PUBLIC_TYPEMAPS_CHROME_PROMPT_MOJOM_TRAITS_H_ -#define COMPONENTS_CHROME_CLEANER_PUBLIC_TYPEMAPS_CHROME_PROMPT_MOJOM_TRAITS_H_ +#ifndef CHROME_CHROME_CLEANER_MOJOM_TYPEMAPS_FOOTPRINTS_MOJOM_TRAITS_H_ +#define CHROME_CHROME_CLEANER_MOJOM_TYPEMAPS_FOOTPRINTS_MOJOM_TRAITS_H_ #include "base/containers/span.h" #include "base/files/file_path.h" #include "base/strings/string16.h" -#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h" +#include "chrome/chrome_cleaner/mojom/footprints.mojom.h" namespace mojo { @@ -37,4 +37,4 @@ } // namespace mojo -#endif // COMPONENTS_CHROME_CLEANER_PUBLIC_TYPEMAPS_CHROME_PROMPT_MOJOM_TRAITS_H_ +#endif // CHROME_CHROME_CLEANER_MOJOM_TYPEMAPS_FOOTPRINTS_MOJOM_TRAITS_H_
diff --git a/chrome/chrome_cleaner/mojom/typemaps/pup_mojom_traits.cc b/chrome/chrome_cleaner/mojom/typemaps/pup_mojom_traits.cc index d6348a3..31a787d 100644 --- a/chrome/chrome_cleaner/mojom/typemaps/pup_mojom_traits.cc +++ b/chrome/chrome_cleaner/mojom/typemaps/pup_mojom_traits.cc
@@ -5,7 +5,7 @@ #include "chrome/chrome_cleaner/mojom/typemaps/pup_mojom_traits.h" #include "chrome/chrome_cleaner/logging/proto/shared_data.pb.h" -#include "components/chrome_cleaner/public/typemaps/chrome_prompt_mojom_traits.h" +#include "chrome/chrome_cleaner/mojom/typemaps/footprints_mojom_traits.h" #include "mojo/public/cpp/bindings/struct_traits.h" namespace mojo {
diff --git a/chrome/chrome_cleaner/mojom/typemaps/typemaps.gni b/chrome/chrome_cleaner/mojom/typemaps/typemaps.gni index 3bbd409..c3a7042 100644 --- a/chrome/chrome_cleaner/mojom/typemaps/typemaps.gni +++ b/chrome/chrome_cleaner/mojom/typemaps/typemaps.gni
@@ -3,6 +3,7 @@ # found in the LICENSE file. typemaps = [ + "//chrome/chrome_cleaner/mojom/typemaps/footprints.typemap", "//chrome/chrome_cleaner/mojom/typemaps/pup.typemap", "//chrome/chrome_cleaner/mojom/typemaps/string16_embedded_nulls.typemap", "//chrome/chrome_cleaner/mojom/typemaps/windows_handle.typemap",
diff --git a/chrome/common/extensions/api/accessibility_features.json b/chrome/common/extensions/api/accessibility_features.json index 4311c073b..499a89a3 100644 --- a/chrome/common/extensions/api/accessibility_features.json +++ b/chrome/common/extensions/api/accessibility_features.json
@@ -75,7 +75,7 @@ }, "switchAccess": { "$ref": "types.ChromeSetting", - "description": "<p><strong>ChromeOS only.</strong></p><p>Switch access. The value indicates whether the feature is enabled or not. <code>get()</code> requires <code>accessibilityFeatures.read</code> permission. <code>set()</code> and <code>clear()</code> require <code>accessibilityFeatures.modify</code> permission.</p>", + "description": "<p><strong>ChromeOS only.</strong></p><p>Switch Access. The value indicates whether the feature is enabled or not. <code>get()</code> requires <code>accessibilityFeatures.read</code> permission. <code>set()</code> and <code>clear()</code> require <code>accessibilityFeatures.modify</code> permission.</p>", "value": ["switchAccess", {"type": "boolean"}], "platforms": ["chromeos"] },
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index 75717b3..42efd95 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h
@@ -210,9 +210,9 @@ // Path to preinstalled Select-to-speak extension (relative to // |chrome::DIR_RESOURCES|). extern const char kSelectToSpeakExtensionPath[]; -// The extension id of the Switch access extension. +// The extension id of the Switch Access extension. extern const char kSwitchAccessExtensionId[]; -// Path to preinstalled Switch access extension (relative to +// Path to preinstalled Switch Access extension (relative to // |chrome::DIR_RESOURCES|). extern const char kSwitchAccessExtensionPath[]; // Name of the manifest file in an extension when a special manifest is used
diff --git a/chrome/common/search.mojom b/chrome/common/search.mojom index 4c71ce0a..2d46ff96 100644 --- a/chrome/common/search.mojom +++ b/chrome/common/search.mojom
@@ -181,8 +181,8 @@ ConfirmThemeChanges(); // Gets autocomplete matches from the browser. - QueryAutocomplete(mojo_base.mojom.String16 input) => - (AutocompleteResult result); + QueryAutocomplete(mojo_base.mojom.String16 input, + bool prevent_inline_autocomplete) => (AutocompleteResult result); // Deletes the AutocompleteMatch in the current results by |line| number if // it is deletable. When a match is deleted, |matches| is populated with the
diff --git a/chrome/renderer/searchbox/searchbox.cc b/chrome/renderer/searchbox/searchbox.cc index 5c270d29..f4fd1982 100644 --- a/chrome/renderer/searchbox/searchbox.cc +++ b/chrome/renderer/searchbox/searchbox.cc
@@ -438,10 +438,12 @@ embedded_search_service_->ConfirmThemeChanges(); } -void SearchBox::QueryAutocomplete(const base::string16& input) { +void SearchBox::QueryAutocomplete(const base::string16& input, + bool prevent_inline_autocomplete) { embedded_search_service_->QueryAutocomplete( - input, base::BindOnce(&SearchBox::QueryAutocompleteResult, - weak_ptr_factory_.GetWeakPtr())); + input, prevent_inline_autocomplete, + base::BindOnce(&SearchBox::QueryAutocompleteResult, + weak_ptr_factory_.GetWeakPtr())); } void SearchBox::DeleteAutocompleteMatch(uint8_t line) {
diff --git a/chrome/renderer/searchbox/searchbox.h b/chrome/renderer/searchbox/searchbox.h index c4e0d4d1..d185c54 100644 --- a/chrome/renderer/searchbox/searchbox.h +++ b/chrome/renderer/searchbox/searchbox.h
@@ -190,8 +190,11 @@ void ConfirmThemeChanges(); // Queries the autocomplete backend for realbox results for |input| as a - // search term. Handled by |QueryAutocompleteResult|. - void QueryAutocomplete(const base::string16& input); + // search term. |prevent_inline_autocomplete| is true if the result set should + // not require inline autocomplete for the default match. Handled by + // |QueryAutocompleteResult|. + void QueryAutocomplete(const base::string16& input, + bool prevent_inline_autocomplete); // Deletes |AutocompleteMatch| by index of the result. void DeleteAutocompleteMatch(uint8_t line);
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index fdaf0cc..faaa7601 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -593,7 +593,8 @@ // Handlers for JS functions. static void DeleteAutocompleteMatch(int line); static void Paste(const std::string& text); - static void QueryAutocomplete(const base::string16& input); + static void QueryAutocomplete(const base::string16& input, + bool prevent_inline_autocomplete); static void StopAutocomplete(bool clear_result); static void StartCapturingKeyStrokes(); static void StopCapturingKeyStrokes(); @@ -660,11 +661,12 @@ } // static -void SearchBoxBindings::QueryAutocomplete(const base::string16& input) { +void SearchBoxBindings::QueryAutocomplete(const base::string16& input, + bool prevent_inline_autocomplete) { SearchBox* search_box = GetSearchBoxForCurrentContext(); if (!search_box) return; - search_box->QueryAutocomplete(input); + search_box->QueryAutocomplete(input, prevent_inline_autocomplete); } // static
diff --git a/chrome/test/base/interactive_test_utils_mac.mm b/chrome/test/base/interactive_test_utils_mac.mm index d461e02..a6b4fc9 100644 --- a/chrome/test/base/interactive_test_utils_mac.mm +++ b/chrome/test/base/interactive_test_utils_mac.mm
@@ -29,7 +29,9 @@ // Callback for MockCrApplication. void ObserveSendEvent(NSEvent* event); - IMP original_send_event() const { return original_send_event_; } + void OriginalSendEvent(id receiver, SEL selector, NSEvent* event) { + scoped_swizzler_->InvokeOriginal<void, NSEvent*>(receiver, selector, event); + } void SendGlobalKeyEventsAndWait(int key_code, int modifier_flags); @@ -39,7 +41,6 @@ bool key_down); std::unique_ptr<base::mac::ScopedObjCClassSwizzler> scoped_swizzler_; - IMP original_send_event_ = nullptr; base::ScopedCFTypeRef<CGEventSourceRef> event_source_; CGEventTapLocation event_tap_location_; base::RunLoop run_loop_; @@ -62,7 +63,7 @@ - (void)sendEvent:(NSEvent*)event { DCHECK(g_global_key_events_helper); g_global_key_events_helper->ObserveSendEvent(event); - g_global_key_events_helper->original_send_event()(self, _cmd, event); + g_global_key_events_helper->OriginalSendEvent(self, _cmd, event); } @end @@ -78,7 +79,6 @@ scoped_swizzler_ = std::make_unique<base::mac::ScopedObjCClassSwizzler>( [BrowserCrApplication class], [MockCrApplication class], @selector(sendEvent:)); - original_send_event_ = scoped_swizzler_->GetOriginalImplementation(); } SendGlobalKeyEventsHelper::~SendGlobalKeyEventsHelper() {
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index b013c79..95dbb48 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -545,6 +545,9 @@ // must be initialized when the testing profile finishes its initialization. signin_util::EnsureUserSignoutAllowedIsInitializedForProfile(this); } + + if (original_profile_) + original_profile_->NotifyOffTheRecordProfileCreated(this); } TestingProfile::~TestingProfile() {
diff --git a/chrome/test/chromedriver/js/get_element_location.js b/chrome/test/chromedriver/js/get_element_location.js index dcdb2530..5397fb0 100644 --- a/chrome/test/chromedriver/js/get_element_location.js +++ b/chrome/test/chromedriver/js/get_element_location.js
@@ -20,8 +20,8 @@ var top = Math.max(0, rect.top); var bottom = Math.min(window.innerHeight, rect.bottom); - // Find the view boundry of the element by checking itself and all of its - // ancestor's boundry. + // Find the view boundary of the element by checking itself and all of its + // ancestor's boundary. while (element.parentElement != null && element.parentElement != document.body && element.parentElement.getClientRects().length > 0) { @@ -30,21 +30,26 @@ var overflowX = parentStyle.getPropertyValue("overflow-x"); var overflowY = parentStyle.getPropertyValue("overflow-y"); var parentRect = getParentRect(element); - if (overflow == "auto" || overflow == "scroll" || overflow == "hidden") { - left = Math.max(left, parentRect.left); - right = Math.min(right, parentRect.right); - top = Math.max(top, parentRect.top); - bottom = Math.min(bottom, parentRect.bottom); - } else { - if (overflowX == "auto" || overflowX == "scroll" || - overflowX == "hidden") { + // Only consider about overflow cases when the parent area overlaps with + // the element's area. + if (parentRect.right > left && parentRect.bottom > top && + right > parentRect.left && bottom > parentRect.top) { + if (overflow == "auto" || overflow == "scroll" || overflow == "hidden") { left = Math.max(left, parentRect.left); right = Math.min(right, parentRect.right); - } - if (overflowY == "auto" || overflowY == "scroll" || - overflowY == "hidden") { top = Math.max(top, parentRect.top); bottom = Math.min(bottom, parentRect.bottom); + } else { + if (overflowX == "auto" || overflowX == "scroll" || + overflowX == "hidden") { + left = Math.max(left, parentRect.left); + right = Math.min(right, parentRect.right); + } + if (overflowY == "auto" || overflowY == "scroll" || + overflowY == "hidden") { + top = Math.max(top, parentRect.top); + bottom = Math.min(bottom, parentRect.bottom); + } } } element = element.parentElement; @@ -52,7 +57,6 @@ var x = 0.5 * (left + right); var y = 0.5 * (top + bottom); - return [x, y, left, top]; }
diff --git a/chrome/test/data/android/render_tests/StartSurfaceLayoutTest.3_incognito_ntps.Nexus_5-19.png.sha1 b/chrome/test/data/android/render_tests/StartSurfaceLayoutTest.3_incognito_ntps.Nexus_5-19.png.sha1 deleted file mode 100644 index 59c7543..0000000 --- a/chrome/test/data/android/render_tests/StartSurfaceLayoutTest.3_incognito_ntps.Nexus_5-19.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -aa72b682f2a1056919067f870c576e0f9f531302 \ No newline at end of file
diff --git a/chrome/test/data/local_ntp/realbox_browsertest.js b/chrome/test/data/local_ntp/realbox_browsertest.js index 0bcfc0bf..5b4ae7a5 100644 --- a/chrome/test/data/local_ntp/realbox_browsertest.js +++ b/chrome/test/data/local_ntp/realbox_browsertest.js
@@ -84,7 +84,10 @@ modifiers); }; -/** @type {!Array<string>} */ +/** @typedef {{input: string, preventInlineAutocomplete: bool}} */ +let AutocompleteQuery; + +/** @type {!Array<AutocompleteQuery>} */ test.realbox.queries; /** @type {!Array<number>} */ @@ -108,8 +111,11 @@ deleteAutocompleteMatch(line) { test.realbox.deletedLines.push(line); }, - queryAutocomplete(query) { - test.realbox.queries.push(query); + queryAutocomplete(input, preventInlineAutocomplete) { + test.realbox.queries.push({ + input: input, + preventInlineAutocomplete: preventInlineAutocomplete + }); }, stopAutocomplete(clearResult) {} }, @@ -146,14 +152,14 @@ test.realbox.realboxEl.value = 'hello realbox'; test.realbox.realboxEl.dispatchEvent(new CustomEvent('input')); assertEquals(1, test.realbox.queries.length); - assertEquals('hello realbox', test.realbox.queries[0]); + assertEquals('hello realbox', test.realbox.queries[0].input); }; test.realbox.testReplyWithMatches = function() { test.realbox.realboxEl.value = 'hello world'; test.realbox.realboxEl.dispatchEvent(new CustomEvent('input')); assertEquals(1, test.realbox.queries.length); - assertEquals('hello world', test.realbox.queries[0]); + assertEquals('hello world', test.realbox.queries[0].input); const matches = [test.realbox.getSearchMatch(), test.realbox.getUrlMatch()]; chrome.embeddedSearch.searchBox.onqueryautocompletedone( @@ -176,7 +182,7 @@ test.realbox.realboxEl.value = 'hello '; test.realbox.realboxEl.dispatchEvent(new CustomEvent('input')); assertEquals(1, test.realbox.queries.length); - assertEquals('hello ', test.realbox.queries[0]); + assertEquals('hello ', test.realbox.queries[0].input); const match = test.realbox.getSearchMatch({ contents: 'hello ', @@ -202,11 +208,14 @@ assertEquals('world', realboxValue.substring(start, end)); }; +// Ensures that deleting text from input informs the backend to prevent inline +// autocompletion for the default match. test.realbox.testDeleteWithInlineAutocompletion = function() { test.realbox.realboxEl.value = 'supercal'; test.realbox.realboxEl.dispatchEvent(new CustomEvent('input')); assertEquals(1, test.realbox.queries.length); - assertEquals('supercal', test.realbox.queries[0]); + assertEquals('supercal', test.realbox.queries[0].input); + assertFalse(test.realbox.queries[0].preventInlineAutocomplete); const match = test.realbox.getSearchMatch({ contents: 'supercal', @@ -222,28 +231,18 @@ test.realbox.realboxEl.value = 'superca'; test.realbox.realboxEl.dispatchEvent(new CustomEvent('input')); + assertEquals(2, test.realbox.queries.length); + assertEquals('superca', test.realbox.queries[1].input); + assertTrue(test.realbox.queries[1].preventInlineAutocomplete) match.contents = 'superca'; - match.inlineAutocompletion = 'lifragilisticexpialidocious'; + match.inlineAutocompletion = ''; chrome.embeddedSearch.searchBox.onqueryautocompletedone({ input: test.realbox.realboxEl.value, matches: [match], }); - // Ensure that removing characters from input doesn't just inline autocomplete - // to the same contents on backspace/cut/etc. assertEquals('superca', test.realbox.realboxEl.value); - - test.realbox.realboxEl.value = 'super'; - test.realbox.realboxEl.dispatchEvent(new CustomEvent('input')); - - match.contents = 'super'; - match.inlineAutocompletion = 'califragilisticexpialidocious'; - chrome.embeddedSearch.searchBox.onqueryautocompletedone({ - input: test.realbox.realboxEl.value, - matches: [match], - }); - assertEquals('super', test.realbox.realboxEl.value); }; test.realbox.testTypeInlineAutocompletion = function() { @@ -857,7 +856,7 @@ assertEquals(1, test.realbox.queries.length); chrome.embeddedSearch.searchBox.onqueryautocompletedone({ - input: test.realbox.queries[0], + input: test.realbox.queries[0].input, matches: [test.realbox.getSearchMatch()], }); @@ -900,7 +899,7 @@ assertEquals(1, test.realbox.queries.length); chrome.embeddedSearch.searchBox.onqueryautocompletedone({ - input: test.realbox.queries[0], + input: test.realbox.queries[0].input, matches: [test.realbox.getSearchMatch()], });
diff --git a/chrome/test/data/webui/tab_strip/tab_test.js b/chrome/test/data/webui/tab_strip/tab_test.js index ca159f5..d99d66f 100644 --- a/chrome/test/data/webui/tab_strip/tab_test.js +++ b/chrome/test/data/webui/tab_strip/tab_test.js
@@ -27,6 +27,7 @@ const strings = { closeTab: 'Close tab', + loadingTab: 'Loading...', tabCrashed: '$1 has crashed', tabNetworkError: '$1 has a network error', }; @@ -195,6 +196,18 @@ tab.title, tabElement.shadowRoot.querySelector('#titleText').innerText); }); + test('sets the loading title while loading', () => { + const loadingTabWithoutTitle = Object.assign({}, tab, { + networkState: TabNetworkState.WAITING, + shouldHideThrobber: false, + }); + delete loadingTabWithoutTitle.title; + tabElement.tab = loadingTabWithoutTitle; + assertEquals( + strings['loadingTab'], + tabElement.shadowRoot.querySelector('#titleText').innerText); + }); + test('exposes the tab ID to an attribute', () => { tabElement.tab = Object.assign({}, tab, {id: 1001}); assertEquals('1001', tabElement.getAttribute('data-tab-id'));
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn index e482914..4b0f1eb 100644 --- a/chromecast/BUILD.gn +++ b/chromecast/BUILD.gn
@@ -659,6 +659,9 @@ android_manifest = "$root_gen_dir/cast_shell_manifest/AndroidManifest.xml" android_manifest_dep = "//chromecast/browser/android:cast_shell_manifest" + min_sdk_version = 21 + target_sdk_version = 28 + shared_libraries = [ "//chromecast/android:libcast_shell_android" ] product_config_java_packages = [ "org.chromium.chromecast.shell" ]
diff --git a/chromecast/browser/android/apk/AndroidManifest.xml.jinja2 b/chromecast/browser/android/apk/AndroidManifest.xml.jinja2 index c857253..67297710 100644 --- a/chromecast/browser/android/apk/AndroidManifest.xml.jinja2 +++ b/chromecast/browser/android/apk/AndroidManifest.xml.jinja2
@@ -8,6 +8,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.chromium.chromecast.shell"> + <uses-sdk android:minSdkVersion="21" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WAKE_LOCK"/>
diff --git a/chromecast/media/cma/backend/multizone_backend_unittest.cc b/chromecast/media/cma/backend/multizone_backend_unittest.cc index 220bc4d..e144c41 100644 --- a/chromecast/media/cma/backend/multizone_backend_unittest.cc +++ b/chromecast/media/cma/backend/multizone_backend_unittest.cc
@@ -368,7 +368,10 @@ kMaxRenderingDelayErrorUs); } -TEST_P(MultizoneBackendTest, RenderingDelay) { +// TODO(b/143135800): The new mixer backend didn't calculate the rendering delay +// correctly when playback rate changes. Temporary disable the test to unblock +// PoG. +TEST_P(MultizoneBackendTest, DISABLED_RenderingDelay) { const TestParams& params = GetParam(); int sample_rate = testing::get<0>(params); float playback_rate = testing::get<1>(params); @@ -380,7 +383,7 @@ Start(playback_rate); } -TEST_F(MultizoneBackendTest, RenderingDelayWithMultipleRateChanges) { +TEST_F(MultizoneBackendTest, DISABLED_RenderingDelayWithMultipleRateChanges) { Initialize(48000 /* sample_rate */, 10 /* playback_rate_change_count */); AddEffectsStreams(); Start(1.0f /* playback_rate */);
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 8722e24..6ce06d7 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -316,9 +316,22 @@ return base::FeatureList::IsEnabled(kSplitSettingsSync); } +bool ShouldDeprecateV1DeviceSync() { + return ShouldUseV2DeviceSync() && + base::FeatureList::IsEnabled( + chromeos::features::kCryptAuthV1DeviceSyncDeprecate); +} + bool ShouldShowPlayStoreInDemoMode() { return base::FeatureList::IsEnabled(kShowPlayInDemoMode); } +bool ShouldUseV2DeviceSync() { + return base::FeatureList::IsEnabled( + chromeos::features::kCryptAuthV2Enrollment) && + base::FeatureList::IsEnabled( + chromeos::features::kCryptAuthV2DeviceSync); +} + } // namespace features } // namespace chromeos
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index 2d17f750..93a120b7 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -141,10 +141,13 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsParentalControlsSettingsEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsSplitSettingsEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsSplitSettingsSyncEnabled(); +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool ShouldDeprecateV1DeviceSync(); // TODO(michaelpg): Remove after M71 branch to re-enable Play Store by default. COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool ShouldShowPlayStoreInDemoMode(); +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool ShouldUseV2DeviceSync(); + // Keep alphabetized. } // namespace features
diff --git a/chromeos/network/network_connect.cc b/chromeos/network/network_connect.cc index a24406b..f14ef962 100644 --- a/chromeos/network/network_connect.cc +++ b/chromeos/network/network_connect.cc
@@ -491,7 +491,12 @@ void NetworkConnect::Shutdown() { CHECK(g_network_connect); delete g_network_connect; - g_network_connect = NULL; + g_network_connect = nullptr; +} + +// static +bool NetworkConnect::IsInitialized() { + return g_network_connect; } // static
diff --git a/chromeos/network/network_connect.h b/chromeos/network/network_connect.h index c39887a..0efcf22f4e 100644 --- a/chromeos/network/network_connect.h +++ b/chromeos/network/network_connect.h
@@ -60,7 +60,10 @@ // Destroys the global NetworkConnect object. static void Shutdown(); - // Returns the global NetworkConnect object if initialized or NULL. + // Returns true if the global NetworkConnect object is initialized. + static bool IsInitialized(); + + // Returns the global NetworkConnect object if initialized or null. static NetworkConnect* Get(); virtual ~NetworkConnect();
diff --git a/chromeos/services/device_sync/device_sync_impl.cc b/chromeos/services/device_sync/device_sync_impl.cc index 8b91dc2..1e1388ab 100644 --- a/chromeos/services/device_sync/device_sync_impl.cc +++ b/chromeos/services/device_sync/device_sync_impl.cc
@@ -21,6 +21,7 @@ #include "chromeos/services/device_sync/cryptauth_device_registry_impl.h" #include "chromeos/services/device_sync/cryptauth_enroller_factory_impl.h" #include "chromeos/services/device_sync/cryptauth_enrollment_manager_impl.h" +#include "chromeos/services/device_sync/cryptauth_feature_status_setter_impl.h" #include "chromeos/services/device_sync/cryptauth_gcm_manager_impl.h" #include "chromeos/services/device_sync/cryptauth_key_registry_impl.h" #include "chromeos/services/device_sync/cryptauth_scheduler_impl.h" @@ -89,13 +90,6 @@ kMaxValue = kUnexpectedClientFeature }; -bool ShouldUseV2DeviceSync() { - return base::FeatureList::IsEnabled( - chromeos::features::kCryptAuthV2Enrollment) && - base::FeatureList::IsEnabled( - chromeos::features::kCryptAuthV2DeviceSync); -} - DeviceSyncRequestFailureReason GetDeviceSyncRequestFailureReason( mojom::NetworkRequestResult failure_reason) { switch (failure_reason) { @@ -246,7 +240,7 @@ bool DeviceSyncImpl::PendingSetSoftwareFeatureRequest::IsFulfilled() const { const auto& synced_devices = remote_device_provider_->GetSyncedDevices(); - const auto& devices_it = + const auto devices_it = std::find_if(synced_devices.begin(), synced_devices.end(), [this](const auto& remote_device) { return device_public_key_ == remote_device.public_key; @@ -256,7 +250,7 @@ if (devices_it == synced_devices.end()) return false; - const auto& features_map_it = + const auto features_map_it = devices_it->software_features.find(software_feature_); // If the device does not contain an entry for |software_feature_|, the @@ -292,11 +286,88 @@ CryptAuthEnrollmentManagerImpl::RegisterPrefs(registry); } - if (ShouldUseV2DeviceSync()) { + if (features::ShouldUseV2DeviceSync()) { CryptAuthDeviceRegistryImpl::RegisterPrefs(registry); } } +DeviceSyncImpl::PendingSetFeatureStatusRequest::PendingSetFeatureStatusRequest( + const std::string& device_instance_id, + multidevice::SoftwareFeature software_feature, + FeatureStatusChange status_change, + RemoteDeviceProvider* remote_device_provider, + SetFeatureStatusCallback callback) + : device_instance_id_(device_instance_id), + software_feature_(software_feature), + status_change_(status_change), + remote_device_provider_(remote_device_provider), + callback_(std::move(callback)) { + DCHECK(!device_instance_id.empty()); +} + +DeviceSyncImpl::PendingSetFeatureStatusRequest:: + ~PendingSetFeatureStatusRequest() = default; + +bool DeviceSyncImpl::PendingSetFeatureStatusRequest::IsFulfilled() const { + // True if the device from the request is included in the synced-devices list. + bool is_requested_device_in_list = false; + + // True if the feature from the request is enabled on the device from the + // request. + bool is_feature_enabled_for_requested_device = false; + + // True if the feature from the request is enabled on any synced device other + // than the device from the request. + bool is_feature_enabled_for_any_other_device = false; + + for (const multidevice::RemoteDevice& remote_device : + remote_device_provider_->GetSyncedDevices()) { + const auto it = remote_device.software_features.find(software_feature_); + bool is_feature_set_for_device = + it != remote_device.software_features.end(); + bool is_feature_enabled_for_device = + is_feature_set_for_device && + it->second == multidevice::SoftwareFeatureState::kEnabled; + + if (device_instance_id_ == remote_device.instance_id) { + DCHECK(!is_requested_device_in_list); + is_requested_device_in_list = true; + + // If the requested device does not contain an entry for + // |software_feature_|, the request is not fulfilled. + if (!is_feature_set_for_device) + return false; + + is_feature_enabled_for_requested_device = is_feature_enabled_for_device; + } else { + is_feature_enabled_for_any_other_device = + is_feature_enabled_for_any_other_device || + is_feature_enabled_for_device; + } + } + + // If the requested device no longer exists, the request is not fulfilled. + if (!is_requested_device_in_list) + return false; + + switch (status_change_) { + case FeatureStatusChange::kEnableExclusively: + return is_feature_enabled_for_requested_device && + !is_feature_enabled_for_any_other_device; + case FeatureStatusChange::kEnableNonExclusively: + return is_feature_enabled_for_requested_device; + case FeatureStatusChange::kDisable: + return !is_feature_enabled_for_requested_device; + } +} + +void DeviceSyncImpl::PendingSetFeatureStatusRequest::InvokeCallback( + mojom::NetworkRequestResult result) { + // Callback should only be invoked once. + DCHECK(callback_); + std::move(callback_).Run(result); +} + DeviceSyncImpl::DeviceSyncImpl( signin::IdentityManager* identity_manager, gcm::GCMDriver* gcm_driver, @@ -370,7 +441,7 @@ cryptauth_device_manager_->ForceSyncNow(cryptauth::INVOCATION_REASON_MANUAL); - if (ShouldUseV2DeviceSync()) { + if (features::ShouldUseV2DeviceSync()) { cryptauth_v2_device_manager_->ForceDeviceSyncNow( cryptauthv2::ClientMetadata::MANUAL, base::nullopt /* session_id */); } @@ -441,6 +512,35 @@ is_exclusive); } +void DeviceSyncImpl::SetFeatureStatus(const std::string& device_instance_id, + multidevice::SoftwareFeature feature, + FeatureStatusChange status_change, + SetFeatureStatusCallback callback) { + DCHECK(!device_instance_id.empty()); + + if (status_ != Status::READY) { + PA_LOG(WARNING) << "DeviceSyncImpl::SetFeatureStatus() invoked before " + << "initialization was complete. Cannot enable/disable " + << "feature."; + std::move(callback).Run( + mojom::NetworkRequestResult::kServiceNotYetInitialized); + return; + } + + auto request_id = base::UnguessableToken::Create(); + id_to_pending_set_feature_status_request_map_.emplace( + request_id, std::make_unique<PendingSetFeatureStatusRequest>( + device_instance_id, feature, status_change, + remote_device_provider_.get(), std::move(callback))); + + feature_status_setter_->SetFeatureStatus( + device_instance_id, feature, status_change, + base::BindOnce(&DeviceSyncImpl::OnSetFeatureStatusSuccess, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&DeviceSyncImpl::OnSetFeatureStatusError, + weak_ptr_factory_.GetWeakPtr(), request_id)); +} + void DeviceSyncImpl::FindEligibleDevices( multidevice::SoftwareFeature software_feature, FindEligibleDevicesCallback callback) { @@ -551,8 +651,8 @@ // Iterate through pending SetSoftwareFeature() requests. If any of them have // been fulfilled, invoke their callbacks. - auto it = id_to_pending_set_software_feature_request_map_.begin(); - while (it != id_to_pending_set_software_feature_request_map_.end()) { + for (auto it = id_to_pending_set_software_feature_request_map_.begin(); + it != id_to_pending_set_software_feature_request_map_.end();) { if (!it->second->IsFulfilled()) { ++it; continue; @@ -564,10 +664,27 @@ it->second->InvokeCallback(mojom::NetworkRequestResult::kSuccess); it = id_to_pending_set_software_feature_request_map_.erase(it); } + + // Iterate through pending SetFeatureStatus() requests. If any of them have + // been fulfilled, invoke their callbacks. + for (auto it = id_to_pending_set_feature_status_request_map_.begin(); + it != id_to_pending_set_feature_status_request_map_.end();) { + if (!it->second->IsFulfilled()) { + ++it; + continue; + } + + PA_LOG(VERBOSE) << "DeviceSyncImpl::OnSyncDeviceListChanged(): Feature " + << "status updated via device sync; notifying success " + << "callbacks."; + it->second->InvokeCallback(mojom::NetworkRequestResult::kSuccess); + it = id_to_pending_set_feature_status_request_map_.erase(it); + } } void DeviceSyncImpl::Shutdown() { software_feature_manager_.reset(); + feature_status_setter_.reset(); remote_device_provider_.reset(); cryptauth_v2_device_manager_.reset(); cryptauth_device_manager_.reset(); @@ -674,7 +791,7 @@ clock_, cryptauth_client_factory_.get(), cryptauth_gcm_manager_.get(), profile_prefs_); - if (ShouldUseV2DeviceSync()) { + if (features::ShouldUseV2DeviceSync()) { cryptauth_device_registry_ = CryptAuthDeviceRegistryImpl::Factory::Get()->BuildInstance( profile_prefs_); @@ -697,7 +814,7 @@ // Now that enrollment has completed, the current device has been registered // with the CryptAuth back-end and can begin monitoring synced devices. cryptauth_device_manager_->Start(); - if (ShouldUseV2DeviceSync()) { + if (features::ShouldUseV2DeviceSync()) { cryptauth_v2_device_manager_->Start(); } @@ -709,6 +826,11 @@ software_feature_manager_ = SoftwareFeatureManagerImpl::Factory::NewInstance( cryptauth_client_factory_.get()); + feature_status_setter_ = + CryptAuthFeatureStatusSetterImpl::Factory::Get()->BuildInstance( + client_app_metadata_provider_, cryptauth_client_factory_.get(), + cryptauth_gcm_manager_.get()); + status_ = Status::READY; PA_LOG(VERBOSE) << "DeviceSyncImpl: CryptAuth Enrollment is valid; service " @@ -722,10 +844,10 @@ << "DeviceSyncImpl::GetSyncedDeviceWithPublicKey() called before ready."; const auto& synced_devices = remote_device_provider_->GetSyncedDevices(); - const auto& it = std::find_if(synced_devices.begin(), synced_devices.end(), - [&public_key](const auto& remote_device) { - return public_key == remote_device.public_key; - }); + const auto it = std::find_if(synced_devices.begin(), synced_devices.end(), + [&public_key](const auto& remote_device) { + return public_key == remote_device.public_key; + }); if (it == synced_devices.end()) return base::nullopt; @@ -740,7 +862,7 @@ cryptauth_device_manager_->ForceSyncNow( cryptauth::INVOCATION_REASON_FEATURE_TOGGLED); - if (ShouldUseV2DeviceSync()) { + if (features::ShouldUseV2DeviceSync()) { cryptauth_v2_device_manager_->ForceDeviceSyncNow( cryptauthv2::ClientMetadata::FEATURE_TOGGLED, base::nullopt /* session_id */); @@ -772,6 +894,36 @@ id_to_pending_set_software_feature_request_map_.erase(it); } +void DeviceSyncImpl::OnSetFeatureStatusSuccess() { + PA_LOG(VERBOSE) << "DeviceSyncImpl::OnSetFeatureStatusSuccess(): " + << "Successfully completed SetFeatureStatus() call; " + << "requesting force sync."; + cryptauth_device_manager_->ForceSyncNow( + cryptauth::INVOCATION_REASON_FEATURE_TOGGLED); + + if (features::ShouldUseV2DeviceSync()) { + cryptauth_v2_device_manager_->ForceDeviceSyncNow( + cryptauthv2::ClientMetadata::FEATURE_TOGGLED, + base::nullopt /* session_id */); + } +} + +void DeviceSyncImpl::OnSetFeatureStatusError( + const base::UnguessableToken& request_id, + NetworkRequestError error) { + auto it = id_to_pending_set_feature_status_request_map_.find(request_id); + if (it == id_to_pending_set_feature_status_request_map_.end()) { + PA_LOG(ERROR) << "DeviceSyncImpl::OnSetFeatureStatusError(): " + << "Could not find request entry with ID " << request_id; + NOTREACHED(); + return; + } + + it->second->InvokeCallback( + mojo::ConvertTo<mojom::NetworkRequestResult>(error)); + id_to_pending_set_feature_status_request_map_.erase(it); +} + void DeviceSyncImpl::OnFindEligibleDevicesSuccess( const base::RepeatingCallback<void(mojom::NetworkRequestResult, mojom::FindEligibleDevicesResponsePtr)>&
diff --git a/chromeos/services/device_sync/device_sync_impl.h b/chromeos/services/device_sync/device_sync_impl.h index cc7ac50..517160d 100644 --- a/chromeos/services/device_sync/device_sync_impl.h +++ b/chromeos/services/device_sync/device_sync_impl.h
@@ -14,6 +14,7 @@ #include "chromeos/services/device_sync/cryptauth_enrollment_manager.h" #include "chromeos/services/device_sync/cryptauth_gcm_manager.h" #include "chromeos/services/device_sync/device_sync_base.h" +#include "chromeos/services/device_sync/feature_status_change.h" #include "chromeos/services/device_sync/network_request_error.h" #include "chromeos/services/device_sync/public/mojom/device_sync.mojom.h" #include "chromeos/services/device_sync/remote_device_provider.h" @@ -44,6 +45,7 @@ class CryptAuthClientFactory; class CryptAuthDeviceManager; class CryptAuthDeviceRegistry; +class CryptAuthFeatureStatusSetter; class CryptAuthKeyRegistry; class CryptAuthScheduler; class CryptAuthV2DeviceManager; @@ -100,6 +102,10 @@ bool enabled, bool is_exclusive, SetSoftwareFeatureStateCallback callback) override; + void SetFeatureStatus(const std::string& device_instance_id, + multidevice::SoftwareFeature feature, + FeatureStatusChange status_change, + SetFeatureStatusCallback callback) override; void FindEligibleDevices(multidevice::SoftwareFeature software_feature, FindEligibleDevicesCallback callback) override; void GetDevicesActivityStatus( @@ -147,6 +153,30 @@ SetSoftwareFeatureStateCallback callback_; }; + class PendingSetFeatureStatusRequest { + public: + PendingSetFeatureStatusRequest( + const std::string& device_instance_id, + multidevice::SoftwareFeature software_feature, + FeatureStatusChange status_change, + RemoteDeviceProvider* remote_device_provider, + SetFeatureStatusCallback callback); + ~PendingSetFeatureStatusRequest(); + + // True if the device and software feature status specified in the request + // agrees with the device data returned by CryptAuth. + bool IsFulfilled() const; + + void InvokeCallback(mojom::NetworkRequestResult result); + + private: + std::string device_instance_id_; + multidevice::SoftwareFeature software_feature_; + FeatureStatusChange status_change_; + RemoteDeviceProvider* remote_device_provider_; + SetFeatureStatusCallback callback_; + }; + DeviceSyncImpl( signin::IdentityManager* identity_manager, gcm::GCMDriver* gcm_driver, @@ -174,6 +204,9 @@ void OnSetSoftwareFeatureStateSuccess(); void OnSetSoftwareFeatureStateError(const base::UnguessableToken& request_id, NetworkRequestError error); + void OnSetFeatureStatusSuccess(); + void OnSetFeatureStatusError(const base::UnguessableToken& request_id, + NetworkRequestError error); void OnFindEligibleDevicesSuccess( const base::RepeatingCallback< void(mojom::NetworkRequestResult, @@ -213,6 +246,9 @@ base::flat_map<base::UnguessableToken, std::unique_ptr<PendingSetSoftwareFeatureRequest>> id_to_pending_set_software_feature_request_map_; + base::flat_map<base::UnguessableToken, + std::unique_ptr<PendingSetFeatureStatusRequest>> + id_to_pending_set_feature_status_request_map_; base::flat_map<base::UnguessableToken, GetDevicesActivityStatusCallback> get_devices_activity_status_callbacks_; @@ -231,6 +267,7 @@ std::unique_ptr<CryptAuthDeviceManager> cryptauth_device_manager_; std::unique_ptr<RemoteDeviceProvider> remote_device_provider_; std::unique_ptr<SoftwareFeatureManager> software_feature_manager_; + std::unique_ptr<CryptAuthFeatureStatusSetter> feature_status_setter_; std::unique_ptr<CryptAuthDeviceActivityGetter> cryptauth_device_activity_getter_;
diff --git a/chromeos/services/device_sync/device_sync_service_unittest.cc b/chromeos/services/device_sync/device_sync_service_unittest.cc index 22f192b4..3684e67d 100644 --- a/chromeos/services/device_sync/device_sync_service_unittest.cc +++ b/chromeos/services/device_sync/device_sync_service_unittest.cc
@@ -31,6 +31,7 @@ #include "chromeos/services/device_sync/device_sync_impl.h" #include "chromeos/services/device_sync/fake_cryptauth_device_manager.h" #include "chromeos/services/device_sync/fake_cryptauth_enrollment_manager.h" +#include "chromeos/services/device_sync/fake_cryptauth_feature_status_setter.h" #include "chromeos/services/device_sync/fake_cryptauth_gcm_manager.h" #include "chromeos/services/device_sync/fake_cryptauth_scheduler.h" #include "chromeos/services/device_sync/fake_cryptauth_v2_device_manager.h" @@ -133,6 +134,24 @@ base::Closure on_delegate_call_closure_; }; +// Delegate which invokes the Closure provided to its constructor when a +// delegate function is invoked. +class FakeCryptAuthFeatureStatusSetterDelegate + : public FakeCryptAuthFeatureStatusSetter::Delegate { + public: + explicit FakeCryptAuthFeatureStatusSetterDelegate( + base::Closure on_delegate_call_closure) + : on_delegate_call_closure_(on_delegate_call_closure) {} + + ~FakeCryptAuthFeatureStatusSetterDelegate() override = default; + + // FakeCryptAuthFeatureStatusSetter::Delegate: + void OnSetFeatureStatusCalled() override { on_delegate_call_closure_.Run(); } + + private: + base::Closure on_delegate_call_closure_; +}; + class FakeCryptAuthGCMManagerFactory : public CryptAuthGCMManagerImpl::Factory { public: FakeCryptAuthGCMManagerFactory(gcm::FakeGCMDriver* fake_gcm_driver, @@ -224,10 +243,8 @@ : public CryptAuthDeviceRegistryImpl::Factory { public: explicit FakeCryptAuthDeviceRegistryFactory( - TestingPrefServiceSimple* test_pref_service, - bool using_v2_device_sync) - : test_pref_service_(test_pref_service), - using_v2_device_sync_(using_v2_device_sync) {} + TestingPrefServiceSimple* test_pref_service) + : test_pref_service_(test_pref_service) {} ~FakeCryptAuthDeviceRegistryFactory() override = default; @@ -237,7 +254,7 @@ // CryptAuthDeviceRegistryImpl::Factory: std::unique_ptr<CryptAuthDeviceRegistry> BuildInstance( PrefService* pref_service) override { - EXPECT_TRUE(using_v2_device_sync_); + EXPECT_TRUE(features::ShouldUseV2DeviceSync()); EXPECT_EQ(test_pref_service_, pref_service); // Only one instance is expected to be created per test. @@ -248,7 +265,6 @@ } TestingPrefServiceSimple* test_pref_service_; - bool using_v2_device_sync_; FakeCryptAuthDeviceRegistry* instance_ = nullptr; }; @@ -266,10 +282,8 @@ : public CryptAuthKeyRegistryImpl::Factory { public: explicit FakeCryptAuthKeyRegistryFactory( - TestingPrefServiceSimple* test_pref_service, - bool using_v2_enrollment) - : test_pref_service_(test_pref_service), - using_v2_enrollment_(using_v2_enrollment) {} + TestingPrefServiceSimple* test_pref_service) + : test_pref_service_(test_pref_service) {} ~FakeCryptAuthKeyRegistryFactory() override = default; @@ -279,7 +293,7 @@ // CryptAuthKeyRegistryImpl::Factory: std::unique_ptr<CryptAuthKeyRegistry> BuildInstance( PrefService* pref_service) override { - EXPECT_TRUE(using_v2_enrollment_); + EXPECT_TRUE(base::FeatureList::IsEnabled(features::kCryptAuthV2Enrollment)); EXPECT_EQ(test_pref_service_, pref_service); // Only one instance is expected to be created per test. @@ -290,17 +304,14 @@ } TestingPrefServiceSimple* test_pref_service_; - bool using_v2_enrollment_; FakeCryptAuthKeyRegistry* instance_ = nullptr; }; class FakeCryptAuthSchedulerFactory : public CryptAuthSchedulerImpl::Factory { public: explicit FakeCryptAuthSchedulerFactory( - TestingPrefServiceSimple* test_pref_service, - bool using_v2_enrollment) - : test_pref_service_(test_pref_service), - using_v2_enrollment_(using_v2_enrollment) {} + TestingPrefServiceSimple* test_pref_service) + : test_pref_service_(test_pref_service) {} ~FakeCryptAuthSchedulerFactory() override = default; @@ -314,7 +325,7 @@ base::Clock* clock, std::unique_ptr<base::OneShotTimer> enrollment_timer, std::unique_ptr<base::OneShotTimer> device_sync_timer) override { - EXPECT_TRUE(using_v2_enrollment_); + EXPECT_TRUE(base::FeatureList::IsEnabled(features::kCryptAuthV2Enrollment)); EXPECT_EQ(test_pref_service_, pref_service); // Only one instance is expected to be created per test. @@ -327,7 +338,6 @@ } TestingPrefServiceSimple* test_pref_service_; - bool using_v2_enrollment_; FakeCryptAuthScheduler* instance_ = nullptr; }; @@ -339,14 +349,12 @@ FakeCryptAuthDeviceRegistryFactory* fake_device_registry_factory, FakeCryptAuthKeyRegistryFactory* fake_key_registry_factory, FakeCryptAuthGCMManagerFactory* fake_gcm_manager_factory, - FakeCryptAuthSchedulerFactory* fake_scheduler_factory, - bool using_v2_device_sync) + FakeCryptAuthSchedulerFactory* fake_scheduler_factory) : fake_client_app_metadata_provider_(fake_client_app_metadata_provider), fake_device_registry_factory_(fake_device_registry_factory), fake_key_registry_factory_(fake_key_registry_factory), fake_gcm_manager_factory_(fake_gcm_manager_factory), - fake_scheduler_factory_(fake_scheduler_factory), - using_v2_device_sync_(using_v2_device_sync) {} + fake_scheduler_factory_(fake_scheduler_factory) {} ~FakeCryptAuthV2DeviceManagerFactory() override = default; @@ -362,7 +370,7 @@ CryptAuthGCMManager* gcm_manager, CryptAuthScheduler* scheduler, std::unique_ptr<base::OneShotTimer> timer) override { - EXPECT_TRUE(using_v2_device_sync_); + EXPECT_TRUE(features::ShouldUseV2DeviceSync()); EXPECT_EQ(fake_client_app_metadata_provider_, client_app_metadata_provider); EXPECT_EQ(fake_device_registry_factory_->instance(), device_registry); EXPECT_EQ(fake_key_registry_factory_->instance(), key_registry); @@ -383,7 +391,6 @@ FakeCryptAuthKeyRegistryFactory* fake_key_registry_factory_ = nullptr; FakeCryptAuthGCMManagerFactory* fake_gcm_manager_factory_ = nullptr; FakeCryptAuthSchedulerFactory* fake_scheduler_factory_ = nullptr; - bool using_v2_device_sync_; FakeCryptAuthV2DeviceManager* instance_ = nullptr; }; @@ -393,12 +400,10 @@ FakeCryptAuthEnrollmentManagerFactory( base::SimpleTestClock* simple_test_clock, FakeCryptAuthGCMManagerFactory* fake_cryptauth_gcm_manager_factory, - TestingPrefServiceSimple* test_pref_service, - bool using_v2_enrollment) + TestingPrefServiceSimple* test_pref_service) : simple_test_clock_(simple_test_clock), fake_cryptauth_gcm_manager_factory_(fake_cryptauth_gcm_manager_factory), - test_pref_service_(test_pref_service), - using_v2_enrollment_(using_v2_enrollment) {} + test_pref_service_(test_pref_service) {} ~FakeCryptAuthEnrollmentManagerFactory() override = default; @@ -419,7 +424,8 @@ const cryptauth::GcmDeviceInfo& device_info, CryptAuthGCMManager* gcm_manager, PrefService* pref_service) override { - EXPECT_FALSE(using_v2_enrollment_); + EXPECT_FALSE( + base::FeatureList::IsEnabled(features::kCryptAuthV2Enrollment)); EXPECT_EQ(simple_test_clock_, clock); EXPECT_EQ(kTestGcmDeviceInfoLongDeviceId, device_info.long_device_id()); EXPECT_EQ(fake_cryptauth_gcm_manager_factory_->instance(), gcm_manager); @@ -440,7 +446,6 @@ base::SimpleTestClock* simple_test_clock_; FakeCryptAuthGCMManagerFactory* fake_cryptauth_gcm_manager_factory_; TestingPrefServiceSimple* test_pref_service_; - bool using_v2_enrollment_; bool device_already_enrolled_in_cryptauth_ = false; FakeCryptAuthEnrollmentManager* instance_ = nullptr; }; @@ -454,16 +459,14 @@ FakeCryptAuthGCMManagerFactory* fake_cryptauth_gcm_manager_factory, FakeCryptAuthSchedulerFactory* fake_cryptauth_scheduler_factory, TestingPrefServiceSimple* test_pref_service, - base::SimpleTestClock* simple_test_clock, - bool using_v2_enrollment) + base::SimpleTestClock* simple_test_clock) : fake_client_app_metadata_provider_(fake_client_app_metadata_provider), fake_cryptauth_key_registry_factory_( fake_cryptauth_key_registry_factory), fake_cryptauth_gcm_manager_factory_(fake_cryptauth_gcm_manager_factory), fake_cryptauth_scheduler_factory_(fake_cryptauth_scheduler_factory), test_pref_service_(test_pref_service), - simple_test_clock_(simple_test_clock), - using_v2_enrollment_(using_v2_enrollment) {} + simple_test_clock_(simple_test_clock) {} ~FakeCryptAuthV2EnrollmentManagerFactory() override = default; @@ -485,7 +488,7 @@ PrefService* pref_service, base::Clock* clock, std::unique_ptr<base::OneShotTimer> timer) override { - EXPECT_TRUE(using_v2_enrollment_); + EXPECT_TRUE(base::FeatureList::IsEnabled(features::kCryptAuthV2Enrollment)); EXPECT_EQ(fake_client_app_metadata_provider_, client_app_metadata_provider); EXPECT_EQ(fake_cryptauth_key_registry_factory_->instance(), key_registry); EXPECT_EQ(fake_cryptauth_gcm_manager_factory_->instance(), gcm_manager); @@ -511,7 +514,6 @@ FakeCryptAuthSchedulerFactory* fake_cryptauth_scheduler_factory_; TestingPrefServiceSimple* test_pref_service_; base::SimpleTestClock* simple_test_clock_; - bool using_v2_enrollment_; bool device_already_enrolled_in_cryptauth_ = false; FakeCryptAuthEnrollmentManager* instance_ = nullptr; }; @@ -526,8 +528,7 @@ FakeCryptAuthEnrollmentManagerFactory* fake_cryptauth_enrollment_manager_factory, FakeCryptAuthV2EnrollmentManagerFactory* - fake_cryptauth_v2_enrollment_manager_factory, - bool using_v2_enrollment) + fake_cryptauth_v2_enrollment_manager_factory) : initial_devices_(initial_devices), identity_manager_(identity_manager), fake_cryptauth_device_manager_factory_( @@ -535,8 +536,7 @@ fake_cryptauth_enrollment_manager_factory_( fake_cryptauth_enrollment_manager_factory), fake_cryptauth_v2_enrollment_manager_factory_( - fake_cryptauth_v2_enrollment_manager_factory), - using_v2_enrollment_(using_v2_enrollment) {} + fake_cryptauth_v2_enrollment_manager_factory) {} ~FakeRemoteDeviceProviderFactory() override = default; @@ -550,7 +550,7 @@ EXPECT_EQ(fake_cryptauth_device_manager_factory_->instance(), device_manager); EXPECT_EQ(identity_manager_->GetPrimaryAccountId(), user_id); - if (using_v2_enrollment_) { + if (base::FeatureList::IsEnabled(features::kCryptAuthV2Enrollment)) { EXPECT_EQ(fake_cryptauth_v2_enrollment_manager_factory_->instance() ->GetUserPrivateKey(), user_private_key); @@ -579,7 +579,6 @@ fake_cryptauth_enrollment_manager_factory_; FakeCryptAuthV2EnrollmentManagerFactory* fake_cryptauth_v2_enrollment_manager_factory_; - bool using_v2_enrollment_; FakeRemoteDeviceProvider* instance_ = nullptr; }; @@ -663,7 +662,6 @@ } else { disabled_features.push_back(chromeos::features::kCryptAuthV2Enrollment); } - use_v2_enrollment_ = std::get<0>(GetParam()); // Choose whether or not to enabled v2 DeviceSync feature flag based on the // second parameter provided by ::testing::TestWithParam<std::tuple<bool, @@ -674,7 +672,6 @@ } else { disabled_features.push_back(chromeos::features::kCryptAuthV2DeviceSync); } - use_v2_device_sync_ = std::get<0>(GetParam()) && std::get<1>(GetParam()); scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); @@ -704,13 +701,13 @@ fake_cryptauth_key_registry_factory_ = std::make_unique<FakeCryptAuthKeyRegistryFactory>( - test_pref_service_.get(), use_v2_enrollment_); + test_pref_service_.get()); CryptAuthKeyRegistryImpl::Factory::SetFactoryForTesting( fake_cryptauth_key_registry_factory_.get()); fake_cryptauth_scheduler_factory_ = std::make_unique<FakeCryptAuthSchedulerFactory>( - test_pref_service_.get(), use_v2_enrollment_); + test_pref_service_.get()); CryptAuthSchedulerImpl::Factory::SetFactoryForTesting( fake_cryptauth_scheduler_factory_.get()); @@ -720,7 +717,7 @@ fake_cryptauth_key_registry_factory_.get(), fake_cryptauth_gcm_manager_factory_.get(), fake_cryptauth_scheduler_factory_.get(), test_pref_service_.get(), - simple_test_clock_.get(), use_v2_enrollment_); + simple_test_clock_.get()); CryptAuthV2EnrollmentManagerImpl::Factory::SetFactoryForTesting( fake_cryptauth_v2_enrollment_manager_factory_.get()); // ---------- End: Only used for v2 Enrollment ---------- @@ -729,7 +726,7 @@ fake_cryptauth_enrollment_manager_factory_ = std::make_unique<FakeCryptAuthEnrollmentManagerFactory>( simple_test_clock_.get(), fake_cryptauth_gcm_manager_factory_.get(), - test_pref_service_.get(), use_v2_enrollment_); + test_pref_service_.get()); CryptAuthEnrollmentManagerImpl::Factory::SetInstanceForTesting( fake_cryptauth_enrollment_manager_factory_.get()); @@ -743,7 +740,7 @@ // ---------- Begin: Only used for v2 DeviceSync ---------- fake_cryptauth_device_registry_factory_ = std::make_unique<FakeCryptAuthDeviceRegistryFactory>( - test_pref_service_.get(), use_v2_device_sync_); + test_pref_service_.get()); CryptAuthDeviceRegistryImpl::Factory::SetFactoryForTesting( fake_cryptauth_device_registry_factory_.get()); @@ -753,7 +750,7 @@ fake_cryptauth_device_registry_factory_.get(), fake_cryptauth_key_registry_factory_.get(), fake_cryptauth_gcm_manager_factory_.get(), - fake_cryptauth_scheduler_factory_.get(), use_v2_device_sync_); + fake_cryptauth_scheduler_factory_.get()); CryptAuthV2DeviceManagerImpl::Factory::SetFactoryForTesting( fake_cryptauth_v2_device_manager_factory_.get()); // ---------- End: Only used for v2 DeviceSync ---------- @@ -763,8 +760,7 @@ test_devices_, identity_test_environment_->identity_manager(), fake_cryptauth_device_manager_factory_.get(), fake_cryptauth_enrollment_manager_factory_.get(), - fake_cryptauth_v2_enrollment_manager_factory_.get(), - use_v2_enrollment_); + fake_cryptauth_v2_enrollment_manager_factory_.get()); RemoteDeviceProviderImpl::Factory::SetInstanceForTesting( fake_remote_device_provider_factory_.get()); @@ -773,6 +769,11 @@ SoftwareFeatureManagerImpl::Factory::SetInstanceForTesting( fake_software_feature_manager_factory_.get()); + fake_feature_status_setter_factory_ = + std::make_unique<FakeCryptAuthFeatureStatusSetterFactory>(); + CryptAuthFeatureStatusSetterImpl::Factory::SetFactoryForTesting( + fake_feature_status_setter_factory_.get()); + auto mock_timer = std::make_unique<base::MockOneShotTimer>(); mock_timer_ = mock_timer.get(); @@ -807,7 +808,7 @@ device_already_enrolled_in_cryptauth_ = device_already_enrolled_in_cryptauth; - if (use_v2_enrollment_) { + if (base::FeatureList::IsEnabled(features::kCryptAuthV2Enrollment)) { fake_cryptauth_v2_enrollment_manager_factory_ ->set_device_already_enrolled_in_cryptauth( device_already_enrolled_in_cryptauth); @@ -869,7 +870,7 @@ expected_to_be_initialized, fake_cryptauth_device_manager_factory_->instance()->has_started()); - if (use_v2_device_sync_) { + if (features::ShouldUseV2DeviceSync()) { EXPECT_EQ( expected_to_be_initialized, fake_cryptauth_v2_device_manager_factory_->instance()->has_started()); @@ -922,7 +923,7 @@ ? CryptAuthDeviceManager::DeviceChangeResult::UNCHANGED : CryptAuthDeviceManager::DeviceChangeResult::CHANGED); - if (use_v2_device_sync_) { + if (features::ShouldUseV2DeviceSync()) { EXPECT_TRUE(v2_device_manager->IsDeviceSyncInProgress()); v2_device_manager->FinishNextForcedDeviceSync( CryptAuthDeviceSyncResult( @@ -972,7 +973,7 @@ base::MockOneShotTimer* mock_timer() { return mock_timer_; } FakeCryptAuthEnrollmentManager* fake_cryptauth_enrollment_manager() { - return use_v2_enrollment_ + return base::FeatureList::IsEnabled(features::kCryptAuthV2Enrollment) ? fake_cryptauth_v2_enrollment_manager_factory_->instance() : fake_cryptauth_enrollment_manager_factory_->instance(); } @@ -985,6 +986,18 @@ return fake_software_feature_manager_factory_->instance(); } + FakeCryptAuthFeatureStatusSetter* fake_feature_status_setter() { + if (fake_feature_status_setter_factory_->instances().empty()) + return nullptr; + + EXPECT_EQ(1u, fake_feature_status_setter_factory_->instances().size()); + return fake_feature_status_setter_factory_->instances()[0]; + } + + const std::vector<mojom::NetworkRequestResult>& set_feature_status_results() { + return set_feature_status_results_; + } + std::unique_ptr<mojom::NetworkRequestResult> GetLastSetSoftwareFeatureStateResponseAndReset() { return std::move(last_set_software_feature_state_response_); @@ -1020,6 +1033,15 @@ EXPECT_EQ(mojom::NetworkRequestResult::kServiceNotYetInitialized, *last_set_response); + // SetFeatureStatus() should return a struct with the special + // kErrorNotInitialized error code. + CallSetFeatureStatus(test_devices()[0].instance_id, + multidevice::SoftwareFeature::kBetterTogetherHost, + FeatureStatusChange::kEnableExclusively); + EXPECT_EQ(1u, set_feature_status_results_.size()); + EXPECT_EQ(mojom::NetworkRequestResult::kServiceNotYetInitialized, + set_feature_status_results_[0]); + // Likewise, FindEligibleDevices() should also return a struct with the same // error code. CallFindEligibleDevices(multidevice::SoftwareFeature::kBetterTogetherHost); @@ -1143,6 +1165,34 @@ fake_software_feature_manager_factory_->instance()->set_delegate(nullptr); } + void CallSetFeatureStatus(const std::string& device_instance_id, + multidevice::SoftwareFeature software_feature, + FeatureStatusChange status_change) { + base::RunLoop run_loop; + + // If the feature setter has not yet been created, the service has not been + // initialized. SetFeatureStatus() is expected to respond synchronously with + // an error. + if (!fake_feature_status_setter()) { + device_sync_->SetFeatureStatus( + device_instance_id, software_feature, status_change, + base::Bind( + &DeviceSyncServiceTest::OnSetFeatureStatusCompletedSynchronously, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + return; + } + + FakeCryptAuthFeatureStatusSetterDelegate delegate(run_loop.QuitClosure()); + fake_feature_status_setter()->set_delegate(&delegate); + device_sync_->SetFeatureStatus( + device_instance_id, software_feature, status_change, + base::Bind(&DeviceSyncServiceTest::OnSetFeatureStatusCompleted, + base::Unretained(this))); + run_loop.Run(); + fake_feature_status_setter()->set_delegate(nullptr); + } + void CallFindEligibleDevices(multidevice::SoftwareFeature software_feature) { base::RunLoop run_loop; FakeSoftwareFeatureManager* manager = fake_software_feature_manager(); @@ -1230,6 +1280,17 @@ std::move(quit_closure).Run(); } + void OnSetFeatureStatusCompleted(mojom::NetworkRequestResult result_code) { + set_feature_status_results_.push_back(result_code); + } + + void OnSetFeatureStatusCompletedSynchronously( + base::OnceClosure quit_closure, + mojom::NetworkRequestResult result_code) { + OnSetFeatureStatusCompleted(result_code); + std::move(quit_closure).Run(); + } + void OnFindEligibleDevicesCompleted( mojom::NetworkRequestResult result_code, mojom::FindEligibleDevicesResponsePtr response) { @@ -1289,6 +1350,8 @@ fake_remote_device_provider_factory_; std::unique_ptr<FakeSoftwareFeatureManagerFactory> fake_software_feature_manager_factory_; + std::unique_ptr<FakeCryptAuthFeatureStatusSetterFactory> + fake_feature_status_setter_factory_; std::unique_ptr<signin::IdentityTestEnvironment> identity_test_environment_; std::unique_ptr<gcm::FakeGCMDriver> fake_gcm_driver_; @@ -1305,14 +1368,13 @@ mojom::FindEligibleDevicesResponsePtr>> last_find_eligible_devices_response_; base::Optional<mojom::DebugInfo> last_debug_info_result_; + std::vector<mojom::NetworkRequestResult> set_feature_status_results_; std::unique_ptr<FakeDeviceSyncObserver> fake_device_sync_observer_; std::unique_ptr<DeviceSyncBase> device_sync_; base::HistogramTester histogram_tester_; - bool use_v2_enrollment_; - bool use_v2_device_sync_; base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(DeviceSyncServiceTest); @@ -1624,6 +1686,172 @@ "MultiDevice.DeviceSyncService.SetSoftwareFeatureState.Result", true, 0); } +TEST_P(DeviceSyncServiceTest, SetFeatureStatus_Success) { + InitializeServiceSuccessfully(); + + EXPECT_EQ(0u, fake_feature_status_setter()->requests().size()); + + multidevice::RemoteDevice device_for_test = test_devices()[0]; + + // Exclusively enable kBetterTogetherHost for the device. + CallSetFeatureStatus(device_for_test.instance_id, + multidevice::SoftwareFeature::kBetterTogetherHost, + FeatureStatusChange::kEnableExclusively); + EXPECT_EQ(1u, fake_feature_status_setter()->requests().size()); + EXPECT_EQ(multidevice::SoftwareFeature::kBetterTogetherHost, + fake_feature_status_setter()->requests()[0].feature); + EXPECT_EQ(FeatureStatusChange::kEnableExclusively, + fake_feature_status_setter()->requests()[0].status_change); + EXPECT_TRUE(fake_feature_status_setter()->requests()[0].success_callback); + EXPECT_TRUE(fake_feature_status_setter()->requests()[0].error_callback); + + // The DeviceSyncImpl::SetFeatureStatus() callback has not yet been invoked. + EXPECT_TRUE(set_feature_status_results().empty()); + + // Now, invoke the CryptAuthFeatureStatusSetter success callback. + std::move(fake_feature_status_setter()->requests()[0].success_callback).Run(); + + // The DeviceSyncImpl::SetFeatureStatus() callback still has not yet been + // invoked since a device sync has not confirmed the feature state change yet. + EXPECT_TRUE(set_feature_status_results().empty()); + + // Simulate a sync which includes the device with the correct "enabled" state. + device_for_test + .software_features[multidevice::SoftwareFeature::kBetterTogetherHost] = + multidevice::SoftwareFeatureState::kEnabled; + SimulateSync(true /* success */, {device_for_test}); + base::RunLoop().RunUntilIdle(); + + ASSERT_EQ(1u, set_feature_status_results().size()); + EXPECT_EQ(mojom::NetworkRequestResult::kSuccess, + set_feature_status_results()[0]); +} + +TEST_P(DeviceSyncServiceTest, + SetFeatureStatus_RequestSucceedsButDoesNotTakeEffect) { + InitializeServiceSuccessfully(); + + // Expected device feature states after SetFeatureStatus() calls: + // * Device 0 has kSmartLockHost disabled. + // * Device 1 has kSmartLockHost disabled. + // * Device 2 has kBetterTogetherHost enabled exclusively. + // * Device 3 has kInstantTetheringHost enabled. + // * Device 4 has kMessagesForWebHost disabled. + multidevice::RemoteDeviceList expected_remote_devices = + multidevice::CreateRemoteDeviceListForTest(5u); + expected_remote_devices[0] + .software_features[multidevice::SoftwareFeature::kSmartLockHost] = + multidevice::SoftwareFeatureState::kSupported; + expected_remote_devices[1] + .software_features[multidevice::SoftwareFeature::kSmartLockHost] = + multidevice::SoftwareFeatureState::kSupported; + expected_remote_devices[2] + .software_features[multidevice::SoftwareFeature::kBetterTogetherHost] = + multidevice::SoftwareFeatureState::kEnabled; + expected_remote_devices[3] + .software_features[multidevice::SoftwareFeature::kInstantTetheringHost] = + multidevice::SoftwareFeatureState::kEnabled; + expected_remote_devices[4] + .software_features[multidevice::SoftwareFeature::kMessagesForWebHost] = + multidevice::SoftwareFeatureState::kSupported; + + CallSetFeatureStatus(expected_remote_devices[0].instance_id, + multidevice::SoftwareFeature::kSmartLockHost, + FeatureStatusChange::kDisable); + CallSetFeatureStatus(expected_remote_devices[1].instance_id, + multidevice::SoftwareFeature::kSmartLockHost, + FeatureStatusChange::kDisable); + CallSetFeatureStatus(expected_remote_devices[2].instance_id, + multidevice::SoftwareFeature::kBetterTogetherHost, + FeatureStatusChange::kEnableExclusively); + CallSetFeatureStatus(expected_remote_devices[3].instance_id, + multidevice::SoftwareFeature::kInstantTetheringHost, + FeatureStatusChange::kEnableNonExclusively); + CallSetFeatureStatus(expected_remote_devices[4].instance_id, + multidevice::SoftwareFeature::kMessagesForWebHost, + FeatureStatusChange::kDisable); + EXPECT_EQ(5u, fake_feature_status_setter()->requests().size()); + + // The DeviceSyncImpl::SetFeatureStatus() callbacks have not yet been invoked. + EXPECT_TRUE(set_feature_status_results().empty()); + + // Now, invoke the CryptAuthFeatureStatusSetter success callbacks. + std::move(fake_feature_status_setter()->requests()[0].success_callback).Run(); + std::move(fake_feature_status_setter()->requests()[1].success_callback).Run(); + std::move(fake_feature_status_setter()->requests()[2].success_callback).Run(); + std::move(fake_feature_status_setter()->requests()[3].success_callback).Run(); + std::move(fake_feature_status_setter()->requests()[4].success_callback).Run(); + + // The DeviceSyncImpl::SetFeatureStatus() callbacks still have not been + // invoked since a DeviceSync has not confirmed any of the requested feature + // state changes yet. + EXPECT_TRUE(set_feature_status_results().empty()); + + // Simulate a DeviceSync which returns unexpected device feature states: + // * Device 0 not in list of devices. + // * Device 1 missing kSmartLockHost entry in the feature list. + // * Device 2 has kBetterTogetherHost enabled but not exclusively since device + // 1 also has it enabled. + // * Device 3 does not have kInstantTetheringHost enabled. + // * Device 4 does not have kMessagesForWebHost disabled. + multidevice::RemoteDeviceList remote_devices_from_first_sync = + multidevice::CreateRemoteDeviceListForTest(5u); + remote_devices_from_first_sync[1] + .software_features[multidevice::SoftwareFeature::kBetterTogetherHost] = + multidevice::SoftwareFeatureState::kEnabled; + remote_devices_from_first_sync[2] + .software_features[multidevice::SoftwareFeature::kBetterTogetherHost] = + multidevice::SoftwareFeatureState::kEnabled; + remote_devices_from_first_sync[3] + .software_features[multidevice::SoftwareFeature::kInstantTetheringHost] = + multidevice::SoftwareFeatureState::kSupported; + remote_devices_from_first_sync[4] + .software_features[multidevice::SoftwareFeature::kMessagesForWebHost] = + multidevice::SoftwareFeatureState::kEnabled; + remote_devices_from_first_sync.erase(remote_devices_from_first_sync.begin()); + + SimulateSync(true /* success */, remote_devices_from_first_sync); + base::RunLoop().RunUntilIdle(); + + // The DeviceSyncImpl::SetFeatureStatus() callbacks still have not yet been + // invoked since the latest DeviceSync did not reflect the requested feature + // state changes. + EXPECT_EQ(0u, set_feature_status_results().size()); + + // Simulate a DeviceSync which returns the expected device feature states: + EXPECT_TRUE(CallForceSyncNow()); + SimulateSync(true /* success */, expected_remote_devices); + base::RunLoop().RunUntilIdle(); + + ASSERT_EQ(5u, set_feature_status_results().size()); + for (mojom::NetworkRequestResult result : set_feature_status_results()) + EXPECT_EQ(mojom::NetworkRequestResult::kSuccess, result); +} + +TEST_P(DeviceSyncServiceTest, SetFeatureStatus_Error) { + InitializeServiceSuccessfully(); + + multidevice::RemoteDevice device_for_test = test_devices()[0]; + + // Attempt to exclusively enable kBetterTogetherHost for the device. + CallSetFeatureStatus(device_for_test.instance_id, + multidevice::SoftwareFeature::kBetterTogetherHost, + FeatureStatusChange::kEnableExclusively); + + // The DeviceSyncImpl::SetFeatureStatus() callback has not yet been invoked. + EXPECT_TRUE(set_feature_status_results().empty()); + + // Now, invoke the CryptAuthFeatureStatusSetter error callback. + std::move(fake_feature_status_setter()->requests()[0].error_callback) + .Run(NetworkRequestError::kBadRequest); + + // The DeviceSyncImpl::SetFeatureStatus() callback is invoked with the same + // error code. + ASSERT_EQ(1u, set_feature_status_results().size()); + EXPECT_EQ(mojom::NetworkRequestResult::kBadRequest, + set_feature_status_results()[0]); +} + TEST_P(DeviceSyncServiceTest, FindEligibleDevices) { InitializeServiceSuccessfully();
diff --git a/chromeos/services/device_sync/fake_device_sync.cc b/chromeos/services/device_sync/fake_device_sync.cc index e028c44..933f2e4 100644 --- a/chromeos/services/device_sync/fake_device_sync.cc +++ b/chromeos/services/device_sync/fake_device_sync.cc
@@ -39,6 +39,12 @@ set_software_feature_state_callback_queue_.pop(); } +void FakeDeviceSync::InvokePendingSetFeatureStatusCallback( + mojom::NetworkRequestResult result_code) { + std::move(set_feature_status_callback_queue_.front()).Run(result_code); + set_feature_status_callback_queue_.pop(); +} + void FakeDeviceSync::InvokePendingFindEligibleDevicesCallback( mojom::NetworkRequestResult result_code, mojom::FindEligibleDevicesResponsePtr find_eligible_devices_response_ptr) { @@ -89,6 +95,13 @@ set_software_feature_state_callback_queue_.push(std::move(callback)); } +void FakeDeviceSync::SetFeatureStatus(const std::string& device_instance_id, + multidevice::SoftwareFeature feature, + FeatureStatusChange status_change, + SetFeatureStatusCallback callback) { + set_feature_status_callback_queue_.push(std::move(callback)); +} + void FakeDeviceSync::FindEligibleDevices( multidevice::SoftwareFeature software_feature, FindEligibleDevicesCallback callback) {
diff --git a/chromeos/services/device_sync/fake_device_sync.h b/chromeos/services/device_sync/fake_device_sync.h index f7ab85f..493ed5d 100644 --- a/chromeos/services/device_sync/fake_device_sync.h +++ b/chromeos/services/device_sync/fake_device_sync.h
@@ -41,6 +41,8 @@ remote_devices); void InvokePendingSetSoftwareFeatureStateCallback( mojom::NetworkRequestResult result_code); + void InvokePendingSetFeatureStatusCallback( + mojom::NetworkRequestResult result_code); void InvokePendingFindEligibleDevicesCallback( mojom::NetworkRequestResult result_code, mojom::FindEligibleDevicesResponsePtr find_eligible_devices_response_ptr); @@ -62,6 +64,10 @@ bool enabled, bool is_exclusive, SetSoftwareFeatureStateCallback callback) override; + void SetFeatureStatus(const std::string& device_instance_id, + multidevice::SoftwareFeature feature, + FeatureStatusChange status_change, + SetFeatureStatusCallback callback) override; void FindEligibleDevices(multidevice::SoftwareFeature software_feature, FindEligibleDevicesCallback callback) override; void GetDebugInfo(GetDebugInfoCallback callback) override; @@ -77,6 +83,7 @@ std::queue<GetSyncedDevicesCallback> get_synced_devices_callback_queue_; std::queue<SetSoftwareFeatureStateCallback> set_software_feature_state_callback_queue_; + std::queue<SetFeatureStatusCallback> set_feature_status_callback_queue_; std::queue<FindEligibleDevicesCallback> find_eligible_devices_callback_queue_; std::queue<GetDevicesActivityStatusCallback> get_devices_activity_status_callback_queue_;
diff --git a/chromeos/services/device_sync/public/mojom/device_sync.mojom b/chromeos/services/device_sync/public/mojom/device_sync.mojom index 9b572cd..283af3c 100644 --- a/chromeos/services/device_sync/public/mojom/device_sync.mojom +++ b/chromeos/services/device_sync/public/mojom/device_sync.mojom
@@ -147,12 +147,26 @@ // SoftwareFeature::EASY_UNLOCK_HOST and |enabled| = false, |public_key| is // ignored, because that combination of arguments disables EASY_UNLOCK_HOST on // all of the user's devices. + // + // TODO(https://crbug.com/1019206): Remove this function when v1 DeviceSync + // is deprecated. SetSoftwareFeatureState( string device_public_key, chromeos.multidevice.mojom.SoftwareFeature software_feature, bool enabled, bool is_exclusive) => (NetworkRequestResult result_code); + // Enables or disables |feature| for the device with Instance ID + // |device_instance_id|. + // + // This function can only affect devices using CryptAuth v2 DeviceSync since + // it requires an Instance ID. See SetSoftwareFeatureState() for the v1 + // DeviceSync analog. + SetFeatureStatus( + string device_instance_id, + chromeos.multidevice.mojom.SoftwareFeature feature, + FeatureStatusChange status_change) => (NetworkRequestResult result_code); + // Finds devices which are eligible for the given feature. When this function // is invoked, a network request will be sent to each eligible device which // instructs that device to enable BLE advertising; thus, this function can be @@ -161,6 +175,9 @@ // On success, this function returns a null error_code with a valid response // to the callback; on error, it returns a valid error_code string indicating // the reason for failure along with a null response. + // + // TODO(https://crbug.com/1019206): Remove this function when v1 DeviceSync + // is deprecated. FindEligibleDevices( chromeos.multidevice.mojom.SoftwareFeature software_feature) => (NetworkRequestResult result_code,
diff --git a/components/.eslintrc.js b/components/.eslintrc.js new file mode 100644 index 0000000..e5323a2b --- /dev/null +++ b/components/.eslintrc.js
@@ -0,0 +1,9 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module.exports = { + 'rules': { + 'no-restricted-properties': 'off', + }, +};
diff --git a/components/OWNERS b/components/OWNERS index 26e9def..cbbf1d9 100644 --- a/components/OWNERS +++ b/components/OWNERS
@@ -37,6 +37,10 @@ per-file version_ui_strings.grdp=file://components/version_ui/OWNERS per-file web_contents_delegate_android_strings.grdp=file://components/embedder_support/android/delegate/OWNERS +# For web_dev_style related changes. +per-file .eslintrc.js=file://ui/webui/PLATFORM_OWNERS +per-file PRESUBMIT.py=file://ui/webui/PLATFORM_OWNERS + # Translation artifacts: per-file *.xtb=file://tools/translation/TRANSLATION_OWNERS
diff --git a/components/PRESUBMIT.py b/components/PRESUBMIT.py new file mode 100644 index 0000000..80340ee9 --- /dev/null +++ b/components/PRESUBMIT.py
@@ -0,0 +1,48 @@ +# 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. + + +def CheckChangeOnUpload(input_api, output_api): + return _CommonChecks(input_api, output_api) + + +def CheckChangeOnCommit(input_api, output_api): + return _CommonChecks(input_api, output_api) + + +def _CheckSvgsOptimized(input_api, output_api): + results = [] + try: + import sys + old_sys_path = sys.path[:] + cwd = input_api.PresubmitLocalPath() + sys.path += [input_api.os_path.join(cwd, '..', 'tools')] + from resources import svgo_presubmit + results += svgo_presubmit.CheckOptimized(input_api, output_api) + finally: + sys.path = old_sys_path + return results + + +def _CheckWebDevStyle(input_api, output_api): + results = [] + try: + import sys + old_sys_path = sys.path[:] + cwd = input_api.PresubmitLocalPath() + sys.path += [input_api.os_path.join(cwd, '..', 'tools')] + from web_dev_style import presubmit_support + results += presubmit_support.CheckStyle(input_api, output_api) + finally: + sys.path = old_sys_path + return results + + +def _CommonChecks(input_api, output_api): + results = [] + results += _CheckSvgsOptimized(input_api, output_api) + results += _CheckWebDevStyle(input_api, output_api) + results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api, + check_js=True) + return results
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.cc b/components/arc/intent_helper/arc_intent_helper_bridge.cc index 5c3a986b..c6dcbea 100644 --- a/components/arc/intent_helper/arc_intent_helper_bridge.cc +++ b/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -248,27 +248,6 @@ ash::NewWindowDelegate::GetInstance()->CloseCameraApp(); } -void ArcIntentHelperBridge::HandleCameraResult( - uint32_t intent_id, - arc::mojom::CameraIntentAction action, - const std::vector<uint8_t>& data, - arc::mojom::IntentHelperInstance::HandleCameraResultCallback callback) { - auto* arc_service_manager = arc::ArcServiceManager::Get(); - arc::mojom::IntentHelperInstance* instance = nullptr; - if (arc_service_manager) { - instance = ARC_GET_INSTANCE_FOR_METHOD( - arc_service_manager->arc_bridge_service()->intent_helper(), - HandleCameraResult); - } - if (!instance) { - LOG(ERROR) << "Failed to get instance for HandleCameraResult()."; - std::move(callback).Run(false); - return; - } - - instance->HandleCameraResult(intent_id, action, data, std::move(callback)); -} - ArcIntentHelperBridge::GetResult ArcIntentHelperBridge::GetActivityIcons( const std::vector<ActivityName>& activities, OnIconsReadyCallback callback) { @@ -310,6 +289,27 @@ return observer_list_.HasObserver(observer); } +void ArcIntentHelperBridge::HandleCameraResult( + uint32_t intent_id, + arc::mojom::CameraIntentAction action, + const std::vector<uint8_t>& data, + arc::mojom::IntentHelperInstance::HandleCameraResultCallback callback) { + auto* arc_service_manager = arc::ArcServiceManager::Get(); + arc::mojom::IntentHelperInstance* instance = nullptr; + if (arc_service_manager) { + instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_service_manager->arc_bridge_service()->intent_helper(), + HandleCameraResult); + } + if (!instance) { + LOG(ERROR) << "Failed to get instance for HandleCameraResult()."; + std::move(callback).Run(false); + return; + } + + instance->HandleCameraResult(intent_id, action, data, std::move(callback)); +} + // static bool ArcIntentHelperBridge::IsIntentHelperPackage( const std::string& package_name) {
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.h b/components/arc/intent_helper/arc_intent_helper_bridge.h index ad40a80d..9656417 100644 --- a/components/arc/intent_helper/arc_intent_helper_bridge.h +++ b/components/arc/intent_helper/arc_intent_helper_bridge.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_ARC_INTENT_HELPER_ARC_INTENT_HELPER_BRIDGE_H_ #define COMPONENTS_ARC_INTENT_HELPER_ARC_INTENT_HELPER_BRIDGE_H_ +#include <map> #include <memory> #include <set> #include <string> @@ -60,6 +61,11 @@ void AddObserver(ArcIntentHelperObserver* observer); void RemoveObserver(ArcIntentHelperObserver* observer); bool HasObserver(ArcIntentHelperObserver* observer) const; + void HandleCameraResult( + uint32_t intent_id, + arc::mojom::CameraIntentAction action, + const std::vector<uint8_t>& data, + arc::mojom::IntentHelperInstance::HandleCameraResultCallback callback); // mojom::IntentHelperHost void OnIconInvalidated(const std::string& package_name) override; @@ -85,11 +91,6 @@ bool should_down_scale, bool is_secure) override; void CloseCameraApp() override; - void HandleCameraResult( - uint32_t intent_id, - arc::mojom::CameraIntentAction action, - const std::vector<uint8_t>& data, - arc::mojom::IntentHelperInstance::HandleCameraResultCallback callback); void OnIntentFiltersUpdatedForPackage( const std::string& package_name, std::vector<IntentFilter> intent_filters) override;
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc index 1e1c3fce..3dfde0e 100644 --- a/components/bookmarks/browser/bookmark_model.cc +++ b/components/bookmarks/browser/bookmark_model.cc
@@ -205,7 +205,10 @@ DCHECK(parent); size_t index = size_t{parent->GetIndexOf(node)}; DCHECK_NE(size_t{-1}, index); - DCHECK(!is_permanent_node(node)); + + // Removing a permanent node is problematic and can cause crashes elsewhere + // that are difficult to trace back. + CHECK(!is_permanent_node(node)) << "for type " << node->type(); for (BookmarkModelObserver& observer : observers_) observer.OnWillRemoveBookmarks(this, parent, index, node);
diff --git a/components/chrome_cleaner/public/constants/constants.cc b/components/chrome_cleaner/public/constants/constants.cc index 98c0b89..345d481c 100644 --- a/components/chrome_cleaner/public/constants/constants.cc +++ b/components/chrome_cleaner/public/constants/constants.cc
@@ -9,7 +9,6 @@ // Command line switches. const char kChromeChannelSwitch[] = "chrome-channel"; const char kChromeExePathSwitch[] = "chrome-exe-path"; -const char kChromeMojoPipeTokenSwitch[] = "chrome-mojo-pipe-token"; const char kChromePromptSwitch[] = "chrome-prompt"; const char kChromeReadHandleSwitch[] = "chrome-read-handle"; const char kChromeWriteHandleSwitch[] = "chrome-write-handle";
diff --git a/components/chrome_cleaner/public/constants/constants.h b/components/chrome_cleaner/public/constants/constants.h index 5beced3..1a1d84da 100644 --- a/components/chrome_cleaner/public/constants/constants.h +++ b/components/chrome_cleaner/public/constants/constants.h
@@ -23,10 +23,6 @@ // The path to Chrome's executable. extern const char kChromeExePathSwitch[]; -// The Mojo pipe token for IPC communication between the Software Reporter and -// Chrome. -extern const char kChromeMojoPipeTokenSwitch[]; - // Indicates that a cleaner run was started by Chrome. extern const char kChromePromptSwitch[];
diff --git a/components/chrome_cleaner/public/interfaces/BUILD.gn b/components/chrome_cleaner/public/interfaces/BUILD.gn deleted file mode 100644 index fa6dda81..0000000 --- a/components/chrome_cleaner/public/interfaces/BUILD.gn +++ /dev/null
@@ -1,22 +0,0 @@ -# Copyright 2017 The Chromium Authors. All Rights Reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//mojo/public/tools/bindings/mojom.gni") - -# TODO(crbug.com/969139): This target uses a non-standard name because it is -# mirrored at -# https://chromium.googlesource.com/chromium/src/components/chrome_cleaner so -# that it can be used from the internal Chrome Cleanup tool repo which is -# released on a different schedule from Chrome. Coordinating the renaming from -# interfaces -> mojom in the internal repo is tricky. Once crbug.com/969139 is -# implemented we we will delete this interface anyway. -mojom("interfaces") { - sources = [ - "chrome_prompt.mojom", - ] - - # NOTE: We avoid scrambling message IDs here because these messages cross an - # IPC boundary to an external program built from a different source tree. - scramble_message_ids = false -}
diff --git a/components/chrome_cleaner/public/interfaces/OWNERS b/components/chrome_cleaner/public/interfaces/OWNERS deleted file mode 100644 index 74b69f8..0000000 --- a/components/chrome_cleaner/public/interfaces/OWNERS +++ /dev/null
@@ -1,5 +0,0 @@ -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS - -# TEAM: security-dev@chromium.org -# COMPONENT: UI>Browser>Preferences>Protector
diff --git a/components/chrome_cleaner/public/typemaps/DEPS b/components/chrome_cleaner/public/typemaps/DEPS deleted file mode 100644 index b78e1d2..0000000 --- a/components/chrome_cleaner/public/typemaps/DEPS +++ /dev/null
@@ -1,7 +0,0 @@ -# Allow the typemaps to access their dependencies. -include_rules = [ - '+base/containers/span.h', - '+base/files/file_path.h', - '+base/strings/string16.h', - '+build/build_config.h', -]
diff --git a/components/crash/content/app/crashpad_android.cc b/components/crash/content/app/crashpad_android.cc index 09191be..1183271d 100644 --- a/components/crash/content/app/crashpad_android.cc +++ b/components/crash/content/app/crashpad_android.cc
@@ -287,8 +287,16 @@ // adjacent to it. bool GetHandlerTrampoline(std::string* handler_trampoline, std::string* handler_library) { + // The linker doesn't support loading executables passed on its command + // line until Q. + if (!base::android::BuildInfo::GetInstance()->is_at_least_q()) { + return false; + } + Dl_info info; - if (dladdr(reinterpret_cast<void*>(&GetHandlerTrampoline), &info) == 0) { + if (dladdr(reinterpret_cast<void*>(&GetHandlerTrampoline), &info) == 0 || + dlsym(dlopen(info.dli_fname, RTLD_NOLOAD | RTLD_LAZY), + "CrashpadHandlerMain") == nullptr) { return false; } @@ -498,15 +506,8 @@ } if (!base::PathExists(handler_path)) { - // The linker doesn't support loading executables passed on its command - // line until Q. - if (base::android::BuildInfo::GetInstance()->is_at_least_q()) { - bool found_library = - GetHandlerTrampoline(&handler_trampoline_, &handler_library_); - DCHECK(found_library); - } else { - use_java_handler_ = true; - } + use_java_handler_ = + !GetHandlerTrampoline(&handler_trampoline_, &handler_library_); } if (!dump_at_crash) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc index 27a95bf..850e7edc 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
@@ -19,6 +19,7 @@ #include "base/test/task_environment.h" #include "base/time/time.h" #include "base/values.h" +#include "build/build_config.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h" @@ -972,7 +973,13 @@ VerifyDailyDataSavingContentLengthPrefLists(nullptr, 0, nullptr, 0, 0); } -TEST_F(DataReductionProxyCompressionStatsTest, WeeklyAggregateDataUse) { +// Aggregate metrics recording was disabled on Android x86 in crbug.com/865373. +#if defined(OS_ANDROID) && defined(ARCH_CPU_X86) +#define MAYBE_WeeklyAggregateDataUse DISABLED_WeeklyAggregateDataUse +#else +#define MAYBE_WeeklyAggregateDataUse WeeklyAggregateDataUse +#endif +TEST_F(DataReductionProxyCompressionStatsTest, MAYBE_WeeklyAggregateDataUse) { const int32_t kDataUseKB = 100; base::HistogramTester histogram_tester; @@ -1021,7 +1028,14 @@ data_use_measurement::DataUseUserData::MAIN_FRAME_HTML, 0); } -TEST_F(DataReductionProxyCompressionStatsTest, AggregateDataUseForwardWeeks) { +// Aggregate metrics recording was disabled on Android x86 in crbug.com/865373. +#if defined(OS_ANDROID) && defined(ARCH_CPU_X86) +#define MAYBE_AggregateDataUseForwardWeeks DISABLED_AggregateDataUseForwardWeeks +#else +#define MAYBE_AggregateDataUseForwardWeeks AggregateDataUseForwardWeeks +#endif +TEST_F(DataReductionProxyCompressionStatsTest, + MAYBE_AggregateDataUseForwardWeeks) { const int32_t kMainFrameKB = 100; const int32_t kNonMainFrameKB = 101; base::HistogramTester histogram_tester;
diff --git a/components/flags_ui/OWNERS b/components/flags_ui/OWNERS index 6fc413e..f93ac61e 100644 --- a/components/flags_ui/OWNERS +++ b/components/flags_ui/OWNERS
@@ -1,5 +1,6 @@ file://ui/webui/PLATFORM_OWNERS asvitkine@chromium.org +ellyjones@chromium.org # COMPONENT: UI>Browser>WebUI
diff --git a/components/gcm_driver/web_push_common.cc b/components/gcm_driver/web_push_common.cc index 536b99bf..2ba54dc 100644 --- a/components/gcm_driver/web_push_common.cc +++ b/components/gcm_driver/web_push_common.cc
@@ -21,4 +21,8 @@ base::UmaHistogramCounts10000("GCM.SendWebPushMessagePayloadSize", size); } +void LogSendWebPushMessageStatusCode(int status_code) { + base::UmaHistogramSparse("GCM.SendWebPushMessageStatusCode", status_code); +} + } // namespace gcm
diff --git a/components/gcm_driver/web_push_common.h b/components/gcm_driver/web_push_common.h index 743a87a7..e7d364d 100644 --- a/components/gcm_driver/web_push_common.h +++ b/components/gcm_driver/web_push_common.h
@@ -43,6 +43,9 @@ // web push message is sent. void LogSendWebPushMessagePayloadSize(int size); +// Logs the network error or status code after a web push message is sent. +void LogSendWebPushMessageStatusCode(int status_code); + } // namespace gcm #endif // COMPONENTS_GCM_DRIVER_WEB_PUSH_COMMON_H_
diff --git a/components/gcm_driver/web_push_sender.cc b/components/gcm_driver/web_push_sender.cc index b85e8543..67df65a6 100644 --- a/components/gcm_driver/web_push_sender.cc +++ b/components/gcm_driver/web_push_sender.cc
@@ -179,30 +179,32 @@ WebPushCallback callback, std::unique_ptr<std::string> response_body) { int net_error = url_loader->NetError(); - if (net_error == net::ERR_INSUFFICIENT_RESOURCES) { - DLOG(ERROR) << "VAPID key invalid"; - InvokeWebPushCallback(std::move(callback), - SendWebPushMessageResult::kVapidKeyInvalid); - return; - } - if (net_error != net::OK) { - DLOG(ERROR) << "Network Error: " << net_error; - InvokeWebPushCallback(std::move(callback), - SendWebPushMessageResult::kNetworkError); + LogSendWebPushMessageStatusCode(net_error); + if (net_error == net::ERR_INSUFFICIENT_RESOURCES) { + DLOG(ERROR) << "VAPID key invalid"; + InvokeWebPushCallback(std::move(callback), + SendWebPushMessageResult::kVapidKeyInvalid); + } else { + DLOG(ERROR) << "Network Error: " << net_error; + InvokeWebPushCallback(std::move(callback), + SendWebPushMessageResult::kNetworkError); + } return; } - scoped_refptr<net::HttpResponseHeaders> response_headers = - url_loader->ResponseInfo()->headers; - if (!url_loader->ResponseInfo() || !response_headers) { + if (!url_loader->ResponseInfo() || !url_loader->ResponseInfo()->headers) { + LogSendWebPushMessageStatusCode(net::OK); DLOG(ERROR) << "Response info not found"; InvokeWebPushCallback(std::move(callback), SendWebPushMessageResult::kServerError); return; } + scoped_refptr<net::HttpResponseHeaders> response_headers = + url_loader->ResponseInfo()->headers; int response_code = response_headers->response_code(); + LogSendWebPushMessageStatusCode(response_code); if (response_code == net::HTTP_NOT_FOUND || response_code == net::HTTP_GONE) { DLOG(ERROR) << "Device no longer registered"; InvokeWebPushCallback(std::move(callback), @@ -244,7 +246,7 @@ InvokeWebPushCallback(std::move(callback), SendWebPushMessageResult::kSuccessful, - location.substr(slash_pos + 1)); + /*message_id=*/location.substr(slash_pos + 1)); } } // namespace gcm
diff --git a/components/offline_pages/core/archive_validator_unittest.cc b/components/offline_pages/core/archive_validator_unittest.cc index 20de231..f9ab9088 100644 --- a/components/offline_pages/core/archive_validator_unittest.cc +++ b/components/offline_pages/core/archive_validator_unittest.cc
@@ -168,7 +168,8 @@ } #if defined(OS_ANDROID) -TEST_F(ArchiveValidatorTest, ValidateContentUri) { +// Flaky. https://crbug.com/1022322 +TEST_F(ArchiveValidatorTest, DISABLED_ValidateContentUri) { base::FilePath content_uri_path = GetContentUriPathForTest(); EXPECT_TRUE(ArchiveValidator::ValidateFile( content_uri_path, kSizeForTestContentUri, kExpectedDigestForContentUri));
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc index 77717b9..90eeec8 100644 --- a/components/omnibox/browser/autocomplete_result.cc +++ b/components/omnibox/browser/autocomplete_result.cc
@@ -201,6 +201,8 @@ for (auto i(matches_.begin()); i != matches_.end(); ++i) i->ComputeStrippedDestinationURL(input, template_url_service); + CompareWithDemoteByType<AutocompleteMatch> comparing_object( + input.current_page_classification()); #if !(defined(OS_ANDROID) || defined(OS_IOS)) // Do not cull the tail suggestions for zero prefix query suggetions of // chromeOS launcher or NTP, since there won't be any default match in this @@ -210,7 +212,7 @@ metrics::OmniboxEventProto::CHROMEOS_APP_LIST || BaseSearchProvider::IsNTPPage(input.current_page_classification())))) { // Wipe tail suggestions if not exclusive (minus default match). - MaybeCullTailSuggestions(&matches_); + MaybeCullTailSuggestions(&matches_, comparing_object); } #endif DemoteOnDeviceSearchSuggestions(); @@ -218,8 +220,6 @@ DeduplicateMatches(input.current_page_classification(), &matches_); // Sort and trim to the most relevant GetMaxMatches() matches. - CompareWithDemoteByType<AutocompleteMatch> comparing_object( - input.current_page_classification()); std::sort(matches_.begin(), matches_.end(), comparing_object); // Find the best match and rotate it to the front to become the default match. @@ -530,7 +530,7 @@ // the highest-relevance, allowed-to-be-default match while ignoring type // demotion, as we do when IsPreserveDefaultMatchScoreEnabled is true, we need // to explicitly find the highest relevance match rather than just accepting - // the first allowed-to-be--default match in the list. + // the first allowed-to-be-default match in the list. // The goal of this behavior is to ensure that in situations where the user // expects to see a commonly visited URL as the default match, the URL is not // suppressed by type demotion. @@ -554,7 +554,7 @@ return best; } else { return std::find_if(matches->begin(), matches->end(), [](const auto& m) { - return m.allowed_to_be_default_match; + return m.allowed_to_be_default_match && !m.IsSubMatch(); }); } } @@ -797,19 +797,39 @@ } // static -void AutocompleteResult::MaybeCullTailSuggestions(ACMatches* matches) { +void AutocompleteResult::MaybeCullTailSuggestions( + ACMatches* matches, + const CompareWithDemoteByType<AutocompleteMatch>& comparing_object) { + // This function implements the following logic: + // ('E' == 'There exists', '!E' == 'There does not exist') + // 1) !E default non-tail and E tail default? remove non-tails + // 2) !E any tails at all? do nothing + // 3) E default non-tail and other non-tails? remove tails + // 4) E default non-tail and no other non-tails? mark tails as non-default + // 5) E non-default non-tails? remove non-tails std::function<bool(const AutocompleteMatch&)> is_tail = [](const AutocompleteMatch& match) { return match.type == ACMatchType::SEARCH_SUGGEST_TAIL; }; - auto non_tail_default = std::find_if( - matches->begin(), matches->end(), [&](const AutocompleteMatch& match) { - return match.allowed_to_be_default_match && !is_tail(match); - }); - bool tail_default_exists = std::any_of( - matches->begin(), matches->end(), [&](const AutocompleteMatch& match) { - return match.allowed_to_be_default_match && is_tail(match); - }); + auto default_non_tail = matches->end(); + auto default_tail = matches->end(); + bool other_non_tails = false, any_tails = false; + for (auto i = matches->begin(); i != matches->end(); ++i) { + if (comparing_object.GetDemotedRelevance(*i) == 0) + continue; + if (!is_tail(*i)) { + // We allow one default non-tail match. For non-default matches, + // don't consider if we'd remove them later. + if (default_non_tail == matches->end() && i->allowed_to_be_default_match) + default_non_tail = i; + else + other_non_tails = true; + } else { + any_tails = true; + if (default_tail == matches->end() && i->allowed_to_be_default_match) + default_tail = i; + } + } // If the only default matches are tail suggestions, let them remain and // instead remove the non-tail suggestions. This is necessary because we do // not want to display tail suggestions mixed with other suggestions in the @@ -818,39 +838,35 @@ // default match--the non-tail ones much go. This situation though is // unlikely, as we normally would expect the search-what-you-typed suggestion // as a default match (and that's a non-tail suggestion). - if (tail_default_exists && non_tail_default == matches->end()) { - base::EraseIf(*matches, [&is_tail](const AutocompleteMatch& match) { - return !is_tail(match); - }); + // 1) above. + if (default_tail != matches->end() && default_non_tail == matches->end()) { + base::EraseIf(*matches, std::not1(is_tail)); return; } - // Determine if there are both tail and non-tail matches, excluding the - // non-tail default match. - bool any_tail = false, any_non_tail = false; - for (auto i = matches->begin(); - i != matches->end() && !(any_tail && any_non_tail); ++i) { - // We allow one default non-tail match. - if (i != non_tail_default) { - if (is_tail(*i)) - any_tail = true; - else - any_non_tail = true; - } - } + // 2) above. + if (!any_tails) + return; // If both tail and non-tail matches, remove tail. Note that this can // remove the highest rated suggestions. - if (any_tail) { - if (any_non_tail) { + if (default_non_tail != matches->end()) { + // 3) above. + if (other_non_tails) { base::EraseIf(*matches, is_tail); } else { - // We want the non-tail default match to be first. Mark tail suggestions - // as not a legal default match, so that the default match will be moved - // up explicitly. + // 4) above. + // We want the non-tail default match to be placed first. Mark tail + // suggestions as not a legal default match, so that the default match + // will be moved up explicitly. for (auto& match : *matches) { if (is_tail(match)) match.allowed_to_be_default_match = false; } } + } else if (other_non_tails && default_tail == matches->end()) { + // 5) above. + // If there are no defaults at all, but non-tail suggestions exist, remove + // the tail suggestions. + base::EraseIf(*matches, is_tail); } }
diff --git a/components/omnibox/browser/autocomplete_result.h b/components/omnibox/browser/autocomplete_result.h index 9b67f558..3966c8b 100644 --- a/components/omnibox/browser/autocomplete_result.h +++ b/components/omnibox/browser/autocomplete_result.h
@@ -193,7 +193,9 @@ // If there are both tail and non-tail suggestions (ignoring one default // match), remove the tail suggestions. If the only default matches are tail // suggestions, remove the non-tail suggestions. - static void MaybeCullTailSuggestions(ACMatches* matches); + static void MaybeCullTailSuggestions( + ACMatches* matches, + const CompareWithDemoteByType<AutocompleteMatch>& comparing_object); // Populates |provider_to_matches| from |matches_|. This AutocompleteResult // should not be used after the 'move' version.
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc index a1ee48b5..e5c4952 100644 --- a/components/omnibox/browser/autocomplete_result_unittest.cc +++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -524,6 +524,76 @@ } } +TEST_F(AutocompleteResultTest, SortAndCullZeroRelevanceSuggestions) { + // clang-format off + TestData data[] = { + {1, 1, 1000, true}, // A default non-tail suggestion. + {2, 1, 0, true}, // A no-relevance default non-tail suggestion. + {3, 1, 1100, true}, // Default tail + {4, 1, 1000, false}, // Tail + {5, 1, 1300, false}, // Tail + {6, 1, 0, false}, // No-relevance tail suggestion. + }; + // clang-format on + + ACMatches matches; + PopulateAutocompleteMatches(data, base::size(data), &matches); + for (size_t i = 2; i < base::size(data); ++i) + matches[i].type = AutocompleteMatchType::SEARCH_SUGGEST_TAIL; + + AutocompleteInput input(base::ASCIIToUTF16("a"), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + AutocompleteResult result; + result.AppendMatches(input, matches); + result.SortAndCull(input, template_url_service_.get()); + + EXPECT_EQ(4UL, result.size()); + EXPECT_NE(AutocompleteMatchType::SEARCH_SUGGEST_TAIL, + result.match_at(0)->type); + EXPECT_TRUE(result.match_at(0)->allowed_to_be_default_match); + for (size_t i = 1; i < 4; ++i) { + EXPECT_EQ(AutocompleteMatchType::SEARCH_SUGGEST_TAIL, + result.match_at(i)->type); + EXPECT_FALSE(result.match_at(i)->allowed_to_be_default_match); + } +} + +TEST_F(AutocompleteResultTest, SortAndCullZeroRelevanceDefaultMatches) { + // clang-format off + TestData data[] = { + {1, 1, 0, true}, // A zero-relevance default non-tail suggestion. + {2, 1, 1100, true}, // Default tail + {3, 1, 1000, false}, // Tail + {4, 1, 1300, false}, // Tail + {5, 1, 0, false}, // No-relevance tail suggestion. + }; + // clang-format on + + ACMatches matches; + PopulateAutocompleteMatches(data, base::size(data), &matches); + for (size_t i = 1; i < base::size(data); ++i) + matches[i].type = AutocompleteMatchType::SEARCH_SUGGEST_TAIL; + + AutocompleteInput input(base::ASCIIToUTF16("a"), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + AutocompleteResult result; + result.AppendMatches(input, matches); + result.SortAndCull(input, template_url_service_.get()); + + // It should ignore the first suggestion, despite it being marked as + // allowed to be default. + EXPECT_EQ(3UL, result.size()); + EXPECT_TRUE(result.match_at(0)->allowed_to_be_default_match); + for (size_t i = 0; i < 3; ++i) { + EXPECT_EQ(AutocompleteMatchType::SEARCH_SUGGEST_TAIL, + result.match_at(i)->type); + if (i > 0) + EXPECT_FALSE(result.match_at(i)->allowed_to_be_default_match); + } +} + #endif TEST_F(AutocompleteResultTest, SortAndCullOnlyTailSuggestions) {
diff --git a/components/password_manager/core/browser/import/csv_password.cc b/components/password_manager/core/browser/import/csv_password.cc index 0a78a697..a2faf716 100644 --- a/components/password_manager/core/browser/import/csv_password.cc +++ b/components/password_manager/core/browser/import/csv_password.cc
@@ -35,12 +35,12 @@ CSVPassword::~CSVPassword() = default; -bool CSVPassword::Parse(PasswordForm* form) const { +CSVPassword::Status CSVPassword::Parse(PasswordForm* form) const { // |map_| must be an (1) injective and (2) surjective (3) partial map. (3) is // enforced by its type, (2) is checked later in the code and (1) follows from // (2) and the following size() check. if (map_.size() != kLabelCount) - return false; + return Status::kSemanticError; size_t field_idx = 0; CSVFieldParser parser(row_); @@ -51,14 +51,14 @@ while (parser.HasMoreFields()) { base::StringPiece field; if (!parser.NextField(&field)) - return false; + return Status::kSyntaxError; auto meaning_it = map_.find(field_idx++); if (meaning_it == map_.end()) continue; switch (meaning_it->second) { case Label::kOrigin: if (!base::IsStringASCII(field)) - return false; + return Status::kSyntaxError; origin = GURL(field); break; case Label::kUsername: @@ -74,9 +74,9 @@ // username is permitted to be an empty string, while password and origin are // not. if (!origin.is_valid() || !username_set || password.empty()) - return false; + return Status::kSemanticError; if (!form) - return true; + return Status::kOK; // There is currently no way to import non-HTML credentials. form->scheme = PasswordForm::Scheme::kHtml; // GURL::GetOrigin() returns an empty GURL for Android credentials due @@ -89,13 +89,13 @@ form->origin = std::move(origin); form->username_value = Convert(username); form->password_value = Convert(password); - return true; + return Status::kOK; } PasswordForm CSVPassword::ParseValid() const { PasswordForm result; - bool success = Parse(&result); - DCHECK(success); + Status status = Parse(&result); + DCHECK_EQ(Status::kOK, status); return result; }
diff --git a/components/password_manager/core/browser/import/csv_password.h b/components/password_manager/core/browser/import/csv_password.h index e85ff971..810f71a3 100644 --- a/components/password_manager/core/browser/import/csv_password.h +++ b/components/password_manager/core/browser/import/csv_password.h
@@ -21,6 +21,9 @@ enum class Label { kOrigin, kUsername, kPassword }; using ColumnMap = base::flat_map<size_t, Label>; + // Status describes parsing errors. + enum class Status { kOK, kSyntaxError, kSemanticError }; + // Number of values in the Label enum. static constexpr size_t kLabelCount = 3; @@ -32,10 +35,10 @@ ~CSVPassword(); // Returns whether the associated CSV row can be parsed successfully. - // If returning true and |form| is not null, it also stores the parsed result - // in |*form|. It does not return base::Optional<PasswordForm> for efficiency - // reasons in cases when the parsed form is not needed. - bool Parse(autofill::PasswordForm* form) const; + // If returning success and |form| is not null, it also stores the parsed + // result in |*form|. It does not return base::Optional<PasswordForm> for + // efficiency reasons in cases when the parsed form is not needed. + Status Parse(autofill::PasswordForm* form) const; // Convenience wrapper around Parse() for cases known to be correctly // parseable. autofill::PasswordForm ParseValid() const;
diff --git a/components/password_manager/core/browser/import/csv_password_iterator_unittest.cc b/components/password_manager/core/browser/import/csv_password_iterator_unittest.cc index b9e727a..9024ddac 100644 --- a/components/password_manager/core/browser/import/csv_password_iterator_unittest.cc +++ b/components/password_manager/core/browser/import/csv_password_iterator_unittest.cc
@@ -9,6 +9,7 @@ #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" +#include "components/password_manager/core/browser/import/csv_password.h" #include "testing/gtest/include/gtest/gtest.h" namespace password_manager { @@ -75,9 +76,10 @@ CSVPasswordIterator check = iter; for (size_t i = 0; i < base::size(kExpectedPasswords); ++i) { - EXPECT_TRUE((check++)->Parse(nullptr)) << "on line " << i; + EXPECT_EQ(CSVPassword::Status::kOK, (check++)->Parse(nullptr)) + << "on line " << i; } - EXPECT_FALSE(check->Parse(nullptr)); + EXPECT_NE(CSVPassword::Status::kOK, check->Parse(nullptr)); for (const base::StringPiece& expected_password : kExpectedPasswords) { PasswordForm result = (iter++)->ParseValid(); @@ -107,12 +109,13 @@ CSVPasswordIterator check = iter; for (size_t i = 0; i + 1 < kLinesInBlob; ++i) { - EXPECT_FALSE((check++)->Parse(nullptr)) << "on line " << i; + EXPECT_NE(CSVPassword::Status::kOK, (check++)->Parse(nullptr)) + << "on line " << i; } // Last line was not a failure. - EXPECT_TRUE((check++)->Parse(nullptr)); + EXPECT_EQ(CSVPassword::Status::kOK, (check++)->Parse(nullptr)); // After iterating over all lines, there is no more data to parse. - EXPECT_FALSE(check->Parse(nullptr)); + EXPECT_NE(CSVPassword::Status::kOK, check->Parse(nullptr)); } } // namespace password_manager
diff --git a/components/password_manager/core/browser/import/csv_password_unittest.cc b/components/password_manager/core/browser/import/csv_password_unittest.cc index 03a19ed..43c6420d 100644 --- a/components/password_manager/core/browser/import/csv_password_unittest.cc +++ b/components/password_manager/core/browser/import/csv_password_unittest.cc
@@ -14,6 +14,8 @@ using ::autofill::PasswordForm; +using Status = CSVPassword::Status; + TEST(CSVPassword, Construction) { CSVPassword::ColumnMap col_map = { {0, CSVPassword::Label::kOrigin}, @@ -39,6 +41,7 @@ std::string signon_realm; std::string username; std::string password; + Status status = Status::kOK; }; class TestCaseBuilder { @@ -77,6 +80,11 @@ return *this; } + TestCaseBuilder& Status(Status status) { + test_case_.status = status; + return *this; + } + TestCase Build() { return std::move(test_case_); } private: @@ -89,7 +97,7 @@ const TestCase& test_case = GetParam(); SCOPED_TRACE(test_case.name); CSVPassword csv_pwd(test_case.map, test_case.csv); - EXPECT_TRUE(csv_pwd.Parse(nullptr)); + EXPECT_EQ(Status::kOK, csv_pwd.Parse(nullptr)); PasswordForm result = csv_pwd.ParseValid(); @@ -173,7 +181,8 @@ TEST_P(CSVPasswordTestFailure, Parse) { const TestCase& test_case = GetParam(); SCOPED_TRACE(test_case.name); - EXPECT_FALSE(CSVPassword(test_case.map, test_case.csv).Parse(nullptr)); + EXPECT_EQ(test_case.status, + CSVPassword(test_case.map, test_case.csv).Parse(nullptr)); } INSTANTIATE_TEST_SUITE_P( @@ -182,51 +191,60 @@ ::testing::Values(TestCaseBuilder("no columns specified") .Map({}) .CSV("http://example.com,user,password") + .Status(Status::kSemanticError) .Build(), TestCaseBuilder("not ASCII") .Map({{0, CSVPassword::Label::kOrigin}, {1, CSVPassword::Label::kUsername}, {2, CSVPassword::Label::kPassword}}) .CSV("http://example.com/Å™,user,password") + .Status(Status::kSyntaxError) .Build(), TestCaseBuilder("no origin in map") .Map({{1, CSVPassword::Label::kUsername}, {2, CSVPassword::Label::kPassword}}) .CSV("http://example.com,user,password") + .Status(Status::kSemanticError) .Build(), TestCaseBuilder("no username in map") .Map({{0, CSVPassword::Label::kOrigin}, {2, CSVPassword::Label::kPassword}}) .CSV("http://example.com,user,password") + .Status(Status::kSemanticError) .Build(), TestCaseBuilder("no password in map") .Map({{0, CSVPassword::Label::kOrigin}, {1, CSVPassword::Label::kUsername}}) .CSV("http://example.com,user,password") + .Status(Status::kSemanticError) .Build(), TestCaseBuilder("no origin in CSV") .Map({{0, CSVPassword::Label::kUsername}, {1, CSVPassword::Label::kPassword}, {2, CSVPassword::Label::kOrigin}}) .CSV("user,password") + .Status(Status::kSemanticError) .Build(), TestCaseBuilder("no username in CSV") .Map({{0, CSVPassword::Label::kOrigin}, {1, CSVPassword::Label::kPassword}, {2, CSVPassword::Label::kUsername}}) .CSV("http://example.com,password") + .Status(Status::kSemanticError) .Build(), TestCaseBuilder("no password in CSV") .Map({{0, CSVPassword::Label::kOrigin}, {1, CSVPassword::Label::kUsername}, {2, CSVPassword::Label::kPassword}}) .CSV("http://example.com,user") + .Status(Status::kSemanticError) .Build(), TestCaseBuilder("malformed CSV") .Map({{0, CSVPassword::Label::kOrigin}, {1, CSVPassword::Label::kUsername}, {2, CSVPassword::Label::kPassword}}) .CSV("\"") + .Status(Status::kSyntaxError) .Build(), TestCaseBuilder("map not injective") .Map({{0, CSVPassword::Label::kOrigin}, @@ -234,6 +252,7 @@ {2, CSVPassword::Label::kPassword}, {3, CSVPassword::Label::kUsername}}) .CSV("http://example.com,user,pwd,user2") + .Status(Status::kSemanticError) .Build())); } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h index 3e9414a2..aa0ce43 100644 --- a/components/password_manager/core/browser/password_manager_client.h +++ b/components/password_manager/core/browser/password_manager_client.h
@@ -54,6 +54,7 @@ namespace password_manager { +class FieldInfoManager; class PasswordFeatureManager; class PasswordFormManagerForUI; class PasswordManager; @@ -355,6 +356,9 @@ // Returns true if the current page is to the new tab page. virtual bool IsNewTabPage() const = 0; + // Returns a FieldInfoManager associated with the current profile. + virtual FieldInfoManager* GetFieldInfoManager() const = 0; + private: DISALLOW_COPY_AND_ASSIGN(PasswordManagerClient); };
diff --git a/components/password_manager/core/browser/stub_password_manager_client.cc b/components/password_manager/core/browser/stub_password_manager_client.cc index f4a2d90..f17ea98 100644 --- a/components/password_manager/core/browser/stub_password_manager_client.cc +++ b/components/password_manager/core/browser/stub_password_manager_client.cc
@@ -151,4 +151,8 @@ return false; } +FieldInfoManager* StubPasswordManagerClient::GetFieldInfoManager() const { + return nullptr; +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/stub_password_manager_client.h b/components/password_manager/core/browser/stub_password_manager_client.h index 8ba8d18..c62b03d1 100644 --- a/components/password_manager/core/browser/stub_password_manager_client.h +++ b/components/password_manager/core/browser/stub_password_manager_client.h
@@ -91,6 +91,7 @@ scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; bool IsIsolationForPasswordSitesEnabled() const override; bool IsNewTabPage() const override; + FieldInfoManager* GetFieldInfoManager() const override; private: const StubCredentialsFilter credentials_filter_;
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index 0eda211..e841ab6 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -12,7 +12,6 @@ // Everything below this comment will be synchronized between client and server // repos ( go/cros-proto-sync ). -// Please don't manually edit any lines below this comment. message DevicePolicyRefreshRateProto { // In milliseconds.
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index 51c9939..e67f9c9 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -10,7 +10,6 @@ // Everything below this comment will be synchronized between client and server // repos ( go/cros-proto-sync ). -// Please don't manually edit any lines below this comment. // This enum needs to be shared between DeviceRegisterRequest and // LicenseAvailability protos. With java_api_version 1, this means that enum
diff --git a/components/policy/proto/policy_common_definitions.proto b/components/policy/proto/policy_common_definitions.proto index b5ffd71..676d9cd7 100644 --- a/components/policy/proto/policy_common_definitions.proto +++ b/components/policy/proto/policy_common_definitions.proto
@@ -10,7 +10,6 @@ // Everything below this comment will be synchronized between client and server // repos ( go/cros-proto-sync ). -// Please don't manually edit any lines below this comment. message StringList { repeated string entries = 1;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 0cd17f80..4d89975 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -13115,7 +13115,7 @@ 'type': 'array', 'items': { 'type': 'string' }, }, - 'supported_on': ['chrome.*:80-', 'chrome_os:80-'], + 'supported_on': ['chrome.*:79-', 'chrome_os:79-'], 'features': { 'dynamic_refresh': False, 'per_profile': True,
diff --git a/components/security_interstitials_strings.grdp b/components/security_interstitials_strings.grdp index 903497d..9bae094 100644 --- a/components/security_interstitials_strings.grdp +++ b/components/security_interstitials_strings.grdp
@@ -66,7 +66,7 @@ <!-- Lookalike URL warning --> <message name="IDS_LOOKALIKE_URL_TITLE" desc="Tab title. Context: the requested URL might be trying to trick the user since it looks like a more popular URL. This interstitial points the user to the safe site instead."> - Did you mean? + Did you mean <ph name="DOMAIN">$1<ex>example.com</ex></ph>? </message> <message name="IDS_LOOKALIKE_URL_HEADING" desc="Large heading. Context: the error page that's shown when the requested URL might be trying to trick the user since it looks like a more popular URL. This interstitial points the user to the safe site instead."> Did you mean <a href="#" id="dont-proceed-link"><ph name="DOMAIN">$1<ex>example.com</ex></ph></a>?
diff --git a/components/test/data/payments/PRESUBMIT.py b/components/test/data/payments/PRESUBMIT.py deleted file mode 100644 index 8eae247..0000000 --- a/components/test/data/payments/PRESUBMIT.py +++ /dev/null
@@ -1,22 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -def _CommonChecks(input_api, output_api): - results = [] - try: - import sys - old_sys_path = sys.path - cwd = input_api.PresubmitLocalPath() - sys.path += [input_api.os_path.join(cwd, '..', '..', '..', '..', 'tools')] - import web_dev_style.presubmit_support - results = web_dev_style.presubmit_support.CheckStyle(input_api, output_api) - finally: - sys.path = old_sys_path - 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/components/typemaps.gni b/components/typemaps.gni index 879e7796..ca61b1f 100644 --- a/components/typemaps.gni +++ b/components/typemaps.gni
@@ -5,7 +5,6 @@ typemaps = [ "//components/account_id/mojom/account_id.typemap", "//components/autofill/core/common/mojom/autofill_types.typemap", - "//components/chrome_cleaner/public/typemaps/chrome_prompt.typemap", "//components/content_capture/common/content_capture.typemap", "//components/content_settings/core/common/content_settings.typemap", "//components/nacl/common/nacl.typemap",
diff --git a/components/viz/common/gpu/DEPS b/components/viz/common/gpu/DEPS index 5cbd28a..ba50fcbe2 100644 --- a/components/viz/common/gpu/DEPS +++ b/components/viz/common/gpu/DEPS
@@ -7,7 +7,6 @@ "+gpu/command_buffer", "+gpu/GLES2/gl2extchromium.h", "+gpu/vulkan", - "+third_party/dawn/src/include", "+third_party/khronos/GLES2/gl2.h", "+third_party/skia/include/gpu", "+third_party/vulkan/include",
diff --git a/components/viz/common/gpu/dawn_context_provider.cc b/components/viz/common/gpu/dawn_context_provider.cc index d57ef4c..6c1f978 100644 --- a/components/viz/common/gpu/dawn_context_provider.cc +++ b/components/viz/common/gpu/dawn_context_provider.cc
@@ -4,10 +4,11 @@ #include "components/viz/common/gpu/dawn_context_provider.h" +#include <dawn/dawn_proc.h> + #include "base/logging.h" #include "base/memory/ptr_util.h" #include "build/build_config.h" -#include "third_party/dawn/src/include/dawn/dawn_proc.h" namespace viz {
diff --git a/components/viz/common/gpu/dawn_context_provider.h b/components/viz/common/gpu/dawn_context_provider.h index b1d81b1..dc4c53e 100644 --- a/components/viz/common/gpu/dawn_context_provider.h +++ b/components/viz/common/gpu/dawn_context_provider.h
@@ -5,9 +5,10 @@ #ifndef COMPONENTS_VIZ_COMMON_GPU_DAWN_CONTEXT_PROVIDER_H_ #define COMPONENTS_VIZ_COMMON_GPU_DAWN_CONTEXT_PROVIDER_H_ +#include <dawn_native/DawnNative.h> + #include "base/macros.h" #include "components/viz/common/viz_dawn_context_provider_export.h" -#include "third_party/dawn/src/include/dawn_native/DawnNative.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/dawn/GrDawnTypes.h"
diff --git a/components/viz/common/resources/DEPS b/components/viz/common/resources/DEPS index 7fbfdb3..c98a60da 100644 --- a/components/viz/common/resources/DEPS +++ b/components/viz/common/resources/DEPS
@@ -11,7 +11,6 @@ "+mojo/public/cpp/system/buffer.h", "+mojo/public/cpp/system/platform_handle.h", "+skia/buildflags.h", - "+third_party/dawn/src/include", "+third_party/khronos/GLES2", "+third_party/skia", "+third_party/vulkan",
diff --git a/components/viz/common/resources/resource_format_utils.h b/components/viz/common/resources/resource_format_utils.h index eb8748f9..33ebb5c 100644 --- a/components/viz/common/resources/resource_format_utils.h +++ b/components/viz/common/resources/resource_format_utils.h
@@ -18,7 +18,7 @@ #endif #if BUILDFLAG(SKIA_USE_DAWN) -#include "third_party/dawn/src/include/dawn/dawncpp.h" // nogncheck +#include <dawn/dawncpp.h> #endif namespace viz {
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index e80a645..b3e1580a 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -683,6 +683,9 @@ render_pass_requires_scissor); FinishDrawingQuadList(); + if (is_root_render_pass && overdraw_feedback_) + FlushOverdrawFeedback(render_pass_scissor_in_draw_space); + if (render_pass->generate_mipmap) GenerateMipmap(); }
diff --git a/components/viz/service/display/direct_renderer.h b/components/viz/service/display/direct_renderer.h index c12b9d1d..b4021d6 100644 --- a/components/viz/service/display/direct_renderer.h +++ b/components/viz/service/display/direct_renderer.h
@@ -206,6 +206,7 @@ virtual void DoDrawQuad(const DrawQuad* quad, const gfx::QuadF* clip_region) = 0; virtual void BeginDrawingFrame() = 0; + virtual void FlushOverdrawFeedback(const gfx::Rect& output_rect) {} virtual void FinishDrawingFrame() = 0; // If a pass contains a single tile draw quad and can be drawn without // a render pass (e.g. applying a filter directly to the tile quad)
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index cf811dc..3a601c8 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -2725,8 +2725,6 @@ } swap_buffer_rect_.Union(current_frame()->root_damage_rect); - if (overdraw_feedback_) - FlushOverdrawFeedback(swap_buffer_rect_); if (use_swap_with_bounds_) swap_content_bounds_ = current_frame()->root_content_bounds; @@ -2799,9 +2797,6 @@ std::unique_ptr<CopyOutputRequest> request) { TRACE_EVENT0("viz", "GLRenderer::CopyDrawnRenderPass"); - if (overdraw_feedback_) - FlushOverdrawFeedback(current_frame()->current_render_pass->output_rect); - GLuint framebuffer_texture = 0; gfx::Size framebuffer_texture_size; if (current_framebuffer_texture_) {
diff --git a/components/viz/service/display/gl_renderer.h b/components/viz/service/display/gl_renderer.h index ad7718b..2273f20 100644 --- a/components/viz/service/display/gl_renderer.h +++ b/components/viz/service/display/gl_renderer.h
@@ -102,6 +102,7 @@ void DoDrawQuad(const class DrawQuad*, const gfx::QuadF* draw_region) override; void BeginDrawingFrame() override; + void FlushOverdrawFeedback(const gfx::Rect& output_rect) override; void FinishDrawingFrame() override; bool FlippedFramebuffer() const override; bool FlippedRootFramebuffer() const; @@ -330,7 +331,7 @@ // Setup/flush all pending overdraw feedback to framebuffer. void SetupOverdrawFeedback(); - void FlushOverdrawFeedback(const gfx::Rect& output_rect); + // Process overdraw feedback from query. void ProcessOverdrawFeedback(std::vector<int>* overdraw, size_t num_expected_results,
diff --git a/components/viz/service/display/skia_output_surface.h b/components/viz/service/display/skia_output_surface.h index ae7dbf5..f51730c 100644 --- a/components/viz/service/display/skia_output_surface.h +++ b/components/viz/service/display/skia_output_surface.h
@@ -133,8 +133,10 @@ // ScheduleDCLayers() will be called. virtual void SetEnableDCLayers(bool enable) = 0; - // Schedule drawing DC layer overlays at next SkiaSwapBuffers() call. - virtual void ScheduleDCLayers(std::vector<DCLayerOverlay> dc_layers) = 0; + // Schedule drawing DC layer overlays at next SkiaSwapBuffers() call. Waits on + // |sync_tokens| for the overlay textures to be ready before scheduling. + virtual void ScheduleDCLayers(std::vector<DCLayerOverlay> dc_layers, + std::vector<gpu::SyncToken> sync_tokens) = 0; // Add context lost observer. virtual void AddContextLostObserver(ContextLostObserver* observer) = 0;
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index d110134..5ce9fd3e 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -2044,6 +2044,7 @@ if (current_frame()->dc_layer_overlay_list.empty()) return; + std::vector<gpu::SyncToken> sync_tokens; for (auto& dc_layer_overlay : current_frame()->dc_layer_overlay_list) { for (size_t i = 0; i < DCLayerOverlay::kNumResources; ++i) { ResourceId resource_id = dc_layer_overlay.resources[i]; @@ -2053,6 +2054,12 @@ // Resources will be unlocked after the next call to SwapBuffers(). auto* image_context = lock_set_for_external_use_->LockResource(resource_id, true); + + // Sync tokens ensure the texture to be overlaid is available before + // scheduling it for display. + DCHECK(image_context->mailbox_holder().sync_token.HasData()); + sync_tokens.push_back(image_context->mailbox_holder().sync_token); + dc_layer_overlay.mailbox[i] = image_context->mailbox_holder().mailbox; } DCHECK(!dc_layer_overlay.mailbox[0].IsZero()); @@ -2060,7 +2067,8 @@ has_locked_overlay_resources_ = true; skia_output_surface_->ScheduleDCLayers( - std::move(current_frame()->dc_layer_overlay_list)); + std::move(current_frame()->dc_layer_overlay_list), + std::move(sync_tokens)); } sk_sp<SkColorFilter> SkiaRenderer::GetColorFilter(const gfx::ColorSpace& src,
diff --git a/components/viz/service/display_embedder/DEPS b/components/viz/service/display_embedder/DEPS index 38a3343..577b438e 100644 --- a/components/viz/service/display_embedder/DEPS +++ b/components/viz/service/display_embedder/DEPS
@@ -31,7 +31,6 @@ "+mojo/public/cpp/bindings", "+mojo/public/cpp/system", "+skia", - "+third_party/dawn/src/include", "+third_party/khronos/GLES2/gl2.h", "+third_party/khronos/GLES2/gl2ext.h", "+third_party/skia",
diff --git a/components/viz/service/display_embedder/skia_output_device_dawn.cc b/components/viz/service/display_embedder/skia_output_device_dawn.cc index b2153b8..aa9b901f 100644 --- a/components/viz/service/display_embedder/skia_output_device_dawn.cc +++ b/components/viz/service/display_embedder/skia_output_device_dawn.cc
@@ -9,9 +9,9 @@ #include "components/viz/common/gpu/dawn_context_provider.h" #if defined(OS_WIN) -#include "third_party/dawn/src/include/dawn_native/D3D12Backend.h" +#include <dawn_native/D3D12Backend.h> #elif defined(OS_LINUX) -#include "third_party/dawn/src/include/dawn_native/VulkanBackend.h" +#include <dawn_native/VulkanBackend.h> #endif namespace viz {
diff --git a/components/viz/service/display_embedder/skia_output_device_dawn.h b/components/viz/service/display_embedder/skia_output_device_dawn.h index a39722b..607f400 100644 --- a/components/viz/service/display_embedder/skia_output_device_dawn.h +++ b/components/viz/service/display_embedder/skia_output_device_dawn.h
@@ -5,10 +5,11 @@ #ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_ #define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_ +#include <dawn/dawn_wsi.h> +#include <dawn/dawncpp.h> +#include <dawn_native/DawnNative.h> + #include "components/viz/service/display_embedder/skia_output_device.h" -#include "third_party/dawn/src/include/dawn/dawn_wsi.h" -#include "third_party/dawn/src/include/dawn/dawncpp.h" -#include "third_party/dawn/src/include/dawn_native/DawnNative.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/gpu/GrBackendSurface.h"
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 0deeecb..eda3bb4e 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -621,11 +621,12 @@ } void SkiaOutputSurfaceImpl::ScheduleDCLayers( - std::vector<DCLayerOverlay> overlays) { + std::vector<DCLayerOverlay> overlays, + std::vector<gpu::SyncToken> sync_tokens) { auto task = base::BindOnce(&SkiaOutputSurfaceImplOnGpu::ScheduleDCLayers, base::Unretained(impl_on_gpu_.get()), std::move(overlays)); - ScheduleGpuTask(std::move(task), {}); + ScheduleGpuTask(std::move(task), std::move(sync_tokens)); } void SkiaOutputSurfaceImpl::SetCapabilitiesForTesting(
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index 8345677..4f03f5d 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -115,7 +115,8 @@ void RemoveRenderPassResource(std::vector<RenderPassId> ids) override; void SetEnableDCLayers(bool enable) override; - void ScheduleDCLayers(std::vector<DCLayerOverlay> overlays) override; + void ScheduleDCLayers(std::vector<DCLayerOverlay> overlays, + std::vector<gpu::SyncToken> sync_tokens) override; void CopyOutput(RenderPassId id, const copy_output::RenderPassGeometry& geometry, const gfx::ColorSpace& color_space,
diff --git a/components/viz/test/fake_skia_output_surface.h b/components/viz/test/fake_skia_output_surface.h index cf291e2..8994312 100644 --- a/components/viz/test/fake_skia_output_surface.h +++ b/components/viz/test/fake_skia_output_surface.h
@@ -90,7 +90,8 @@ sk_sp<SkColorSpace> color_space) override; void RemoveRenderPassResource(std::vector<RenderPassId> ids) override; void SetEnableDCLayers(bool enable) override {} - void ScheduleDCLayers(std::vector<DCLayerOverlay> overlays) override {} + void ScheduleDCLayers(std::vector<DCLayerOverlay> overlays, + std::vector<gpu::SyncToken> sync_tokens) override {} void CopyOutput(RenderPassId id, const copy_output::RenderPassGeometry& geometry, const gfx::ColorSpace& color_space,
diff --git a/content/browser/DEPS b/content/browser/DEPS index 7205411c..d014086 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS
@@ -116,7 +116,6 @@ "+third_party/blink/public/platform/web_touch_event.h", "+third_party/blink/public/platform/web_text_input_type.h", "+third_party/blink/public/platform/mac/web_scrollbar_theme.h", - "+third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h", "+third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h", "+third_party/blink/public/platform/modules/sms/sms_receiver.mojom.h", "+third_party/blink/public/public_buildflags.h",
diff --git a/content/browser/android/web_contents_observer_proxy.cc b/content/browser/android/web_contents_observer_proxy.cc index 229d6184..1d5ed90 100644 --- a/content/browser/android/web_contents_observer_proxy.cc +++ b/content/browser/android/web_contents_observer_proxy.cc
@@ -126,6 +126,11 @@ jstring_error_description, jstring_url); } +void WebContentsObserverProxy::DidChangeVisibleSecurityState() { + Java_WebContentsObserverProxy_didChangeVisibleSecurityState( + AttachCurrentThread(), java_observer_); +} + void WebContentsObserverProxy::DocumentAvailableInMainFrame() { JNIEnv* env = AttachCurrentThread(); Java_WebContentsObserverProxy_documentAvailableInMainFrame(env,
diff --git a/content/browser/android/web_contents_observer_proxy.h b/content/browser/android/web_contents_observer_proxy.h index dd72d644..ad9acb7 100644 --- a/content/browser/android/web_contents_observer_proxy.h +++ b/content/browser/android/web_contents_observer_proxy.h
@@ -40,6 +40,7 @@ const GURL& validated_url, int error_code, const base::string16& error_description) override; + void DidChangeVisibleSecurityState() override; void DocumentAvailableInMainFrame() override; void DidFirstVisuallyNonEmptyPaint() override; void OnVisibilityChanged(content::Visibility visibility) override;
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index cd93395c..cc423e5 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -3190,7 +3190,13 @@ params.started_from_context_menu, has_user_gesture, InitiatorCSPInfo(), std::vector<int>(), params.href_translate, false /* is_history_navigation_in_new_child_frame */, - params.input_start); + params.input_start, + // TODO(chenleihu): The value of frame policy should be set to a + // valid value here. Currently when we navigate a remote frame, the + // frame_policy value in common_params is not used to initialize + // container policy in document.cc. + // https://crbug.com/972089 + base::nullopt /* frame policy */); mojom::CommitNavigationParamsPtr commit_params = mojom::CommitNavigationParams::New( @@ -3327,7 +3333,8 @@ *frame_entry, request_body, dest_url, blink::mojom::Referrer::New(dest_referrer.url, dest_referrer.policy), navigation_type, previews_state, navigation_start, - base::TimeTicks() /* input_start */); + base::TimeTicks() /* input_start */, + frame_tree_node->pending_frame_policy()); common_params->is_history_navigation_in_new_child_frame = is_history_navigation_in_new_child_frame;
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index e7d7414..fb11d43 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -702,7 +702,8 @@ mojom::NavigationType navigation_type, PreviewsState previews_state, base::TimeTicks navigation_start, - base::TimeTicks input_start) { + base::TimeTicks input_start, + const blink::FramePolicy& frame_policy) { NavigationDownloadPolicy download_policy; if (IsViewSourceMode()) download_policy.SetDisallowed(NavigationDownloadType::kViewSource); @@ -715,7 +716,8 @@ post_body ? post_body : post_data_, base::Optional<SourceLocation>(), has_started_from_context_menu(), has_user_gesture(), InitiatorCSPInfo(), std::vector<int>(), std::string(), - false /* is_history_navigation_in_new_child_frame */, input_start); + false /* is_history_navigation_in_new_child_frame */, input_start, + frame_policy); } mojom::CommitNavigationParamsPtr
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h index 97097c29..4921a37d 100644 --- a/content/browser/frame_host/navigation_entry_impl.h +++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -184,7 +184,8 @@ mojom::NavigationType navigation_type, PreviewsState previews_state, base::TimeTicks navigation_start, - base::TimeTicks input_start); + base::TimeTicks input_start, + const blink::FramePolicy& frame_policy); mojom::CommitNavigationParamsPtr ConstructCommitNavigationParams( const FrameNavigationEntry& frame_entry, const GURL& original_url,
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 7da0bce4..7111efaa 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -821,7 +821,7 @@ std::vector<int>() /* initiator_origin_trial_features */, std::string() /* href_translate */, false /* is_history_navigation_in_new_child_frame */, - base::TimeTicks::Now()); + base::TimeTicks::Now(), base::nullopt /* frame policy */); mojom::CommitNavigationParamsPtr commit_params = mojom::CommitNavigationParams::New( params.origin, params.is_overriding_user_agent, params.redirects,
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 1fd6d7e..d490e6a 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -4826,7 +4826,8 @@ base::TimeTicks::Now(), "GET", nullptr, base::Optional<SourceLocation>(), false /* started_from_context_menu */, false /* has_user_gesture */, InitiatorCSPInfo(), std::vector<int>(), std::string(), - false /* is_history_navigation_in_new_child_frame */, base::TimeTicks()); + false /* is_history_navigation_in_new_child_frame */, base::TimeTicks(), + base::nullopt /* frame_policy */); CommitNavigation(nullptr /* navigation_request */, std::move(common_params), CreateCommitNavigationParams(), nullptr /* response_head */, mojo::ScopedDataPipeConsumerHandle(),
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc index 7e46c7e..c082f24 100644 --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -397,7 +397,8 @@ *frame_entry, request_body, frame_entry->url(), blink::mojom::Referrer::New(referrer.url, referrer.policy), navigate_type, PREVIEWS_UNSPECIFIED, base::TimeTicks::Now(), - base::TimeTicks::Now()); + base::TimeTicks::Now(), + frame_tree_node->current_replication_state().frame_policy); mojom::CommitNavigationParamsPtr commit_params = entry->ConstructCommitNavigationParams( *frame_entry, common_params->url, frame_entry->committed_origin(), @@ -2746,7 +2747,8 @@ *frame_entry, nullptr, frame_entry->url(), blink::mojom::Referrer::New(referrer.url, referrer.policy), mojom::NavigationType::DIFFERENT_DOCUMENT, PREVIEWS_UNSPECIFIED, - base::TimeTicks::Now(), base::TimeTicks::Now()); + base::TimeTicks::Now(), base::TimeTicks::Now(), + frame_tree_node->current_replication_state().frame_policy); mojom::CommitNavigationParamsPtr commit_params = entry.ConstructCommitNavigationParams( *frame_entry, common_params->url, frame_entry->committed_origin(),
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc index 5b72934..0b32f351 100644 --- a/content/browser/indexed_db/database_impl.cc +++ b/content/browser/indexed_db/database_impl.cc
@@ -20,7 +20,7 @@ #include "content/browser/indexed_db/indexed_db_factory_impl.h" #include "content/browser/indexed_db/indexed_db_transaction.h" #include "content/browser/indexed_db/transaction_impl.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" using blink::IndexedDBIndexKeys; using blink::IndexedDBKey; @@ -186,7 +186,7 @@ blink::mojom::IDBDatabase::GetCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!connection_->IsConnected()) { - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, "Not connected."); std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); @@ -196,7 +196,7 @@ IndexedDBTransaction* transaction = connection_->GetTransaction(transaction_id); if (!transaction) { - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, "Unknown transaction."); std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); @@ -225,7 +225,7 @@ blink::mojom::IDBDatabase::GetAllCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!connection_->IsConnected()) { - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, "Not connected."); std::move(callback).Run( blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( @@ -236,7 +236,7 @@ IndexedDBTransaction* transaction = connection_->GetTransaction(transaction_id); if (!transaction) { - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, "Unknown transaction."); std::move(callback).Run( blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( @@ -245,7 +245,7 @@ } if (!connection_->database()->IsObjectStoreIdInMetadata(object_store_id)) { - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, "Bad request"); std::move(callback).Run( blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( @@ -330,7 +330,7 @@ blink::mojom::IDBDatabase::OpenCursorCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!connection_->IsConnected()) { - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, "Not connected."); std::move(callback).Run( blink::mojom::IDBDatabaseOpenCursorResult::NewErrorResult( @@ -341,7 +341,7 @@ IndexedDBTransaction* transaction = connection_->GetTransaction(transaction_id); if (!transaction) { - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, "Unknown transaction."); std::move(callback).Run( blink::mojom::IDBDatabaseOpenCursorResult::NewErrorResult( @@ -573,7 +573,7 @@ connection_->AbortTransactionAndTearDownOnError( transaction, - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionAbortError, + IndexedDBDatabaseError(blink::mojom::IDBException::kAbortError, "Transaction aborted by user.")); }
diff --git a/content/browser/indexed_db/indexed_db_callback_helpers.h b/content/browser/indexed_db/indexed_db_callback_helpers.h index 607d4b53..b63fb725 100644 --- a/content/browser/indexed_db/indexed_db_callback_helpers.h +++ b/content/browser/indexed_db/indexed_db_callback_helpers.h
@@ -11,7 +11,7 @@ #include "base/logging.h" #include "base/memory/weak_ptr.h" #include "content/browser/indexed_db/indexed_db_transaction.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" #include "third_party/leveldatabase/env_chromium.h" // Since functions in this file use templates, they must be in a header file @@ -34,9 +34,8 @@ R AbortCallback(base::WeakPtr<IndexedDBTransaction> transaction) { if (transaction) transaction->IncrementNumErrorsSent(); - IndexedDBDatabaseError error( - blink::kWebIDBDatabaseExceptionIgnorableAbortError, - "Backend aborted error"); + IndexedDBDatabaseError error(blink::mojom::IDBException::kIgnorableAbortError, + "Backend aborted error"); return R::Struct::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message())); }
diff --git a/content/browser/indexed_db/indexed_db_connection.cc b/content/browser/indexed_db/indexed_db_connection.cc index d970dd7..a58c70b6 100644 --- a/content/browser/indexed_db/indexed_db_connection.cc +++ b/content/browser/indexed_db/indexed_db_connection.cc
@@ -16,7 +16,7 @@ #include "content/browser/indexed_db/indexed_db_origin_state.h" #include "content/browser/indexed_db/indexed_db_tracing.h" #include "content/browser/indexed_db/indexed_db_transaction.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" namespace content { @@ -74,7 +74,7 @@ callbacks_ = nullptr; // Finish up any transaction, in case there were any running. - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, "Connection is closing."); leveldb::Status status; switch (error_handling) {
diff --git a/content/browser/indexed_db/indexed_db_connection.h b/content/browser/indexed_db/indexed_db_connection.h index 4c0b381b..2d9d787 100644 --- a/content/browser/indexed_db/indexed_db_connection.h +++ b/content/browser/indexed_db/indexed_db_connection.h
@@ -16,7 +16,7 @@ #include "content/browser/indexed_db/indexed_db_database.h" #include "content/browser/indexed_db/indexed_db_execution_context_connection_tracker.h" #include "content/browser/indexed_db/indexed_db_origin_state_handle.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" namespace content { class IndexedDBDatabaseCallbacks;
diff --git a/content/browser/indexed_db/indexed_db_connection_coordinator.cc b/content/browser/indexed_db/indexed_db_connection_coordinator.cc index 8cdd6eb..a056b4f 100644 --- a/content/browser/indexed_db/indexed_db_connection_coordinator.cc +++ b/content/browser/indexed_db/indexed_db_connection_coordinator.cc
@@ -25,6 +25,7 @@ #include "content/browser/indexed_db/leveldb/transactional_leveldb_factory.h" #include "content/browser/indexed_db/leveldb/transactional_leveldb_transaction.h" #include "third_party/blink/public/common/indexeddb/indexeddb_metadata.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" using base::ASCIIToUTF16; using base::NumberToString16; @@ -152,7 +153,7 @@ NumberToString16(pending_->version); } pending_->callbacks->OnError(IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionUnknownError, message)); + blink::mojom::IDBException::kUnknownError, message)); state_ = RequestState::kError; return; } @@ -199,7 +200,7 @@ // Requested version is lower than current version - fail the request. DCHECK(!is_new_database); pending_->callbacks->OnError(IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionVersionError, + blink::mojom::IDBException::kVersionError, ASCIIToUTF16("The requested version (") + NumberToString16(pending_->version) + ASCIIToUTF16(") is less than the existing version (") + @@ -248,7 +249,7 @@ connection_ptr_for_close_comparision_ = nullptr; if (!pending_->callbacks->is_complete()) { pending_->callbacks->OnError( - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionAbortError, + IndexedDBDatabaseError(blink::mojom::IDBException::kAbortError, "The connection was closed.")); } state_ = RequestState::kDone; @@ -332,7 +333,7 @@ } else { DCHECK_NE(pending_->version, db_->metadata_.version); pending_->callbacks->OnError( - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionAbortError, + IndexedDBDatabaseError(blink::mojom::IDBException::kAbortError, "Version change transaction was aborted in " "upgradeneeded event handler.")); } @@ -344,7 +345,7 @@ DCHECK(pending_); if (!pending_->callbacks->is_complete()) { pending_->callbacks->OnError( - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionAbortError, + IndexedDBDatabaseError(blink::mojom::IDBException::kAbortError, "The connection was closed.")); } if (state_ != RequestState::kError) @@ -464,7 +465,7 @@ if (!saved_leveldb_status_.ok()) { // TODO(jsbell): Consider including sanitized leveldb status message. - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, "Internal error deleting database."); callbacks_->OnError(error); state_ = RequestState::kError;
diff --git a/content/browser/indexed_db/indexed_db_cursor.cc b/content/browser/indexed_db/indexed_db_cursor.cc index ebd9add4..5f8989d 100644 --- a/content/browser/indexed_db/indexed_db_cursor.cc +++ b/content/browser/indexed_db/indexed_db_cursor.cc
@@ -20,7 +20,7 @@ #include "content/browser/indexed_db/indexed_db_value.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" using blink::IndexedDBKey; @@ -33,12 +33,12 @@ // back end; in that case the tx will already have sent an abort to the request // so this would be ignored. IndexedDBDatabaseError CreateCursorClosedError() { - return IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError, + return IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError, "The cursor has been closed."); } IndexedDBDatabaseError CreateError( - uint16_t code, + blink::mojom::IDBException code, const char* message, base::WeakPtr<IndexedDBTransaction> transaction) { if (transaction) @@ -113,7 +113,7 @@ // CreateError() needs to be called before calling Close() so // |transaction_| is alive. - auto error = CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + auto error = CreateError(blink::mojom::IDBException::kUnknownError, "Error advancing cursor", transaction_); Close(); std::move(callback).Run(blink::mojom::IDBCursorResult::NewErrorResult( @@ -200,7 +200,7 @@ // |transaction_| must be valid for CreateError(), so we can't call // Close() until after calling CreateError(). IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Error continuing cursor.", transaction_); Close(); std::move(callback).Run(blink::mojom::IDBCursorResult::NewErrorResult( @@ -294,7 +294,7 @@ // |transaction_| must be valid for CreateError(), so we can't call // Close() until after calling CreateError(). IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Error continuing cursor.", transaction_); Close(); std::move(callback).Run(blink::mojom::IDBCursorResult::NewErrorResult(
diff --git a/content/browser/indexed_db/indexed_db_cursor.h b/content/browser/indexed_db/indexed_db_cursor.h index 79b75f4..f1915aca 100644 --- a/content/browser/indexed_db/indexed_db_cursor.h +++ b/content/browser/indexed_db/indexed_db_cursor.h
@@ -17,7 +17,7 @@ #include "content/browser/indexed_db/indexed_db_database.h" #include "content/browser/indexed_db/indexed_db_transaction.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" namespace content {
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 11f68e0..32e132f 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -52,12 +52,10 @@ #include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key_range.h" #include "third_party/blink/public/common/indexeddb/indexeddb_metadata.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "third_party/leveldatabase/env_chromium.h" #include "url/origin.h" -using base::ASCIIToUTF16; -using base::NumberToString16; using blink::IndexedDBDatabaseMetadata; using blink::IndexedDBIndexKeys; using blink::IndexedDBIndexMetadata; @@ -70,14 +68,14 @@ namespace content { namespace { -IndexedDBDatabaseError CreateError(uint16_t code, +IndexedDBDatabaseError CreateError(blink::mojom::IDBException code, const char* message, IndexedDBTransaction* transaction) { transaction->IncrementNumErrorsSent(); return IndexedDBDatabaseError(code, message); } -IndexedDBDatabaseError CreateError(uint16_t code, +IndexedDBDatabaseError CreateError(blink::mojom::IDBException code, const base::string16& message, IndexedDBTransaction* transaction) { transaction->IncrementNumErrorsSent(); @@ -771,9 +769,8 @@ IDB_TRACE1("IndexedDBDatabase::GetOperation", "txn.id", transaction->id()); if (!IsObjectStoreIdAndMaybeIndexIdInMetadata(object_store_id, index_id)) { - IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, "Bad request", - transaction); + IndexedDBDatabaseError error = CreateError( + blink::mojom::IDBException::kUnknownError, "Bad request", transaction); std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); return leveldb::Status::InvalidArgument( @@ -790,8 +787,8 @@ Status s = Status::OK(); if (!dispatcher_host) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, - "Unknown error", transaction); + CreateError(blink::mojom::IDBException::kUnknownError, "Unknown error", + transaction); std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); return s; @@ -826,7 +823,7 @@ if (!s.ok()) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Corruption detected, unable to continue", transaction); std::move(callback).Run( blink::mojom::IDBDatabaseGetResult::NewErrorResult( @@ -851,7 +848,7 @@ object_store_id, *key, &value); if (!s.ok()) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Unknown error", transaction); std::move(callback).Run( blink::mojom::IDBDatabaseGetResult::NewErrorResult( @@ -887,7 +884,7 @@ if (!IndexedDBCallbacks::CreateAllBlobs( dispatcher_host->blob_storage_context(), std::move(value_blob))) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Unknown error", transaction); std::move(callback).Run( blink::mojom::IDBDatabaseGetResult::NewErrorResult( @@ -907,8 +904,8 @@ *key, &primary_key); if (!s.ok()) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, - "Unknown error", transaction); + CreateError(blink::mojom::IDBException::kUnknownError, "Unknown error", + transaction); std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); return s; @@ -931,8 +928,8 @@ object_store_id, *primary_key, &value); if (!s.ok()) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, - "Unknown error", transaction); + CreateError(blink::mojom::IDBException::kUnknownError, "Unknown error", + transaction); std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); return s; @@ -958,8 +955,8 @@ if (!IndexedDBCallbacks::CreateAllBlobs( dispatcher_host->blob_storage_context(), std::move(value_blob))) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, - "Unknown error", transaction); + CreateError(blink::mojom::IDBException::kUnknownError, "Unknown error", + transaction); std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); return s; @@ -987,9 +984,8 @@ IDB_TRACE1("IndexedDBDatabase::GetAllOperation", "txn.id", transaction->id()); if (!IsObjectStoreIdInMetadata(object_store_id)) { - IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, "Bad request", - transaction); + IndexedDBDatabaseError error = CreateError( + blink::mojom::IDBException::kUnknownError, "Bad request", transaction); std::move(callback).Run( blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); @@ -1006,8 +1002,8 @@ Status s = Status::OK(); if (!dispatcher_host) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, - "Unknown error", transaction); + CreateError(blink::mojom::IDBException::kUnknownError, "Unknown error", + transaction); std::move(callback).Run( blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); @@ -1047,7 +1043,7 @@ if (!s.ok()) { DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Corruption detected, unable to continue", transaction); std::move(callback).Run( blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( @@ -1082,7 +1078,7 @@ } if (!s.ok()) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Seek failure, unable to continue", transaction); std::move(callback).Run( blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( @@ -1113,7 +1109,7 @@ response_size += return_value.SizeEstimate(); if (response_size > GetUsableMessageSizeInBytes()) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Maximum IPC message size exceeded.", transaction); std::move(callback).Run( blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( @@ -1169,9 +1165,8 @@ Status s = Status::OK(); if (!IsObjectStoreIdInMetadata(params->object_store_id)) { - IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, "Bad request", - transaction); + IndexedDBDatabaseError error = CreateError( + blink::mojom::IDBException::kUnknownError, "Bad request", transaction); std::move(params->callback) .Run(blink::mojom::IDBTransactionPutResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); @@ -1192,7 +1187,7 @@ key_was_generated = true; if (!auto_inc_key->IsValid()) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionConstraintError, + CreateError(blink::mojom::IDBException::kConstraintError, "Maximum key generator value reached.", transaction); std::move(params->callback) .Run(blink::mojom::IDBTransactionPutResult::NewErrorResult( @@ -1216,7 +1211,7 @@ return found_status; if (found) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionConstraintError, + CreateError(blink::mojom::IDBException::kConstraintError, "Key already exists in the object store.", transaction); std::move(params->callback) .Run(blink::mojom::IDBTransactionPutResult::NewErrorResult( @@ -1233,7 +1228,7 @@ params->index_keys, &index_writers, &error_message, &obeys_constraints); if (!backing_store_success) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Internal error: backing store error updating index keys.", transaction); std::move(params->callback) @@ -1243,8 +1238,8 @@ } if (!obeys_constraints) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionConstraintError, - error_message, transaction); + CreateError(blink::mojom::IDBException::kConstraintError, error_message, + transaction); std::move(params->callback) .Run(blink::mojom::IDBTransactionPutResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); @@ -1316,7 +1311,7 @@ return s; if (!found) { return transaction->Abort(IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionUnknownError, + blink::mojom::IDBException::kUnknownError, "Internal error setting index keys for object store.")); } @@ -1332,12 +1327,12 @@ false, index_keys, &index_writers, &error_message, &obeys_constraints); if (!backing_store_success) { return transaction->Abort(IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionUnknownError, + blink::mojom::IDBException::kUnknownError, "Internal error: backing store error updating index keys.")); } if (!obeys_constraints) { return transaction->Abort(IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionConstraintError, error_message)); + blink::mojom::IDBException::kConstraintError, error_message)); } for (const auto& writer : index_writers) { @@ -1371,7 +1366,7 @@ Status s; if (!dispatcher_host) { IndexedDBDatabaseError error = - CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + CreateError(blink::mojom::IDBException::kUnknownError, "Dispatcher not connected.", transaction); std::move(params->callback) .Run(blink::mojom::IDBDatabaseOpenCursorResult::NewErrorResult( @@ -1532,7 +1527,7 @@ scoped_refptr<IndexedDBCallbacks> callbacks, IndexedDBTransaction* transaction) { if (!IsObjectStoreIdInMetadata(object_store_id)) { - callbacks->OnError(CreateError(blink::kWebIDBDatabaseExceptionDataError, + callbacks->OnError(CreateError(blink::mojom::IDBException::kDataError, "Object store id not valid.", transaction)); return leveldb::Status::InvalidArgument("Invalid object_store_id."); } @@ -1543,7 +1538,7 @@ ¤t_number); if (!s.ok()) { callbacks->OnError(CreateError( - blink::kWebIDBDatabaseExceptionDataError, + blink::mojom::IDBException::kDataError, "Failed to get the current number of key generator.", transaction)); return s; }
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h index a4718bbb..0988ec9 100644 --- a/content/browser/indexed_db/indexed_db_database.h +++ b/content/browser/indexed_db/indexed_db_database.h
@@ -38,7 +38,7 @@ #include "content/common/content_export.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" namespace blink { class IndexedDBKeyPath;
diff --git a/content/browser/indexed_db/indexed_db_database_error.cc b/content/browser/indexed_db/indexed_db_database_error.cc index af0702e..649d834b 100644 --- a/content/browser/indexed_db/indexed_db_database_error.cc +++ b/content/browser/indexed_db/indexed_db_database_error.cc
@@ -4,17 +4,20 @@ #include "content/browser/indexed_db/indexed_db_database_error.h" -namespace content { +#include "base/strings/utf_string_conversions.h" -IndexedDBDatabaseError::IndexedDBDatabaseError(int32_t code) : code_(code) {} +namespace content { IndexedDBDatabaseError::IndexedDBDatabaseError() = default; -IndexedDBDatabaseError::IndexedDBDatabaseError(int32_t code, +IndexedDBDatabaseError::IndexedDBDatabaseError(blink::mojom::IDBException code) + : code_(code) {} + +IndexedDBDatabaseError::IndexedDBDatabaseError(blink::mojom::IDBException code, const char* message) : code_(code), message_(base::ASCIIToUTF16(message)) {} -IndexedDBDatabaseError::IndexedDBDatabaseError(int32_t code, +IndexedDBDatabaseError::IndexedDBDatabaseError(blink::mojom::IDBException code, const base::string16& message) : code_(code), message_(message) {}
diff --git a/content/browser/indexed_db/indexed_db_database_error.h b/content/browser/indexed_db/indexed_db_database_error.h index 035209b..f07f397 100644 --- a/content/browser/indexed_db/indexed_db_database_error.h +++ b/content/browser/indexed_db/indexed_db_database_error.h
@@ -8,28 +8,27 @@ #include <stdint.h> #include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" #include "content/common/content_export.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" namespace content { class CONTENT_EXPORT IndexedDBDatabaseError { - // TODO(dmurph): Move the WebIDBDatabaseException enum into mojo, and make - // the |code| type the mojo enum type. public: IndexedDBDatabaseError(); - explicit IndexedDBDatabaseError(int32_t code); - IndexedDBDatabaseError(int32_t code, const char* message); - IndexedDBDatabaseError(int32_t code, const base::string16& message); + explicit IndexedDBDatabaseError(blink::mojom::IDBException code); + IndexedDBDatabaseError(blink::mojom::IDBException code, const char* message); + IndexedDBDatabaseError(blink::mojom::IDBException code, + const base::string16& message); ~IndexedDBDatabaseError(); IndexedDBDatabaseError& operator=(const IndexedDBDatabaseError& rhs); - int32_t code() const { return code_; } + blink::mojom::IDBException code() const { return code_; } const base::string16& message() const { return message_; } private: - int32_t code_ = 0; + blink::mojom::IDBException code_ = blink::mojom::IDBException::kNoError; base::string16 message_; };
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc index c8b8aa0..c255a684 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc +++ b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
@@ -11,7 +11,7 @@ #include "base/memory/ref_counted.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" -#include "base/strings/utf_offset_string_conversions.h" +#include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" #include "base/test/mock_callback.h" @@ -41,7 +41,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" #include "url/origin.h" using blink::IndexedDBDatabaseMetadata; @@ -496,18 +495,18 @@ EXPECT_CALL( put_callback, - Run(IsCallbackError(blink::kWebIDBDatabaseExceptionUnknownError))) + Run(IsCallbackError(blink::mojom::IDBException::kUnknownError))) .Times(1) .WillOnce(RunClosure(quit_closure2)); - EXPECT_CALL(*connection->connection_callbacks, - Abort(kTransactionId, - blink::kWebIDBDatabaseExceptionUnknownError, _)) + EXPECT_CALL( + *connection->connection_callbacks, + Abort(kTransactionId, blink::mojom::IDBException::kUnknownError, _)) .Times(1) .WillOnce(RunClosure(quit_closure2)); EXPECT_CALL(*connection->open_callbacks, - Error(blink::kWebIDBDatabaseExceptionAbortError, _)) + Error(blink::mojom::IDBException::kAbortError, _)) .Times(1) .WillOnce(RunClosure(std::move(quit_closure2))); @@ -667,13 +666,13 @@ FROM_HERE, base::BindLambdaForTesting([&]() { ::testing::InSequence dummy; - EXPECT_CALL(*connection->connection_callbacks, - Abort(kTransactionId, - blink::kWebIDBDatabaseExceptionUnknownError, _)) + EXPECT_CALL( + *connection->connection_callbacks, + Abort(kTransactionId, blink::mojom::IDBException::kUnknownError, _)) .Times(1) .WillOnce(RunClosure(quit_closure2)); EXPECT_CALL(*connection->open_callbacks, - Error(blink::kWebIDBDatabaseExceptionAbortError, _)) + Error(blink::mojom::IDBException::kAbortError, _)) .Times(1) .WillOnce(RunClosure(quit_closure2)); EXPECT_CALL(*connection->connection_callbacks, ForcedClose()) @@ -743,13 +742,13 @@ FROM_HERE, base::BindLambdaForTesting([&]() { ::testing::InSequence dummy; - EXPECT_CALL(*connection->connection_callbacks, - Abort(kTransactionId, - blink::kWebIDBDatabaseExceptionUnknownError, _)) + EXPECT_CALL( + *connection->connection_callbacks, + Abort(kTransactionId, blink::mojom::IDBException::kUnknownError, _)) .Times(1) .WillOnce(RunClosure(quit_closure2)); EXPECT_CALL(*connection->open_callbacks, - Error(blink::kWebIDBDatabaseExceptionAbortError, _)) + Error(blink::mojom::IDBException::kAbortError, _)) .Times(1) .WillOnce(RunClosure(quit_closure2)); EXPECT_CALL(*connection->connection_callbacks, ForcedClose()) @@ -894,13 +893,13 @@ FROM_HERE, base::BindLambdaForTesting([&]() { ::testing::InSequence dummy; - EXPECT_CALL(*connection->connection_callbacks, - Abort(kTransactionId, - blink::kWebIDBDatabaseExceptionUnknownError, _)) + EXPECT_CALL( + *connection->connection_callbacks, + Abort(kTransactionId, blink::mojom::IDBException::kUnknownError, _)) .Times(1) .WillOnce(RunClosure(quit_closure2)); EXPECT_CALL(*connection->open_callbacks, - Error(blink::kWebIDBDatabaseExceptionAbortError, _)) + Error(blink::mojom::IDBException::kAbortError, _)) .Times(1) .WillOnce(RunClosure(quit_closure2)); EXPECT_CALL(*connection->connection_callbacks, ForcedClose()) @@ -971,13 +970,13 @@ FROM_HERE, base::BindLambdaForTesting([&]() { ::testing::InSequence dummy; - EXPECT_CALL(*connection->connection_callbacks, - Abort(kTransactionId, - blink::kWebIDBDatabaseExceptionUnknownError, _)) + EXPECT_CALL( + *connection->connection_callbacks, + Abort(kTransactionId, blink::mojom::IDBException::kUnknownError, _)) .Times(1) .WillOnce(RunClosure(quit_closure2)); EXPECT_CALL(*connection->open_callbacks, - Error(blink::kWebIDBDatabaseExceptionAbortError, _)) + Error(blink::mojom::IDBException::kAbortError, _)) .Times(1) .WillOnce(RunClosure(quit_closure2)); EXPECT_CALL(*connection->connection_callbacks, ForcedClose())
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc index c477d56..a3744df 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.cc +++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -46,7 +46,7 @@ #include "content/browser/indexed_db/indexed_db_tracing.h" #include "content/browser/indexed_db/leveldb/transactional_leveldb_database.h" #include "content/browser/indexed_db/leveldb/transactional_leveldb_factory.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "third_party/leveldatabase/env_chromium.h" using base::ASCIIToUTF16; @@ -85,7 +85,7 @@ IndexedDBDatabaseError CreateDefaultError() { return IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionUnknownError, + blink::mojom::IDBException::kUnknownError, ASCIIToUTF16("Internal error opening backing store" " for indexedDB.open.")); } @@ -200,7 +200,7 @@ factory->backing_store_->db(), factory->backing_store_->origin_identifier(), &names_and_versions); if (!s.ok()) { - error = IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError, + error = IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError, "Internal error opening backing store for " "indexedDB.databases()."); callbacks->OnError(error); @@ -243,7 +243,7 @@ factory->backing_store_->db(), factory->backing_store_->origin_identifier(), &names); if (!s.ok()) { - error = IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError, + error = IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError, "Internal error opening backing store for " "indexedDB.webkitGetDatabaseNames."); callbacks->OnError(error); @@ -291,7 +291,7 @@ std::make_unique<IndexedDBMetadataCoding>(), std::move(unique_identifier), factory->lock_manager()); if (!database.get()) { - error = IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError, + error = IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError, ASCIIToUTF16("Internal error creating " "database backend for " "indexedDB.open.")); @@ -357,7 +357,7 @@ factory->backing_store()->db(), factory->backing_store()->origin_identifier(), &names); if (!s.ok()) { - error = IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError, + error = IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError, "Internal error opening backing store for " "indexedDB.deleteDatabase."); callbacks->OnError(error); @@ -382,7 +382,7 @@ factory->lock_manager()); if (!database.get()) { error = IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionUnknownError, + blink::mojom::IDBException::kUnknownError, ASCIIToUTF16("Internal error creating database backend for " "indexedDB.deleteDatabase.")); callbacks->OnError(error); @@ -718,7 +718,7 @@ if (disk_full) { return {IndexedDBOriginStateHandle(), s, IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionQuotaError, + blink::mojom::IDBException::kQuotaError, ASCIIToUTF16("Encountered full disk while opening " "backing store for indexedDB.open.")), data_loss_info, /*was_cold_open=*/true}; @@ -941,11 +941,10 @@ if (status.IsCorruption()) { IndexedDBDatabaseError error = message != nullptr - ? IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionUnknownError, message) - : IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionUnknownError, - base::ASCIIToUTF16(status.ToString())); + ? IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError, + message) + : IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError, + base::ASCIIToUTF16(status.ToString())); HandleBackingStoreCorruption(origin, error); } else { HandleBackingStoreFailure(origin);
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc index 85e8234..ed93533 100644 --- a/content/browser/indexed_db/indexed_db_factory_unittest.cc +++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -41,7 +41,7 @@ #include "storage/browser/test/mock_quota_manager_proxy.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "url/gurl.h" #include "url/origin.h" @@ -695,7 +695,7 @@ error_called_(false) {} void OnError(const IndexedDBDatabaseError& error) override { error_called_ = true; - EXPECT_EQ(blink::kWebIDBDatabaseExceptionQuotaError, error.code()); + EXPECT_EQ(blink::mojom::IDBException::kQuotaError, error.code()); } bool error_called() const { return error_called_; }
diff --git a/content/browser/indexed_db/indexed_db_origin_state.cc b/content/browser/indexed_db/indexed_db_origin_state.cc index d9833ecc..a2acd97 100644 --- a/content/browser/indexed_db/indexed_db_origin_state.cc +++ b/content/browser/indexed_db/indexed_db_origin_state.cc
@@ -26,7 +26,7 @@ #include "content/browser/indexed_db/leveldb/transactional_leveldb_database.h" #include "content/browser/indexed_db/leveldb/transactional_leveldb_factory.h" #include "content/browser/indexed_db/leveldb/transactional_leveldb_transaction.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" namespace content { namespace { @@ -138,7 +138,7 @@ if (connection) { leveldb::Status status = connection->AbortAllTransactions(IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionUnknownError, + blink::mojom::IDBException::kUnknownError, "Aborting all transactions for the origin.")); if (!status.ok()) { // This call should delete this object.
diff --git a/content/browser/indexed_db/indexed_db_transaction.cc b/content/browser/indexed_db/indexed_db_transaction.cc index 9492a77..f226243 100644 --- a/content/browser/indexed_db/indexed_db_transaction.cc +++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -20,7 +20,7 @@ #include "content/browser/indexed_db/indexed_db_database.h" #include "content/browser/indexed_db/indexed_db_database_callbacks.h" #include "content/browser/indexed_db/indexed_db_tracing.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "third_party/leveldatabase/env_chromium.h" namespace content { @@ -42,21 +42,21 @@ }; // Used for UMA metrics - do not change mappings. -UmaIDBException ExceptionCodeToUmaEnum(uint16_t code) { +UmaIDBException ExceptionCodeToUmaEnum(blink::mojom::IDBException code) { switch (code) { - case blink::kWebIDBDatabaseExceptionUnknownError: + case blink::mojom::IDBException::kUnknownError: return UmaIDBExceptionUnknownError; - case blink::kWebIDBDatabaseExceptionConstraintError: + case blink::mojom::IDBException::kConstraintError: return UmaIDBExceptionConstraintError; - case blink::kWebIDBDatabaseExceptionDataError: + case blink::mojom::IDBException::kDataError: return UmaIDBExceptionDataError; - case blink::kWebIDBDatabaseExceptionVersionError: + case blink::mojom::IDBException::kVersionError: return UmaIDBExceptionVersionError; - case blink::kWebIDBDatabaseExceptionAbortError: + case blink::mojom::IDBException::kAbortError: return UmaIDBExceptionAbortError; - case blink::kWebIDBDatabaseExceptionQuotaError: + case blink::mojom::IDBException::kQuotaError: return UmaIDBExceptionQuotaError; - case blink::kWebIDBDatabaseExceptionTimeoutError: + case blink::mojom::IDBException::kTimeoutError: return UmaIDBExceptionTimeoutError; default: NOTREACHED(); @@ -268,7 +268,7 @@ switch (result) { case IndexedDBBackingStore::BlobWriteResult::kFailure: { leveldb::Status status = Abort(IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionDataError, "Failed to write blobs.")); + blink::mojom::IDBException::kDataError, "Failed to write blobs.")); if (!status.ok()) tear_down_callback_.Run(status); // The result is ignored. @@ -318,7 +318,7 @@ if (num_errors_sent_ != num_errors_handled_) { is_commit_pending_ = false; return Abort( - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError)); + IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError)); } state_ = COMMITTING; @@ -428,12 +428,11 @@ IndexedDBDatabaseError error; if (leveldb_env::IndicatesDiskFull(s)) { error = IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionQuotaError, + blink::mojom::IDBException::kQuotaError, "Encountered disk full while committing transaction."); } else { - error = - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError, - "Internal error committing transaction."); + error = IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError, + "Internal error committing transaction."); } callbacks_->OnAbort(*this, error); if (database_) @@ -525,7 +524,7 @@ void IndexedDBTransaction::Timeout() { leveldb::Status result = Abort(IndexedDBDatabaseError( - blink::kWebIDBDatabaseExceptionTimeoutError, + blink::mojom::IDBException::kTimeoutError, base::ASCIIToUTF16("Transaction timed out due to inactivity."))); if (!result.ok()) tear_down_callback_.Run(result);
diff --git a/content/browser/indexed_db/indexed_db_transaction.h b/content/browser/indexed_db/indexed_db_transaction.h index be6369a..572eb76 100644 --- a/content/browser/indexed_db/indexed_db_transaction.h +++ b/content/browser/indexed_db/indexed_db_transaction.h
@@ -28,7 +28,7 @@ #include "content/browser/indexed_db/indexed_db_observer.h" #include "content/browser/indexed_db/indexed_db_task_helper.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" namespace content {
diff --git a/content/browser/indexed_db/indexed_db_transaction_unittest.cc b/content/browser/indexed_db/indexed_db_transaction_unittest.cc index 20e8cd6..502e09b 100644 --- a/content/browser/indexed_db/indexed_db_transaction_unittest.cc +++ b/content/browser/indexed_db/indexed_db_transaction_unittest.cc
@@ -29,7 +29,7 @@ #include "content/browser/indexed_db/mock_indexed_db_factory.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" namespace content { namespace indexed_db_transaction_unittest { @@ -224,7 +224,7 @@ // Clean up to avoid leaks. transaction->Abort(IndexedDBDatabaseError( - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionAbortError, + IndexedDBDatabaseError(blink::mojom::IDBException::kAbortError, "Transaction aborted by user."))); EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state()); EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); @@ -438,9 +438,8 @@ RunPostedTasks(); - transaction->Abort( - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionAbortError, - "Transaction aborted by user.")); + transaction->Abort(IndexedDBDatabaseError( + blink::mojom::IDBException::kAbortError, "Transaction aborted by user.")); EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state()); EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); EXPECT_EQ(0, transaction->pending_preemptive_events_); @@ -548,7 +547,7 @@ // Abort the transaction, which should cancel the // |RegisterAndScheduleTransaction()| pending lock request. transaction->Abort( - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError)); + IndexedDBDatabaseError(blink::mojom::IDBException::kUnknownError)); EXPECT_EQ(transaction->state(), IndexedDBTransaction::FINISHED); // Clear |temp_lock_receiver| so we can test later that all locks have
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index af0da64..083e700f 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -10,6 +10,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "base/run_loop.h" +#include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/default_clock.h"
diff --git a/content/browser/indexed_db/mock_mojo_indexed_db_callbacks.h b/content/browser/indexed_db/mock_mojo_indexed_db_callbacks.h index 620bd00..3fd3bb6 100644 --- a/content/browser/indexed_db/mock_mojo_indexed_db_callbacks.h +++ b/content/browser/indexed_db/mock_mojo_indexed_db_callbacks.h
@@ -29,7 +29,9 @@ mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks> CreateInterfacePtrAndBind(); - MOCK_METHOD2(Error, void(int32_t code, const base::string16& message)); + MOCK_METHOD2(Error, + void(blink::mojom::IDBException code, + const base::string16& message)); MOCK_METHOD1(SuccessNamesAndVersionsList, void(std::vector<blink::mojom::IDBNameAndVersionPtr> list));
diff --git a/content/browser/indexed_db/mock_mojo_indexed_db_database_callbacks.h b/content/browser/indexed_db/mock_mojo_indexed_db_database_callbacks.h index bedff45..3947d49 100644 --- a/content/browser/indexed_db/mock_mojo_indexed_db_database_callbacks.h +++ b/content/browser/indexed_db/mock_mojo_indexed_db_database_callbacks.h
@@ -28,7 +28,7 @@ MOCK_METHOD2(VersionChange, void(int64_t old_version, int64_t new_version)); MOCK_METHOD3(Abort, void(int64_t transaction_id, - int32_t code, + blink::mojom::IDBException code, const base::string16& message)); MOCK_METHOD1(Complete, void(int64_t transaction_id));
diff --git a/content/browser/indexed_db/transaction_impl.cc b/content/browser/indexed_db/transaction_impl.cc index 0ff55b1c..d85f0b5 100644 --- a/content/browser/indexed_db/transaction_impl.cc +++ b/content/browser/indexed_db/transaction_impl.cc
@@ -21,7 +21,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "storage/browser/blob/blob_storage_context.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" namespace content { namespace { @@ -29,7 +29,7 @@ const char kInvalidBlobFilePath[] = "Blob file path is invalid"; IndexedDBDatabaseError CreateBackendAbortError() { - return IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionAbortError, + return IndexedDBDatabaseError(blink::mojom::IDBException::kAbortError, "Backend aborted error"); } @@ -181,7 +181,7 @@ return; } case IOHelper::LoadResultCode::kAbort: { - IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, kInvalidBlobUuid); std::move(callback).Run( blink::mojom::IDBTransactionPutResult::NewErrorResult( @@ -207,9 +207,8 @@ } case IOHelper::LoadResultCode::kSuccess: { if (!transaction_) { - IndexedDBDatabaseError error( - blink::kWebIDBDatabaseExceptionUnknownError, - "Unknown transaction."); + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, + "Unknown transaction."); std::move(callback).Run( blink::mojom::IDBTransactionPutResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); @@ -218,8 +217,8 @@ IndexedDBConnection* connection = transaction_->connection(); if (!connection->IsConnected()) { - IndexedDBDatabaseError error( - blink::kWebIDBDatabaseExceptionUnknownError, "Not connected."); + IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError, + "Not connected."); std::move(callback).Run( blink::mojom::IDBTransactionPutResult::NewErrorResult( blink::mojom::IDBError::New(error.code(), error.message()))); @@ -381,7 +380,7 @@ } else { connection->AbortTransactionAndTearDownOnError( transaction_.get(), - IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionQuotaError)); + IndexedDBDatabaseError(blink::mojom::IDBException::kQuotaError)); } }
diff --git a/content/browser/resources/process/process_internals.css b/content/browser/resources/process/process_internals.css index ba09677..c5b0b09 100644 --- a/content/browser/resources/process/process_internals.css +++ b/content/browser/resources/process/process_internals.css
@@ -81,6 +81,12 @@ z-index: 1; } +@media(forced-colors) { + .content-header { + background: none; + } +} + .tree-label { user-select: text; }
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index d303c1b5..44871cb 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -1573,7 +1573,7 @@ std::vector<int>() /* initiator_origin_trial_features */, std::string() /* href_translate */, false /* is_history_navigation_in_new_child_frame */, - base::TimeTicks()); + base::TimeTicks(), base::nullopt /* frame_policy */); mojom::BeginNavigationParamsPtr begin_params = mojom::BeginNavigationParams::New( std::string() /* headers */, net::LOAD_NORMAL,
diff --git a/content/common/child_process_host_impl.cc b/content/common/child_process_host_impl.cc index 13fd51a4..26cf172 100644 --- a/content/common/child_process_host_impl.cc +++ b/content/common/child_process_host_impl.cc
@@ -31,6 +31,7 @@ #include "ipc/ipc_channel_mojo.h" #include "ipc/ipc_logging.h" #include "ipc/message_filter.h" +#include "mojo/public/cpp/bindings/lib/message_quota_checker.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/constants.mojom.h" #include "services/service_manager/public/cpp/interface_provider.h" @@ -157,7 +158,8 @@ BindInterface(IPC::mojom::ChannelBootstrap::Name_, std::move(pipe.handle1)); channel_ = IPC::ChannelMojo::Create( std::move(pipe.handle0), IPC::Channel::MODE_SERVER, this, - base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(), + mojo::internal::MessageQuotaChecker::MaybeCreate()); DCHECK(channel_); bool initialized = InitChannel();
diff --git a/content/common/navigation_params.mojom b/content/common/navigation_params.mojom index e2761bd..e9fcc25 100644 --- a/content/common/navigation_params.mojom +++ b/content/common/navigation_params.mojom
@@ -14,6 +14,8 @@ import "services/network/public/mojom/url_response_head.mojom"; import "third_party/blink/public/mojom/fetch/fetch_api_request.mojom"; import "third_party/blink/public/mojom/referrer.mojom"; +import "third_party/blink/public/mojom/feature_policy/feature_policy.mojom"; +import "third_party/blink/public/mojom/frame/frame_policy.mojom"; import "url/mojom/origin.mojom"; import "url/mojom/url.mojom"; @@ -207,6 +209,20 @@ // not always be set; it depends on the creator of the CommonNavigationParams // setting it. mojo_base.mojom.TimeTicks input_start; + + // A snapshot value of frame policy(both sandbox flags and container policy) + // of the frame that is being navigated. The snapshot value is captured at the + // start of navigation. + // The value is set to null for top-level browser-initiated navigation. + // The value is also set to null when Ctrl-click was used to create a new tab + // and navigate, i.e. the document in new tab will inherit no frame_policy. + // For navigation created from NavigationControllerImpl:: + // CreateNavigationRequestFromEntry which corresponds to history navigation, + // the value is set to current FrameTreeNode::pending_frame_policy in + // frame_tree_node. This behavior is currently undocumented and probably need + // further discussion. Another potential approach is to record frame policy + // value in NavigationEntry and reuse the historical value. + blink.mojom.FramePolicy? frame_policy; }; // Provided by the browser -----------------------------------------------------
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java index 1ac1beba..292e217 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java
@@ -128,6 +128,14 @@ @Override @CalledByNative + public void didChangeVisibleSecurityState() { + for (mObserversIterator.rewind(); mObserversIterator.hasNext();) { + mObserversIterator.next().didChangeVisibleSecurityState(); + } + } + + @Override + @CalledByNative public void didFailLoad( boolean isMainFrame, int errorCode, String description, String failingUrl) { for (mObserversIterator.rewind(); mObserversIterator.hasNext();) {
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java index aa90d260..d86fbbde 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java
@@ -82,6 +82,11 @@ public void loadProgressChanged(float progress) {} /** + * Called when a page's visible security state has changed. + */ + public void didChangeVisibleSecurityState() {} + + /** * Called when an error occurs while loading a page and/or the page fails to load. * @param isMainFrame Whether the navigation occurred in main frame. * @param errorCode Error code for the occurring error.
diff --git a/content/public/test/content_browser_test_utils_mac.mm b/content/public/test/content_browser_test_utils_mac.mm index 57fec6a..9683d45 100644 --- a/content/public/test/content_browser_test_utils_mac.mm +++ b/content/public/test/content_browser_test_utils_mac.mm
@@ -163,7 +163,7 @@ - (void)didAddSubview:(NSView*)view { content::RenderWidgetHostViewCocoaObserver::GetSwizzler( content::RenderWidgetHostViewCocoaObserver::kDidAddSubview) - ->GetOriginalImplementation()(self, _cmd, view); + ->InvokeOriginal<void, NSView*>(self, _cmd, view); content::RenderWidgetHostViewMac* rwhv_mac = content::GetRenderWidgetHostViewMac(self); @@ -206,7 +206,8 @@ content::RenderWidgetHostViewCocoaObserver::GetSwizzler( content::RenderWidgetHostViewCocoaObserver:: kShowDefinitionForAttributedString) - ->GetOriginalImplementation()(self, _cmd, attrString, textBaselineOrigin); + ->InvokeOriginal<void, NSAttributedString*, NSPoint>( + self, _cmd, attrString, textBaselineOrigin); auto* rwhv_mac = content::GetRenderWidgetHostViewMac(self);
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index 374f186..e00990e 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -667,7 +667,8 @@ base::TimeTicks::Now(), "GET", nullptr, base::Optional<SourceLocation>(), false /* started_from_context_menu */, false /* has_user_gesture */, InitiatorCSPInfo(), std::vector<int>(), std::string(), - false /* is_history_navigation_in_new_child_frame */, base::TimeTicks()); + false /* is_history_navigation_in_new_child_frame */, base::TimeTicks(), + base::nullopt /* frame_policy */); RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); TestRenderFrame* frame = static_cast<TestRenderFrame*>(impl->GetMainRenderFrame()); @@ -813,7 +814,8 @@ base::TimeTicks::Now(), "GET", nullptr, base::Optional<SourceLocation>(), false /* started_from_context_menu */, false /* has_user_gesture */, InitiatorCSPInfo(), std::vector<int>(), std::string(), - false /* is_history_navigation_in_new_child_frame */, base::TimeTicks()); + false /* is_history_navigation_in_new_child_frame */, base::TimeTicks(), + base::nullopt /* frame policy */); auto commit_params = CreateCommitNavigationParams(); commit_params->page_state = state; commit_params->nav_entry_id = pending_offset + 1;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index a8cb25b..e76f0fc 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -597,7 +597,8 @@ info->initiator_csp.self_source.value())) : base::nullopt), initiator_origin_trial_features, info->href_translate.Latin1(), - is_history_navigation_in_new_child_frame, info->input_start); + is_history_navigation_in_new_child_frame, info->input_start, + info->frame_policy); } WebFrameLoadType NavigationTypeToLoadType(mojom::NavigationType navigation_type, @@ -1010,6 +1011,8 @@ navigation_params->appcache_host_id = commit_params.appcache_host_id.value_or(base::UnguessableToken()); + navigation_params->frame_policy = common_params.frame_policy; + if (common_params.navigation_type == mojom::NavigationType::RESTORE) { // We're doing a load of a page that was restored from the last session. // By default this prefers the cache over loading
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index f957828..62ca379 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1937,6 +1937,7 @@ ":run_all_unittests", ":test_interfaces", ":test_support", + "//base", "//base/allocator:buildflags", "//base/test:test_support", "//base/third_party/dynamic_annotations",
diff --git a/docs/accessibility/overview.md b/docs/accessibility/overview.md index d11a2f0..7ab969b 100644 --- a/docs/accessibility/overview.md +++ b/docs/accessibility/overview.md
@@ -18,7 +18,7 @@ * Screen readers for blind users that describe the screen using synthesized speech or braille * Voice control applications that let you speak to the computer, -* Switch access that lets you control the computer with a small number +* Switch Access that lets you control the computer with a small number of physical switches, * Magnifiers that magnify a portion of the screen, and often highlight the cursor and caret for easier viewing, and
diff --git a/docs/login/user_types.md b/docs/login/user_types.md index 230b414..3e5f8c99 100644 --- a/docs/login/user_types.md +++ b/docs/login/user_types.md
@@ -13,7 +13,6 @@ Regular users that were registered using their GAIA account. - ## Child users Users that logged in using @@ -52,6 +51,8 @@ * If the test user is logged in using `LoginManagerMixin`, the injected `UserContext` has to have the refresh token matching the token passed to `FakeGaiaMixin`. +* Note that `LoggedInUserMixin` is a compound helper mixin that conveniently + packages the mixins mentioned above into an easy-to-use interface. ## Guest @@ -62,7 +63,7 @@ To test guest session state, use `GuestSessionMixin` - this will set up appropriate guest session flags. -Testing guest user login is more complicated, as guest login required Chrome +Testing guest user login is more complicated, as guest login requires Chrome restart. The test will require two parts: * `PRE_BrowserTest` test that requests login * `BrowserTest` that can test guest session state @@ -70,4 +71,3 @@ To properly set up and preserve Chrome flags between sessions runs, use `LoginManagerMixin`, and set it up using `LoginManagerMixin::set_session_restore_enabled()` -
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn index e1294b4..cead5da8 100644 --- a/fuchsia/engine/BUILD.gn +++ b/fuchsia/engine/BUILD.gn
@@ -97,6 +97,7 @@ "//third_party/fuchsia-sdk/sdk:ui_gfx", "//third_party/fuchsia-sdk/sdk:web", "//third_party/widevine/cdm:headers", + "//ui/accessibility", "//ui/aura", "//ui/base", "//ui/base/ime", @@ -223,10 +224,15 @@ source_set("browsertest_core") { testonly = true sources = [ + "test/test_data.cc", + "test/test_data.h", "test/web_engine_browser_test.cc", "test/web_engine_browser_test.h", "test/web_engine_test_launcher.cc", ] + data = [ + "test/data", + ] deps = [ ":web_engine_core", "//content/public/browser", @@ -240,15 +246,13 @@ test("web_engine_browsertests") { sources = [ + "browser/accessibility_bridge_browsertest.cc", "browser/content_directory_browsertest.cc", "browser/context_impl_browsertest.cc", "browser/frame_impl_browsertest.cc", "browser/media_browsertest.cc", ] defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] - data = [ - "test/data", - ] deps = [ ":browsertest_core", ":switches", @@ -260,6 +264,7 @@ "//net:test_support", "//testing/gmock", "//testing/gtest", + "//third_party/fuchsia-sdk/sdk:accessibility_semantics", "//third_party/fuchsia-sdk/sdk:scenic_cpp", "//ui/ozone", ] @@ -267,7 +272,6 @@ test("web_engine_unittests") { sources = [ - "browser/accessibility_bridge_unittest.cc", "browser/ax_tree_converter_unittest.cc", "browser/cookie_manager_impl_unittest.cc", "browser/frame_impl_unittest.cc", @@ -288,7 +292,6 @@ "//services/network/public/mojom", "//testing/gmock", "//testing/gtest", - "//third_party/fuchsia-sdk/sdk:accessibility_semantics", "//third_party/fuchsia-sdk/sdk:scenic_cpp", "//third_party/fuchsia-sdk/sdk:web", ]
diff --git a/fuchsia/engine/browser/accessibility_bridge.cc b/fuchsia/engine/browser/accessibility_bridge.cc index b2f521c..e2e6ff3 100644 --- a/fuchsia/engine/browser/accessibility_bridge.cc +++ b/fuchsia/engine/browser/accessibility_bridge.cc
@@ -4,18 +4,116 @@ #include "fuchsia/engine/browser/accessibility_bridge.h" +#include <lib/sys/cpp/component_context.h> +#include <lib/ui/scenic/cpp/view_ref_pair.h> +#include <sys/types.h> + +#include "base/fuchsia/fuchsia_logging.h" #include "base/logging.h" +#include "fuchsia/engine/browser/ax_tree_converter.h" + +using fuchsia::accessibility::semantics::SemanticTree; + +namespace { + +constexpr uint32_t kSemanticNodeRootId = 0; + +// TODO(https://crbug.com/973095): Update this value based on average and +// maximum sizes of serialized Semantic Nodes. +constexpr size_t kMaxNodesPerUpdate = 16; + +// Template function to handle batching and sending of FIDL messages when +// updating or deleting nodes. +template <typename T> +void SendBatches(std::vector<T> pending_items, + base::RepeatingCallback<void(std::vector<T>)> callback) { + std::vector<T> nodes_to_send; + for (size_t i = 0; i < pending_items.size(); i++) { + nodes_to_send.push_back(std::move(pending_items.at(i))); + if (nodes_to_send.size() == kMaxNodesPerUpdate) { + callback.Run(std::move(nodes_to_send)); + nodes_to_send.clear(); + } + } + + if (!nodes_to_send.empty()) { + callback.Run(std::move(nodes_to_send)); + } +} + +} // namespace AccessibilityBridge::AccessibilityBridge( fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager, - fuchsia::ui::views::ViewRef view_ref) - : binding_(this) { + fuchsia::ui::views::ViewRef view_ref, + content::WebContents* web_contents) + : binding_(this), web_contents_(web_contents) { + DCHECK(web_contents_); + Observe(web_contents_); + tree_.AddObserver(this); + semantics_manager->RegisterViewForSemantics( std::move(view_ref), binding_.NewBinding(), tree_ptr_.NewRequest()); + tree_ptr_.set_error_handler([](zx_status_t status) { + ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) + << "Semantic Tree disconnected."; + }); } AccessibilityBridge::~AccessibilityBridge() = default; +void AccessibilityBridge::TryCommit() { + if (commit_inflight_ || (to_send_.empty() && to_delete_.empty())) + return; + + if (!to_send_.empty()) { + SendBatches<fuchsia::accessibility::semantics::Node>( + std::move(to_send_), + base::BindRepeating( + [](SemanticTree* tree, + std::vector<fuchsia::accessibility::semantics::Node> nodes) { + tree->UpdateSemanticNodes(std::move(nodes)); + }, + base::Unretained(tree_ptr_.get()))); + } + + if (!to_delete_.empty()) { + SendBatches<uint32_t>( + std::move(to_delete_), + base::BindRepeating( + [](SemanticTree* tree, std::vector<uint32_t> nodes) { + tree->DeleteSemanticNodes(std::move(nodes)); + }, + base::Unretained(tree_ptr_.get()))); + } + + tree_ptr_->CommitUpdates( + fit::bind_member(this, &AccessibilityBridge::OnCommitComplete)); + commit_inflight_ = true; +} + +void AccessibilityBridge::OnCommitComplete() { + commit_inflight_ = false; +} + +uint32_t AccessibilityBridge::ConvertToFuchsiaNodeId(int32_t ax_node_id) { + if (ax_node_id == root_id_) { + // On the Fuchsia side, the root node is indicated by id + // |kSemanticNodeRootId|, which is 0. + return kSemanticNodeRootId; + } else { + // AXNode ids are signed, Semantic Node ids are unsigned. + return bit_cast<uint32_t>(ax_node_id); + } +} + +void AccessibilityBridge::AccessibilityEventReceived( + const content::AXEventNotificationDetails& details) { + for (const ui::AXTreeUpdate& update : details.updates) { + tree_.Unserialize(update); + } +} + void AccessibilityBridge::OnAccessibilityActionRequested( uint32_t node_id, fuchsia::accessibility::semantics::Action action, @@ -31,5 +129,45 @@ void AccessibilityBridge::OnSemanticsModeChanged( bool updates_enabled, OnSemanticsModeChangedCallback callback) { - NOTIMPLEMENTED(); + if (updates_enabled) { + // The first call to AccessibilityEventReceived after this call will be the + // entire semantic tree. + web_contents_->EnableWebContentsOnlyAccessibilityMode(); + } else { + // The SemanticsManager will clear all state in this case, which is mirrored + // here. + to_send_.clear(); + to_delete_.clear(); + commit_inflight_ = false; + } + + // Notify the SemanticsManager that SemanticsMode has been updated. + callback(); +} + +void AccessibilityBridge::OnNodeWillBeDeleted(ui::AXTree* tree, + ui::AXNode* node) { + to_delete_.push_back(ConvertToFuchsiaNodeId(node->id())); + TryCommit(); +} + +void AccessibilityBridge::OnAtomicUpdateFinished( + ui::AXTree* tree, + bool root_changed, + const std::vector<ui::AXTreeObserver::Change>& changes) { + root_id_ = tree_.root()->id(); + for (const ui::AXTreeObserver::Change& change : changes) { + // Reparent changes aren't included here because they consist of a delete + // and create change, which are already being handled. + if (change.type == ui::AXTreeObserver::NODE_CREATED || + change.type == ui::AXTreeObserver::SUBTREE_CREATED || + change.type == ui::AXTreeObserver::NODE_CHANGED) { + ui::AXNodeData ax_data = change.node->data(); + if (change.node->id() == root_id_) { + ax_data.id = kSemanticNodeRootId; + } + to_send_.push_back(AXNodeDataToSemanticNode(ax_data)); + } + } + TryCommit(); }
diff --git a/fuchsia/engine/browser/accessibility_bridge.h b/fuchsia/engine/browser/accessibility_bridge.h index b9d6120..50adc468 100644 --- a/fuchsia/engine/browser/accessibility_bridge.h +++ b/fuchsia/engine/browser/accessibility_bridge.h
@@ -10,8 +10,19 @@ #include <fuchsia/ui/views/cpp/fidl.h> #include <lib/fidl/cpp/binding.h> +#include "base/callback.h" #include "base/macros.h" +#include "content/public/browser/ax_event_notification_details.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_observer.h" #include "fuchsia/engine/web_engine_export.h" +#include "ui/accessibility/ax_serializable_tree.h" +#include "ui/accessibility/ax_tree_id.h" +#include "ui/accessibility/ax_tree_observer.h" + +namespace content { +class WebContents; +} // namespace content // This class is the intermediate for accessibility between Chrome and Fuchsia. // It handles registration to the Fuchsia Semantics Manager, translating events @@ -21,14 +32,38 @@ // View created by FrameImpl. This class refers to the View via the // caller-supplied ViewRef. class WEB_ENGINE_EXPORT AccessibilityBridge - : public fuchsia::accessibility::semantics::SemanticListener { + : public content::WebContentsObserver, + public fuchsia::accessibility::semantics::SemanticListener, + public ui::AXTreeObserver { public: + // |web_contents| is required to exist for the duration of |this|. AccessibilityBridge( fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager, - fuchsia::ui::views::ViewRef view_ref); + fuchsia::ui::views::ViewRef view_ref, + content::WebContents* web_contents); ~AccessibilityBridge() final; + void set_semantic_tree_for_test( + fidl::InterfaceRequest<fuchsia::accessibility::semantics::SemanticTree> + tree_request); + private: + FRIEND_TEST_ALL_PREFIXES(AccessibilityBridgeTest, OnSemanticsModeChanged); + + // Handles batching of semantic nodes and committing them to the SemanticTree. + void TryCommit(); + + // Callback for SemanticTree::CommitUpdates. + void OnCommitComplete(); + + // Converts AXNode ids to Semantic Node ids, and handles special casing of the + // root. + uint32_t ConvertToFuchsiaNodeId(int32_t ax_node_id); + + // content::WebContentsObserver implementation. + void AccessibilityEventReceived( + const content::AXEventNotificationDetails& details) override; + // fuchsia::accessibility::semantics::SemanticListener implementation. void OnAccessibilityActionRequested( uint32_t node_id, @@ -39,8 +74,24 @@ void OnSemanticsModeChanged(bool updates_enabled, OnSemanticsModeChangedCallback callback) final; + // ui::AXTreeObserver implementation. + void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override; + void OnAtomicUpdateFinished( + ui::AXTree* tree, + bool root_changed, + const std::vector<ui::AXTreeObserver::Change>& changes) override; + fuchsia::accessibility::semantics::SemanticTreePtr tree_ptr_; fidl::Binding<fuchsia::accessibility::semantics::SemanticListener> binding_; + content::WebContents* web_contents_; + ui::AXSerializableTree tree_; + + std::vector<fuchsia::accessibility::semantics::Node> to_send_; + std::vector<uint32_t> to_delete_; + bool commit_inflight_ = false; + + // The root id of |tree_|. + int32_t root_id_ = 0; DISALLOW_COPY_AND_ASSIGN(AccessibilityBridge); };
diff --git a/fuchsia/engine/browser/accessibility_bridge_browsertest.cc b/fuchsia/engine/browser/accessibility_bridge_browsertest.cc new file mode 100644 index 0000000..65af13a --- /dev/null +++ b/fuchsia/engine/browser/accessibility_bridge_browsertest.cc
@@ -0,0 +1,244 @@ +// 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 <fuchsia/accessibility/semantics/cpp/fidl.h> +#include <fuchsia/accessibility/semantics/cpp/fidl_test_base.h> +#include <lib/sys/cpp/component_context.h> +#include <lib/ui/scenic/cpp/view_token_pair.h> +#include <zircon/types.h> + +#include "base/fuchsia/default_context.h" +#include "base/fuchsia/scoped_service_binding.h" +#include "base/fuchsia/service_directory_client.h" +#include "base/logging.h" +#include "base/test/bind_test_util.h" +#include "content/public/browser/web_contents_observer.h" +#include "fuchsia/base/frame_test_util.h" +#include "fuchsia/base/result_receiver.h" +#include "fuchsia/base/test_navigation_listener.h" +#include "fuchsia/engine/browser/accessibility_bridge.h" +#include "fuchsia/engine/browser/frame_impl.h" +#include "fuchsia/engine/test/test_data.h" +#include "fuchsia/engine/test/web_engine_browser_test.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gtest/include/gtest/gtest.h" + +using fuchsia::accessibility::semantics::Node; +using fuchsia::accessibility::semantics::SemanticListener; +using fuchsia::accessibility::semantics::SemanticsManager; +using fuchsia::accessibility::semantics::SemanticTree; + +namespace { + +const char kPage1Path[] = "/ax1.html"; +const char kPage2Path[] = "/batching.html"; +const char kPage1Title[] = "accessibility 1"; +const char kPage2Title[] = "lots of nodes!"; +const char kButtonName[] = "a button"; +const char kNodeName[] = "last node"; +const char kParagraphName[] = "a paragraph"; +const size_t kPage1NodeCount = 3; + +class FakeSemanticTree + : public fuchsia::accessibility::semantics::testing::SemanticTree_TestBase { + public: + FakeSemanticTree() = default; + ~FakeSemanticTree() override = default; + + // fuchsia::accessibility::semantics::SemanticTree implementation. + void UpdateSemanticNodes(std::vector<Node> nodes) final { + for (auto& node : nodes) { + nodes_.push_back(std::move(node)); + } + } + + void DeleteSemanticNodes(std::vector<uint32_t> node_ids) final { + for (auto id : node_ids) { + for (uint i = 0; i < nodes_.size(); i++) { + if (nodes_.at(i).node_id() == id) { + nodes_.erase(nodes_.begin() + i); + } + } + } + } + + void CommitUpdates(CommitUpdatesCallback callback) final { + if (on_commit_updates_) { + std::move(on_commit_updates_).Run(); + } + } + + void NotImplemented_(const std::string& name) final { + NOTIMPLEMENTED() << name; + } + + void RunUntilNodeCountAtLeast(size_t count) { + DCHECK(!on_commit_updates_); + + // Spin the RunLoop until the expected conditions are met. + while (nodes_.size() < count) { + base::RunLoop run_loop; + on_commit_updates_ = base::BindLambdaForTesting( + [this, count, quit = run_loop.QuitClosure()]() { + if (nodes_.size() >= count) { + quit.Run(); + } + }); + run_loop.Run(); + } + } + + bool HasNodeWithLabel(base::StringPiece name) { + for (auto& node : nodes_) { + if (node.has_attributes() && node.attributes().has_label() && + node.attributes().label() == name) { + return true; + } + } + return false; + } + + private: + std::vector<Node> nodes_; + base::OnceClosure on_commit_updates_; + + DISALLOW_COPY_AND_ASSIGN(FakeSemanticTree); +}; + +class FakeSemanticsManager : public fuchsia::accessibility::semantics::testing:: + SemanticsManager_TestBase { + public: + FakeSemanticsManager() : semantic_tree_binding_(&semantic_tree_) {} + ~FakeSemanticsManager() override = default; + + bool is_view_registered() const { return view_ref_.reference.is_valid(); } + bool is_listener_valid() const { return static_cast<bool>(listener_); } + FakeSemanticTree* semantic_tree() { return &semantic_tree_; } + + // Directly call the listener to simulate Fuchsia requesting a change in + void SetSemanticsMode(bool is_enabled) { + listener_->OnSemanticsModeChanged(is_enabled, []() {}); + } + + // fuchsia::accessibility::semantics::SemanticsManager implementation. + void RegisterViewForSemantics( + fuchsia::ui::views::ViewRef view_ref, + fidl::InterfaceHandle<SemanticListener> listener, + fidl::InterfaceRequest<SemanticTree> semantic_tree_request) final { + view_ref_ = std::move(view_ref); + listener_ = listener.Bind(); + semantic_tree_binding_.Bind(std::move(semantic_tree_request)); + } + + void NotImplemented_(const std::string& name) final { + NOTIMPLEMENTED() << name; + } + + private: + fuchsia::ui::views::ViewRef view_ref_; + fuchsia::accessibility::semantics::SemanticListenerPtr listener_; + FakeSemanticTree semantic_tree_; + fidl::Binding<SemanticTree> semantic_tree_binding_; + + DISALLOW_COPY_AND_ASSIGN(FakeSemanticsManager); +}; + +} // namespace + +class AccessibilityBridgeTest : public cr_fuchsia::WebEngineBrowserTest { + public: + AccessibilityBridgeTest() : semantics_manager_binding_(&semantics_manager_) { + cr_fuchsia::WebEngineBrowserTest::set_test_server_root( + base::FilePath(cr_fuchsia::kTestServerRoot)); + } + + ~AccessibilityBridgeTest() override = default; + + void SetUpOnMainThread() override { + fuchsia::accessibility::semantics::SemanticsManagerPtr + semantics_manager_ptr; + semantics_manager_binding_.Bind(semantics_manager_ptr.NewRequest()); + + frame_ptr_ = + cr_fuchsia::WebEngineBrowserTest::CreateFrame(&navigation_listener_); + frame_impl_ = context_impl()->GetFrameImplForTest(&frame_ptr_); + frame_impl_->set_semantics_manager_for_test( + std::move(semantics_manager_ptr)); + + // Call CreateView to trigger creation of accessibility bridge + auto view_tokens = scenic::NewViewTokenPair(); + frame_ptr_->CreateView(std::move(view_tokens.first)); + base::RunLoop().RunUntilIdle(); + } + + protected: + fuchsia::web::FramePtr frame_ptr_; + FrameImpl* frame_impl_; + FakeSemanticsManager semantics_manager_; + fidl::Binding<SemanticsManager> semantics_manager_binding_; + cr_fuchsia::TestNavigationListener navigation_listener_; + + DISALLOW_COPY_AND_ASSIGN(AccessibilityBridgeTest); +}; + +// Test registration to the SemanticsManager and accessibility mode on +// WebContents is set correctly.. +IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, RegisterViewRef) { + // Check that setup is successful. + EXPECT_TRUE(semantics_manager_.is_view_registered()); + EXPECT_TRUE(semantics_manager_.is_listener_valid()); + + // Change the accessibility mode on the Fuchsia side and check that it is + // propagated correctly. + EXPECT_FALSE(frame_impl_->web_contents_for_test() + ->IsWebContentsOnlyAccessibilityModeForTesting()); + semantics_manager_.SetSemanticsMode(true); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(frame_impl_->web_contents_for_test() + ->IsWebContentsOnlyAccessibilityModeForTesting()); +} + +IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, CorrectDataSent) { + fuchsia::web::NavigationControllerPtr controller; + frame_ptr_->GetNavigationController(controller.NewRequest()); + ASSERT_TRUE(embedded_test_server()->Start()); + GURL title1(embedded_test_server()->GetURL(kPage1Path)); + + semantics_manager_.SetSemanticsMode(true); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse( + controller.get(), fuchsia::web::LoadUrlParams(), title1.spec())); + navigation_listener_.RunUntilUrlAndTitleEquals(title1, kPage1Title); + + // Check that the data values are correct in the FakeSemanticTree. + // TODO(fxb/18796): Test more fields once Chrome to Fuchsia conversions are + // available. + semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(kPage1NodeCount); + EXPECT_TRUE( + semantics_manager_.semantic_tree()->HasNodeWithLabel(kPage1Title)); + EXPECT_TRUE( + semantics_manager_.semantic_tree()->HasNodeWithLabel(kButtonName)); + EXPECT_TRUE( + semantics_manager_.semantic_tree()->HasNodeWithLabel(kParagraphName)); +} + +// Batching is performed when the number of nodes to send or delete exceeds the +// maximum, as set on the Fuchsia side. Check that all nodes are received by the +// Semantic Tree when batching is performed. +IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, DataSentWithBatching) { + fuchsia::web::NavigationControllerPtr controller; + frame_ptr_->GetNavigationController(controller.NewRequest()); + ASSERT_TRUE(embedded_test_server()->Start()); + GURL title2(embedded_test_server()->GetURL(kPage2Path)); + + semantics_manager_.SetSemanticsMode(true); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse( + controller.get(), fuchsia::web::LoadUrlParams(), title2.spec())); + navigation_listener_.RunUntilUrlAndTitleEquals(title2, kPage2Title); + + // Run until we expect more than a batch's worth of nodes to be present. + semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(50); + EXPECT_TRUE(semantics_manager_.semantic_tree()->HasNodeWithLabel(kNodeName)); +}
diff --git a/fuchsia/engine/browser/accessibility_bridge_unittest.cc b/fuchsia/engine/browser/accessibility_bridge_unittest.cc deleted file mode 100644 index bb12bf2..0000000 --- a/fuchsia/engine/browser/accessibility_bridge_unittest.cc +++ /dev/null
@@ -1,101 +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 "fuchsia/engine/browser/accessibility_bridge.h" - -#include <fuchsia/accessibility/semantics/cpp/fidl.h> -#include <fuchsia/accessibility/semantics/cpp/fidl_test_base.h> -#include <lib/sys/cpp/component_context.h> -#include <lib/ui/scenic/cpp/view_ref_pair.h> -#include <zircon/types.h> - -#include "base/fuchsia/default_context.h" -#include "base/fuchsia/scoped_service_binding.h" -#include "base/fuchsia/service_directory_client.h" -#include "base/logging.h" -#include "base/test/task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -using fuchsia::accessibility::semantics::SemanticListener; -using fuchsia::accessibility::semantics::SemanticsManager; - -namespace { - -class FakeSemanticsManager : public fuchsia::accessibility::semantics::testing:: - SemanticsManager_TestBase { - public: - explicit FakeSemanticsManager() = default; - ~FakeSemanticsManager() override = default; - - // fuchsia::accessibility::semantics::SemanticsManager implementation. - void RegisterViewForSemantics( - fuchsia::ui::views::ViewRef view_ref, - fidl::InterfaceHandle<SemanticListener> listener, - fidl::InterfaceRequest<fuchsia::accessibility::semantics::SemanticTree> - semantic_tree) final { - view_ref_ = std::move(view_ref); - listener_ = std::move(listener); - semantic_tree_ = std::move(semantic_tree); - } - - bool is_view_registered() const { return view_ref_.reference.is_valid(); } - - bool is_listener_handle_valid() const { return listener_.is_valid(); } - - bool is_semantic_tree_handle_valid() const { - return semantic_tree_.is_valid(); - } - - void NotImplemented_(const std::string& name) final { - NOTIMPLEMENTED() << name; - } - - private: - fuchsia::ui::views::ViewRef view_ref_; - fidl::InterfaceHandle<SemanticListener> listener_; - fidl::InterfaceRequest<fuchsia::accessibility::semantics::SemanticTree> - semantic_tree_; - - DISALLOW_COPY_AND_ASSIGN(FakeSemanticsManager); -}; - -} // namespace - -class AccessibilityBridgeTest : public testing::Test { - public: - AccessibilityBridgeTest() - : task_environment_(base::test::TaskEnvironment::MainThreadType::IO), - semantics_manager_binding_(&semantics_manager_) {} - ~AccessibilityBridgeTest() override = default; - - void CreateAccessibilityBridge() { - auto view_ref_pair = scenic::ViewRefPair::New(); - control_ref_ = std::move(view_ref_pair.control_ref); - fuchsia::accessibility::semantics::SemanticsManagerPtr - semantics_manager_ptr; - semantics_manager_binding_.Bind(semantics_manager_ptr.NewRequest()); - accessibility_bridge_ = std::make_unique<AccessibilityBridge>( - std::move(semantics_manager_ptr), std::move(view_ref_pair.view_ref)); - } - - protected: - base::test::SingleThreadTaskEnvironment task_environment_; - std::unique_ptr<AccessibilityBridge> accessibility_bridge_; - FakeSemanticsManager semantics_manager_; - fidl::Binding<fuchsia::accessibility::semantics::SemanticsManager> - semantics_manager_binding_; - fuchsia::ui::views::ViewRefControl control_ref_; - - DISALLOW_COPY_AND_ASSIGN(AccessibilityBridgeTest); -}; - -// Test registration to the SemanticsManager. -TEST_F(AccessibilityBridgeTest, RegisterViewRef) { - CreateAccessibilityBridge(); - // Run loop so FIDL registration requests are processed. - task_environment_.RunUntilIdle(); - EXPECT_TRUE(semantics_manager_.is_view_registered()); - EXPECT_TRUE(semantics_manager_.is_listener_handle_valid()); - EXPECT_TRUE(semantics_manager_.is_semantic_tree_handle_valid()); -}
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc index 31be8d5..2f94199 100644 --- a/fuchsia/engine/browser/frame_impl.cc +++ b/fuchsia/engine/browser/frame_impl.cc
@@ -4,10 +4,12 @@ #include "fuchsia/engine/browser/frame_impl.h" +#include <lib/sys/cpp/component_context.h> #include <lib/ui/scenic/cpp/view_ref_pair.h> #include <limits> #include "base/bind_helpers.h" +#include "base/fuchsia/default_context.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/json/json_writer.h" #include "base/strings/strcat.h" @@ -24,6 +26,7 @@ #include "content/public/common/was_activated_option.mojom.h" #include "fuchsia/base/mem_buffer_util.h" #include "fuchsia/base/message_port.h" +#include "fuchsia/engine/browser/accessibility_bridge.h" #include "fuchsia/engine/browser/context_impl.h" #include "fuchsia/engine/browser/web_engine_devtools_controller.h" #include "mojo/public/cpp/bindings/associated_remote.h" @@ -465,6 +468,27 @@ properties.view_token = std::move(view_token); properties.view_ref_pair = scenic::ViewRefPair::New(); + // Create a ViewRef and register it to the Fuchsia SemanticsManager. + fuchsia::ui::views::ViewRef accessibility_view_ref; + zx_status_t status = properties.view_ref_pair.view_ref.reference.duplicate( + ZX_RIGHT_SAME_RIGHTS, &accessibility_view_ref.reference); + if (status == ZX_OK) { + fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager; + if (test_semantics_manager_ptr_) { + semantics_manager = std::move(test_semantics_manager_ptr_); + } else { + semantics_manager = + base::fuchsia::ComponentContextForCurrentProcess() + ->svc() + ->Connect<fuchsia::accessibility::semantics::SemanticsManager>(); + } + accessibility_bridge_ = std::make_unique<AccessibilityBridge>( + std::move(semantics_manager), std::move(accessibility_view_ref), + web_contents_.get()); + } else { + ZX_LOG(ERROR, status) << "zx_object_duplicate"; + } + window_tree_host_ = std::make_unique<FrameWindowTreeHost>(std::move(properties)); window_tree_host_->InitHost();
diff --git a/fuchsia/engine/browser/frame_impl.h b/fuchsia/engine/browser/frame_impl.h index 6e7f8c6..10b2953e 100644 --- a/fuchsia/engine/browser/frame_impl.h +++ b/fuchsia/engine/browser/frame_impl.h
@@ -20,6 +20,7 @@ #include "base/memory/platform_shared_memory_region.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" +#include "fuchsia/engine/browser/accessibility_bridge.h" #include "fuchsia/engine/browser/discarding_event_filter.h" #include "fuchsia/engine/browser/navigation_controller_impl.h" #include "fuchsia/engine/browser/url_request_rewrite_rules_manager.h" @@ -57,6 +58,14 @@ base::RepeatingCallback<void(base::StringPiece)> hook) { console_log_message_hook_ = std::move(hook); } + AccessibilityBridge* accessibility_bridge_for_test() const { + return accessibility_bridge_.get(); + } + void set_semantics_manager_for_test( + fuchsia::accessibility::semantics::SemanticsManagerPtr + semantics_manager) { + test_semantics_manager_ptr_ = std::move(semantics_manager); + } private: FRIEND_TEST_ALL_PREFIXES(FrameImplTest, DelayedNavigationEventAck); @@ -170,6 +179,9 @@ const std::unique_ptr<content::WebContents> web_contents_; std::unique_ptr<wm::FocusController> focus_controller_; ContextImpl* const context_; + std::unique_ptr<AccessibilityBridge> accessibility_bridge_; + fuchsia::accessibility::semantics::SemanticsManagerPtr + test_semantics_manager_ptr_; DiscardingEventFilter discarding_event_filter_; NavigationControllerImpl navigation_controller_;
diff --git a/fuchsia/engine/browser/frame_impl_browsertest.cc b/fuchsia/engine/browser/frame_impl_browsertest.cc index 28f64e13..af9c1c3 100644 --- a/fuchsia/engine/browser/frame_impl_browsertest.cc +++ b/fuchsia/engine/browser/frame_impl_browsertest.cc
@@ -24,6 +24,7 @@ #include "fuchsia/base/test_navigation_listener.h" #include "fuchsia/base/url_request_rewrite_test_util.h" #include "fuchsia/engine/browser/frame_impl.h" +#include "fuchsia/engine/test/test_data.h" #include "fuchsia/engine/test/web_engine_browser_test.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" @@ -62,7 +63,6 @@ const char kPage3Title[] = "websql not available"; const char kDataUrl[] = "data:text/html;base64,PGI+SGVsbG8sIHdvcmxkLi4uPC9iPg=="; -const char kTestServerRoot[] = FILE_PATH_LITERAL("fuchsia/engine/test/data"); const int64_t kOnLoadScriptId = 0; MATCHER_P(NavigationHandleUrlEquals, @@ -100,7 +100,7 @@ FrameImplTest() : run_timeout_(TestTimeouts::action_timeout(), base::MakeExpectedNotRunClosure(FROM_HERE)) { - set_test_server_root(base::FilePath(kTestServerRoot)); + set_test_server_root(base::FilePath(cr_fuchsia::kTestServerRoot)); } ~FrameImplTest() = default;
diff --git a/fuchsia/engine/browser/media_browsertest.cc b/fuchsia/engine/browser/media_browsertest.cc index 23fca26..96a13e5d 100644 --- a/fuchsia/engine/browser/media_browsertest.cc +++ b/fuchsia/engine/browser/media_browsertest.cc
@@ -10,17 +10,17 @@ #include "fuchsia/base/frame_test_util.h" #include "fuchsia/base/test_navigation_listener.h" #include "fuchsia/engine/switches.h" +#include "fuchsia/engine/test/test_data.h" #include "testing/gtest/include/gtest/gtest.h" namespace { -const char kTestServerRoot[] = FILE_PATH_LITERAL("fuchsia/engine/test/data"); class MediaTest : public cr_fuchsia::WebEngineBrowserTest { public: MediaTest() : run_timeout_(TestTimeouts::action_timeout(), base::MakeExpectedNotRunClosure(FROM_HERE)) { - set_test_server_root(base::FilePath(kTestServerRoot)); + set_test_server_root(base::FilePath(cr_fuchsia::kTestServerRoot)); } ~MediaTest() override = default;
diff --git a/fuchsia/engine/test/data/ax1.html b/fuchsia/engine/test/data/ax1.html new file mode 100644 index 0000000..5b7017d2 --- /dev/null +++ b/fuchsia/engine/test/data/ax1.html
@@ -0,0 +1,7 @@ +<html> + <head><title>accessibility 1</title></head> + <body> + <button>a button</button> + <p>a paragraph</p> + </body> +</html>
diff --git a/fuchsia/engine/test/data/batching.html b/fuchsia/engine/test/data/batching.html new file mode 100644 index 0000000..4059eacd --- /dev/null +++ b/fuchsia/engine/test/data/batching.html
@@ -0,0 +1,99 @@ +<html> + <head><title>lots of nodes!</title></head> + <body> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>node</p> + <p>last node</p> + </body> +</html>
diff --git a/fuchsia/engine/test/test_data.cc b/fuchsia/engine/test/test_data.cc new file mode 100644 index 0000000..1ca9e32 --- /dev/null +++ b/fuchsia/engine/test/test_data.cc
@@ -0,0 +1,13 @@ +// 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 "fuchsia/engine/test/test_data.h" + +#include "base/files/file_path.h" + +namespace cr_fuchsia { + +const char kTestServerRoot[] = FILE_PATH_LITERAL("fuchsia/engine/test/data"); + +} // namespace cr_fuchsia \ No newline at end of file
diff --git a/fuchsia/engine/test/test_data.h b/fuchsia/engine/test/test_data.h new file mode 100644 index 0000000..5a5618e --- /dev/null +++ b/fuchsia/engine/test/test_data.h
@@ -0,0 +1,15 @@ +// 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 FUCHSIA_ENGINE_TEST_TEST_DATA_H_ +#define FUCHSIA_ENGINE_TEST_TEST_DATA_H_ + +namespace cr_fuchsia { + +// Path to data used in browsertests. +extern const char kTestServerRoot[]; + +} // namespace cr_fuchsia + +#endif // FUCHSIA_ENGINE_TEST_TEST_DATA_H_ \ No newline at end of file
diff --git a/fuchsia/runners/web/web_runner.cmx b/fuchsia/runners/web/web_runner.cmx index 50e3a7e4..af9afcc9 100644 --- a/fuchsia/runners/web/web_runner.cmx +++ b/fuchsia/runners/web/web_runner.cmx
@@ -4,6 +4,7 @@ "isolated-persistent-storage" ], "services": [ + "fuchsia.accessibility.semantics.SemanticsManager", "fuchsia.deprecatedtimezone.Timezone", "fuchsia.device.NameProvider", "fuchsia.fonts.Provider",
diff --git a/gpu/ipc/client/gpu_channel_host.cc b/gpu/ipc/client/gpu_channel_host.cc index 4b8c137..505affa4 100644 --- a/gpu/ipc/client/gpu_channel_host.cc +++ b/gpu/ipc/client/gpu_channel_host.cc
@@ -21,6 +21,7 @@ #include "gpu/ipc/common/gpu_watchdog_timeout.h" #include "ipc/ipc_channel_mojo.h" #include "ipc/ipc_sync_message.h" +#include "mojo/public/cpp/bindings/lib/message_quota_checker.h" #include "url/gurl.h" using base::AutoLock; @@ -274,11 +275,13 @@ GpuChannelHost::Listener::Listener( mojo::ScopedMessagePipeHandle handle, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) - : channel_(IPC::ChannelMojo::Create(std::move(handle), - IPC::Channel::MODE_CLIENT, - this, - io_task_runner, - base::ThreadTaskRunnerHandle::Get())) { + : channel_(IPC::ChannelMojo::Create( + std::move(handle), + IPC::Channel::MODE_CLIENT, + this, + io_task_runner, + base::ThreadTaskRunnerHandle::Get(), + mojo::internal::MessageQuotaChecker::MaybeCreate())) { DCHECK(channel_); DCHECK(io_task_runner->BelongsToCurrentThread()); bool result = channel_->Connect();
diff --git a/headless/lib/browser/headless_request_context_manager.cc b/headless/lib/browser/headless_request_context_manager.cc index f6349e2..f0586c8 100644 --- a/headless/lib/browser/headless_request_context_manager.cc +++ b/headless/lib/browser/headless_request_context_manager.cc
@@ -230,9 +230,10 @@ context_params->primary_network_context = is_system; // TODO(https://crbug.com/458508): Allow - // context_params->allow_default_credentials to be controllable by a flag. - context_params->allow_default_credentials = - net::HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS; + // context_params->http_auth_static_network_context_params->allow_default_credentials + // to be controllable by a flag. + context_params->http_auth_static_network_context_params = + ::network::mojom::HttpAuthStaticNetworkContextParams::New(); if (!user_data_path_.empty()) { context_params->enable_encrypted_cookies = cookie_encryption_enabled_;
diff --git a/headless/test/data/protocol/emulation/virtual-time-fetch-keepalive-expected.txt b/headless/test/data/protocol/emulation/virtual-time-fetch-keepalive-expected.txt new file mode 100644 index 0000000..6c5b42c --- /dev/null +++ b/headless/test/data/protocol/emulation/virtual-time-fetch-keepalive-expected.txt
@@ -0,0 +1,2 @@ +Tests that virtual time does not hang when a fetch is cancelled due to exceeded size of pending keepalive data. +Request to https://test.com/index.html, type: Document \ No newline at end of file
diff --git a/headless/test/data/protocol/emulation/virtual-time-fetch-keepalive.js b/headless/test/data/protocol/emulation/virtual-time-fetch-keepalive.js new file mode 100644 index 0000000..55f3526 --- /dev/null +++ b/headless/test/data/protocol/emulation/virtual-time-fetch-keepalive.js
@@ -0,0 +1,33 @@ +// 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. + +(async function(testRunner) { + const {page, session, dp} = await testRunner.startBlank( + 'Tests that virtual time does not hang when a fetch is cancelled ' + + 'due to exceeded size of pending keepalive data.'); + + const FetchHelper = await testRunner.loadScriptAbsolute( + '../fetch/resources/fetch-test.js'); + const helper = new FetchHelper(testRunner, dp); + await helper.enable(); + + helper.onceRequest('https://test.com/index.html').fulfill( + FetchHelper.makeContentResponse(`<html></html>`)); + + await dp.Emulation.setVirtualTimePolicy({policy: 'pause'}); + await dp.Emulation.setVirtualTimePolicy({ + policy: 'pauseIfNetworkFetchesPending', budget: 5000, + waitForNavigation: true}); + await dp.Page.navigate({url: 'https://test.com/index.html'}); + + helper.onceRequest('https://test.com/post').matched().then(() => + testRunner.log('FAIL: this request should not come through!')); + + await session.evaluateAsync(` + fetch('/post', {method: 'POST', body: '*'.repeat(64 * 1024 + 1), + keepalive: true}) + `); + await dp.Emulation.onceVirtualTimeBudgetExpired(); + testRunner.completeTest(); +})
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc index 4d39ed2..65ca28b 100644 --- a/headless/test/headless_protocol_browsertest.cc +++ b/headless/test/headless_protocol_browsertest.cc
@@ -248,6 +248,8 @@ "emulation/virtual-time-history-navigation.js") HEADLESS_PROTOCOL_TEST(VirtualTimeHistoryNavigationSameDoc, "emulation/virtual-time-history-navigation-same-doc.js") +HEADLESS_PROTOCOL_TEST(VirtualTimeFetchKeepalive, + "emulation/virtual-time-fetch-keepalive.js") // http://crbug.com/633321 #if defined(OS_ANDROID)
diff --git a/ios/build/bots/tests/common_tests.json b/ios/build/bots/tests/common_tests.json index 42eb87b0..ad8a2931 100644 --- a/ios/build/bots/tests/common_tests.json +++ b/ios/build/bots/tests/common_tests.json
@@ -25,7 +25,7 @@ "app": "net_unittests" }, { - "app": "ocmock_support_unittests" + "app": "ios_testing_unittests" }, { "app": "services_unittests"
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index 944061c..70efeafa 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -61,11 +61,11 @@ "//ios/chrome/browser/tabs", "//ios/chrome/common/app_group", "//ios/chrome/test:test_support", - "//ios/chrome/test/base", "//ios/public/provider/chrome/browser:browser", "//ios/public/provider/chrome/browser:test_support", "//ios/public/provider/chrome/browser/distribution", "//ios/public/provider/chrome/browser/distribution:test_support", + "//ios/testing:block_swizzler", "//ios/web/public/test:test", "//testing/gtest", "//third_party/ocmock",
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn index 5b2e830..5c118e1 100644 --- a/ios/chrome/app/application_delegate/BUILD.gn +++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -63,11 +63,11 @@ "//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list:test_support", "//ios/chrome/test:test_support", - "//ios/chrome/test/base", "//ios/chrome/test/ocmock", "//ios/public/provider/chrome/browser:test_support", "//ios/public/provider/chrome/browser/distribution", "//ios/public/provider/chrome/browser/user_feedback:test_support", + "//ios/testing:block_swizzler", "//ios/testing:ocmock_support", "//ios/web", "//ios/web/public/test",
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm index 0b692c28..d876272 100644 --- a/ios/chrome/app/application_delegate/app_state_unittest.mm +++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -42,13 +42,13 @@ #import "ios/chrome/browser/ui/main/test/stub_browser_interface_provider.h" #import "ios/chrome/browser/ui/safe_mode/safe_mode_coordinator.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" #include "ios/chrome/test/block_cleanup_test.h" #include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h" #include "ios/public/provider/chrome/browser/distribution/app_distribution_provider.h" #include "ios/public/provider/chrome/browser/test_chrome_browser_provider.h" #include "ios/public/provider/chrome/browser/user_feedback/test_user_feedback_provider.h" #import "ios/testing/ocmock_complex_type_helper.h" +#import "ios/testing/scoped_block_swizzler.h" #include "ios/web/public/test/web_task_environment.h" #include "ios/web/public/thread/web_task_traits.h" #import "third_party/ocmock/OCMock/OCMock.h"
diff --git a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm index 01ac611..aab3c37b 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm
@@ -19,8 +19,8 @@ #import "ios/chrome/browser/ui/main/test/stub_browser_interface_provider.h" #import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" #import "ios/chrome/test/ocmock/OCMockObject+BreakpadControllerTesting.h" +#import "ios/testing/scoped_block_swizzler.h" #include "net/base/network_change_notifier.h" #include "testing/platform_test.h" #import "third_party/breakpad/breakpad/src/client/ios/BreakpadController.h"
diff --git a/ios/chrome/app/application_delegate/url_opener_unittest.mm b/ios/chrome/app/application_delegate/url_opener_unittest.mm index c7fd39b..3be9dffb 100644 --- a/ios/chrome/app/application_delegate/url_opener_unittest.mm +++ b/ios/chrome/app/application_delegate/url_opener_unittest.mm
@@ -16,7 +16,7 @@ #import "ios/chrome/browser/ui/main/test/stub_browser_interface_provider.h" #import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" +#import "ios/testing/scoped_block_swizzler.h" #include "ios/web/public/test/web_task_environment.h" #include "testing/gtest_mac.h" #include "testing/platform_test.h"
diff --git a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm b/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm index d63f2293..a6f478e 100644 --- a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm +++ b/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm
@@ -32,7 +32,7 @@ #import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_opener.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" +#import "ios/testing/scoped_block_swizzler.h" #import "ios/web/public/test/fakes/test_web_state.h" #import "net/base/mac/url_conversions.h" #include "net/test/gtest_util.h"
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index fecc8a6..5ad1985 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -293,6 +293,12 @@ <message name="IDS_IOS_AUTOFILL_EXP_YEAR" desc="Title of the field representing the expiration year of a credit card. [Length: 15em] [iOS only]"> Expiration Year </message> + <message name="IDS_IOS_AUTOFILL_CARDHOLDER_NAME" desc="Tile of the field representing the cardholder name of a credit card. [Length: 15em] [iOS only]"> + Cardholder Name + </message> + <message name="IDS_IOS_AUTOFILL_SAVE_CARD" desc="Title for the view for saving a credit card. [Length: 15em] [iOS only]"> + Save Card + </message> <message name="IDS_IOS_AUTOFILL_FULLNAME" desc="Title of the field of a profile address representing the full name of the addressee. [Length: 15em] [iOS only]"> Full Name </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_CARDHOLDER_NAME.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_CARDHOLDER_NAME.png.sha1 new file mode 100644 index 0000000..b45e7b9 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_CARDHOLDER_NAME.png.sha1
@@ -0,0 +1 @@ +64cccc843ea70fdf800d77ff72a1a9f1d69064d4 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_SAVE_CARD.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_SAVE_CARD.png.sha1 new file mode 100644 index 0000000..f381a06 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AUTOFILL_SAVE_CARD.png.sha1
@@ -0,0 +1 @@ +56bf15e2f93bdb7b5b128f00f7027ca2c1a74319 \ No newline at end of file
diff --git a/ios/chrome/app/tab_opener_unittest.mm b/ios/chrome/app/tab_opener_unittest.mm index c2575ed..8df077c 100644 --- a/ios/chrome/app/tab_opener_unittest.mm +++ b/ios/chrome/app/tab_opener_unittest.mm
@@ -9,7 +9,7 @@ #import "ios/chrome/app/application_delegate/url_opener.h" #include "ios/chrome/app/main_controller_private.h" #import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" +#import "ios/testing/scoped_block_swizzler.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h"
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn index c26b4be..09d2f2eb 100644 --- a/ios/chrome/browser/autofill/BUILD.gn +++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -176,7 +176,7 @@ "//ios/chrome/browser/web:test_support", "//ios/chrome/browser/web:web_internal", "//ios/chrome/browser/webdata_services", - "//ios/chrome/test/base", + "//ios/testing:block_swizzler", "//ios/web/public/deprecated", "//ios/web/public/js_messaging", "//ios/web/public/test",
diff --git a/ios/chrome/browser/crash_report/BUILD.gn b/ios/chrome/browser/crash_report/BUILD.gn index 98fdf653..6d41c083 100644 --- a/ios/chrome/browser/crash_report/BUILD.gn +++ b/ios/chrome/browser/crash_report/BUILD.gn
@@ -88,8 +88,8 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/sessions:serialisation", - "//ios/chrome/test/base", "//ios/chrome/test/ocmock", + "//ios/testing:block_swizzler", "//ios/web/public/test", "//testing/gmock", "//testing/gtest",
diff --git a/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm b/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm index c76c190..309f4224 100644 --- a/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm +++ b/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm
@@ -5,8 +5,8 @@ #import "ios/chrome/browser/crash_report/breakpad_helper.h" #import "base/test/ios/wait_util.h" #include "ios/chrome/browser/crash_report/main_thread_freeze_detector.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" #import "ios/chrome/test/ocmock/OCMockObject+BreakpadControllerTesting.h" +#import "ios/testing/scoped_block_swizzler.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #import "third_party/breakpad/breakpad/src/client/ios/BreakpadController.h"
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h index c9d1560..a5f1b6f 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h +++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
@@ -135,6 +135,7 @@ GetPasswordRequirementsService() override; bool IsIsolationForPasswordSitesEnabled() const override; bool IsNewTabPage() const override; + password_manager::FieldInfoManager* GetFieldInfoManager() const override; private: __weak id<PasswordManagerClientDelegate> delegate_;
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm index 8c0f5db2..92742663 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm +++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
@@ -266,3 +266,8 @@ bool IOSChromePasswordManagerClient::IsNewTabPage() const { return false; } + +password_manager::FieldInfoManager* +IOSChromePasswordManagerClient::GetFieldInfoManager() const { + return nullptr; +}
diff --git a/ios/chrome/browser/ui/alert_coordinator/BUILD.gn b/ios/chrome/browser/ui/alert_coordinator/BUILD.gn index 3d4366b..70dc733 100644 --- a/ios/chrome/browser/ui/alert_coordinator/BUILD.gn +++ b/ios/chrome/browser/ui/alert_coordinator/BUILD.gn
@@ -71,24 +71,3 @@ ] libs = [ "UIKit.framework" ] } - -source_set("eg_tests") { - configs += [ "//build/config/compiler:enable_arc" ] - testonly = true - sources = [ - "alert_coordinator_egtest.mm", - ] - deps = [ - ":alert_coordinator", - "//base", - "//components/strings", - "//ios/chrome/browser/ui/util", - "//ios/chrome/test/earl_grey:test_support", - "//ios/testing/earl_grey:earl_grey_support", - "//ios/third_party/earl_grey:earl_grey+link", - ] - libs = [ - "UIKit.framework", - "XCTest.framework", - ] -}
diff --git a/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_egtest.mm b/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_egtest.mm deleted file mode 100644 index 892f941..0000000 --- a/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_egtest.mm +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import <EarlGrey/EarlGrey.h> -#import <UIKit/UIKit.h> -#import <XCTest/XCTest.h> - -#include "components/strings/grit/components_strings.h" -#import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" -#import "ios/chrome/browser/ui/util/top_view_controller.h" -#import "ios/chrome/test/earl_grey/chrome_matchers.h" -#import "ios/chrome/test/earl_grey/chrome_test_case.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -NSString* kTitle = @"Foo Title"; -} // namespace - -// Integration test for the alert coordinator using Earl Grey. -@interface AlertCoordinatorTestCase : ChromeTestCase - -// Whether an alert is presented. -- (BOOL)isPresentingAlert; - -@end - -@implementation AlertCoordinatorTestCase - -// Tests that if the alert coordinator is destroyed, the alert is dismissed. -- (void)testDismissOnDestroy { - // TODO(crbug.com/754642): Remove TopPresentedViewControllerFrom(). - UIViewController* topViewController = - top_view_controller::TopPresentedViewController(); - - AlertCoordinator* alertCoordinator = - [[AlertCoordinator alloc] initWithBaseViewController:topViewController - title:kTitle - message:nil]; - - [alertCoordinator start]; - - GREYAssertTrue([self isPresentingAlert], @"An alert should be presented"); - - alertCoordinator = nil; - - GREYAssertFalse([self isPresentingAlert], @"The alert should be removed"); -} - -- (void)testNoInteractionActionAfterTap { - // TODO(crbug.com/754642): Remove TopPresentedViewControllerFrom(). - UIViewController* topViewController = - top_view_controller::TopPresentedViewController(); - - AlertCoordinator* alertCoordinator = - [[AlertCoordinator alloc] initWithBaseViewController:topViewController - title:kTitle - message:nil]; - - __block BOOL blockCalled = NO; - - [alertCoordinator setNoInteractionAction:^{ - blockCalled = YES; - }]; - - [alertCoordinator start]; - - GREYAssertTrue([self isPresentingAlert], @"An alert should be presented"); - - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_OK)] performAction:grey_tap()]; - - GREYAssertFalse([self isPresentingAlert], @"The alert should be removed"); - - GREYAssertFalse(blockCalled, - @"The noInteractionBlock should not have been called."); -} - -- (BOOL)isPresentingAlert { - NSError* error = nil; - [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(kTitle)] - assertWithMatcher:grey_sufficientlyVisible() - error:&error]; - - return (error == nil); -} - -@end
diff --git a/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_unittest.mm b/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_unittest.mm index 28fc00ad..dd2d04d 100644 --- a/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_unittest.mm
@@ -228,6 +228,8 @@ EXPECT_EQ(UIAlertActionStyleCancel, action.style); } +// Tests that the |noInteractionAction| block is called for an alert coordinator +// which is stopped before the user has interacted with it. TEST_F(AlertCoordinatorTest, NoInteractionActionTest) { // Setup. UIViewController* viewController = getViewController(); @@ -248,6 +250,8 @@ EXPECT_TRUE(blockCalled); } +// Tests that the |noInteractionAction| block is not called for an alert +// coordinator which is dismissed with the cancel button. TEST_F(AlertCoordinatorTest, NoInteractionActionWithCancelTest) { // Setup. UIViewController* viewController = getViewController(); @@ -268,3 +272,26 @@ // Test. EXPECT_FALSE(blockCalled); } + +// Tests that the alert coordinator is dismissed if destroyed without being +// stopped. +TEST_F(AlertCoordinatorTest, AlertDismissedOnDestroy) { + // Setup. + UIViewController* viewController = getViewController(); + AlertCoordinator* alertCoordinator = getAlertCoordinator(viewController); + + ASSERT_FALSE(alertCoordinator.isVisible); + ASSERT_EQ(nil, viewController.presentedViewController); + + __block BOOL blockCalled = NO; + + alertCoordinator.noInteractionAction = ^{ + blockCalled = YES; + }; + + startAlertCoordinator(); + + alertCoordinator = nil; + + EXPECT_FALSE(blockCalled); +}
diff --git a/ios/chrome/browser/ui/collection_view/BUILD.gn b/ios/chrome/browser/ui/collection_view/BUILD.gn index 801b3829..89eb06e 100644 --- a/ios/chrome/browser/ui/collection_view/BUILD.gn +++ b/ios/chrome/browser/ui/collection_view/BUILD.gn
@@ -51,7 +51,7 @@ "//base", "//ios/chrome/browser/ui/collection_view/cells", "//ios/chrome/test:test_support", - "//ios/chrome/test/base", + "//ios/testing:block_swizzler", "//ios/third_party/material_components_ios", "//testing/gtest", ]
diff --git a/ios/chrome/browser/ui/collection_view/collection_view_controller_unittest.mm b/ios/chrome/browser/ui/collection_view/collection_view_controller_unittest.mm index 0d915ef..016e255ae 100644 --- a/ios/chrome/browser/ui/collection_view/collection_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/collection_view/collection_view_controller_unittest.mm
@@ -6,8 +6,8 @@ #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" #include "ios/chrome/test/block_cleanup_test.h" +#import "ios/testing/scoped_block_swizzler.h" #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index 341c069..bf2dd658 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -226,8 +226,8 @@ "//ios/chrome/browser/url_loading", "//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list:test_support", - "//ios/chrome/test/base", "//ios/public/provider/chrome/browser/ui", + "//ios/testing:block_swizzler", "//ios/web/public/test", "//ios/web/public/test/fakes", "//testing/gtest", @@ -259,7 +259,6 @@ "//ios/chrome/app/strings", "//ios/chrome/browser/ui/toolbar/public:constants", "//ios/chrome/test:eg_test_support+eg2", - "//ios/chrome/test/base", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib", @@ -306,7 +305,6 @@ "//ios/chrome/test:eg_test_support", "//ios/chrome/test:test_support", "//ios/chrome/test/app:test_support", - "//ios/chrome/test/base:base", "//ios/chrome/test/earl_grey:test_support", "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link", @@ -373,7 +371,7 @@ "//ios/chrome/browser/search_engines", "//ios/chrome/browser/ui/util", "//ios/chrome/test/app:test_support", - "//ios/chrome/test/base", + "//ios/testing:block_swizzler", "//ios/testing/earl_grey:eg_app_support+eg2", "//ios/third_party/earl_grey2:app_framework+link", "//testing/gmock", @@ -409,7 +407,7 @@ "//ios/chrome/browser/ui/content_suggestions:content_suggestions_ui", "//ios/chrome/browser/ui/util", "//ios/chrome/test/app:test_support", - "//ios/chrome/test/base", + "//ios/testing:block_swizzler", "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link", "//ios/web",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm index 5b96bce..c6a1e9f 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm
@@ -7,7 +7,7 @@ #include <memory> #include "ios/chrome/browser/ui/util/ui_util.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" +#import "ios/testing/scoped_block_swizzler.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer_unittest.mm index feb40ed..ab44a10 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer_unittest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer_unittest.mm
@@ -8,7 +8,7 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_controlling.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_controlling.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" +#import "ios/testing/scoped_block_swizzler.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h" #import "third_party/ocmock/gtest_support.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm index 4094104d..a6d1a97a 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm
@@ -8,7 +8,7 @@ #include "components/ntp_snippets/content_suggestion.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.h" -#include "ios/chrome/test/base/scoped_block_swizzler.h" +#include "ios/testing/scoped_block_swizzler.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_save_card_coordinator.mm b/ios/chrome/browser/ui/infobars/coordinators/infobar_save_card_coordinator.mm index a3576f97..3c019ef 100644 --- a/ios/chrome/browser/ui/infobars/coordinators/infobar_save_card_coordinator.mm +++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_save_card_coordinator.mm
@@ -13,6 +13,8 @@ #import "ios/chrome/browser/ui/infobars/infobar_container.h" #import "ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" +#include "ios/chrome/grit/ios_strings.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/gfx/image/image.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -154,10 +156,20 @@ self.modalViewController = [[InfobarSaveCardTableViewController alloc] initWithModalDelegate:self]; - // TODO(crbug.com/1014652): Replace with Modal specific text. - self.modalViewController.title = @"Save Credit Card"; + self.modalViewController.title = + l10n_util::GetNSString(IDS_IOS_AUTOFILL_SAVE_CARD); self.modalViewController.cardIssuerIcon = NativeImage(self.saveCardInfoBarDelegate->issuer_icon_id()); + self.modalViewController.cardNumber = [NSString + stringWithFormat:@"•••• %@", + base::SysUTF16ToNSString(self.saveCardInfoBarDelegate + ->card_last_four_digits())]; + self.modalViewController.cardholderName = + base::SysUTF16ToNSString(self.saveCardInfoBarDelegate->cardholder_name()); + self.modalViewController.expirationMonth = base::SysUTF16ToNSString( + self.saveCardInfoBarDelegate->expiration_date_month()); + self.modalViewController.expirationYear = base::SysUTF16ToNSString( + self.saveCardInfoBarDelegate->expiration_date_year()); return YES; }
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.h b/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.h index 6dc253b..43c51a5 100644 --- a/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.h +++ b/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.h
@@ -20,9 +20,21 @@ (ChromeTableViewControllerStyle)appBarStyle NS_UNAVAILABLE; +// Cardholder name to be displayed. +@property(nonatomic, copy) NSString* cardholderName; + // Card Issuer icon image to be displayed. @property(nonatomic, strong) UIImage* cardIssuerIcon; +// Card Number to be displayed. +@property(nonatomic, copy) NSString* cardNumber; + +// Card Expiration Month to be displayed +@property(nonatomic, copy) NSString* expirationMonth; + +// Card Expiration Year to be displayed. +@property(nonatomic, copy) NSString* expirationYear; + @end #endif // IOS_CHROME_BROWSER_UI_INFOBARS_MODALS_INFOBAR_SAVE_CARD_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm index f902e75c..ed106453 100644 --- a/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm +++ b/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm
@@ -15,6 +15,8 @@ #import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #import "ios/chrome/common/colors/semantic_color_names.h" +#include "ios/chrome/grit/ios_strings.h" +#include "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -101,56 +103,54 @@ TableViewModel* model = self.tableViewModel; [model addSectionWithIdentifier:SectionIdentifierContent]; - // TODO(crbug.com/1014652): Use the real strings once they are exposed in the - // delegate. - TableViewTextEditItem* cardLastDigitsItem = - [self textEditItemWithType:ItemTypeCardExpireYear - textFieldName:@"Card Number" - textFieldValue:@"•••• 1234" - textFieldEnabled:NO]; + TableViewTextEditItem* cardLastDigitsItem = [self + textEditItemWithType:ItemTypeCardExpireYear + textFieldName:l10n_util::GetNSString(IDS_IOS_AUTOFILL_CARD_NUMBER) + textFieldValue:self.cardNumber + textFieldEnabled:NO]; cardLastDigitsItem.identifyingIcon = self.cardIssuerIcon; [model addItem:cardLastDigitsItem toSectionWithIdentifier:SectionIdentifierContent]; - // TODO(crbug.com/1014652): Use the real strings once they are exposed in the - // delegate. + // TODO(crbug.com/1014652): Change textFieldEnabled to YES once editing its + // supported. TableViewTextEditItem* cardholderNameItem = [self textEditItemWithType:ItemTypeCardExpireYear - textFieldName:@"Cardholder Name" - textFieldValue:@"Sergio Collazos" - textFieldEnabled:YES]; + textFieldName:l10n_util::GetNSString( + IDS_IOS_AUTOFILL_CARDHOLDER_NAME) + textFieldValue:self.cardholderName + textFieldEnabled:NO]; [model addItem:cardholderNameItem toSectionWithIdentifier:SectionIdentifierContent]; - // TODO(crbug.com/1014652): Use the real strings once they are exposed in the - // delegate. - TableViewTextEditItem* expireMonthItem = - [self textEditItemWithType:ItemTypeCardExpireYear - textFieldName:@"Expiration Month" - textFieldValue:@"07" - textFieldEnabled:YES]; + // TODO(crbug.com/1014652): Change textFieldEnabled to YES once editing its + // supported. + TableViewTextEditItem* expireMonthItem = [self + textEditItemWithType:ItemTypeCardExpireYear + textFieldName:l10n_util::GetNSString(IDS_IOS_AUTOFILL_EXP_MONTH) + textFieldValue:self.expirationMonth + textFieldEnabled:NO]; [model addItem:expireMonthItem toSectionWithIdentifier:SectionIdentifierContent]; - // TODO(crbug.com/1014652): Use the real strings once they are exposed in the - // delegate. - TableViewTextEditItem* expireYearItem = - [self textEditItemWithType:ItemTypeCardExpireYear - textFieldName:@"Expiration Year" - textFieldValue:@"2020" - textFieldEnabled:YES]; + // TODO(crbug.com/1014652): Change textFieldEnabled to YES once editing its + // supported. + TableViewTextEditItem* expireYearItem = [self + textEditItemWithType:ItemTypeCardExpireYear + textFieldName:l10n_util::GetNSString(IDS_IOS_AUTOFILL_EXP_YEAR) + textFieldValue:self.expirationYear + textFieldEnabled:NO]; [model addItem:expireYearItem toSectionWithIdentifier:SectionIdentifierContent]; - // TODO(crbug.com/1014652): Use the real strings once they are exposed in the - // delegate. TableViewTextButtonItem* saveCardButtonItem = [[TableViewTextButtonItem alloc] initWithType:ItemTypeCardSave]; saveCardButtonItem.textAlignment = NSTextAlignmentNatural; // TODO(crbug.com/1014652): Implement TOS with Links. This might require a // separate item. saveCardButtonItem.text = @"TOS Agreement"; - saveCardButtonItem.buttonText = @"Save Credit Card"; + saveCardButtonItem.buttonText = + l10n_util::GetNSString(IDS_IOS_AUTOFILL_SAVE_CARD); saveCardButtonItem.enabled = YES; saveCardButtonItem.disableButtonIntrinsicWidth = YES; [model addItem:saveCardButtonItem
diff --git a/ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.mm b/ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.mm index 5b185127..b02dbef 100644 --- a/ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.mm +++ b/ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.mm
@@ -25,9 +25,14 @@ @implementation InfobarModalPresentationController - (void)presentationTransitionWillBegin { + // Add a gesture recognizer to endEditing (thus hiding the keyboard) if a user + // taps outside the keyboard while one its being presented. Set + // cancelsTouchesInView to NO so the presented Modal can handle the gesture as + // well. (e.g. Selecting a row in a TableViewController.) UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self.presentedView action:@selector(endEditing:)]; + tap.cancelsTouchesInView = NO; [self.containerView addGestureRecognizer:tap]; }
diff --git a/ios/chrome/browser/ui/list_model/BUILD.gn b/ios/chrome/browser/ui/list_model/BUILD.gn index 9b6260b..44f2a899 100644 --- a/ios/chrome/browser/ui/list_model/BUILD.gn +++ b/ios/chrome/browser/ui/list_model/BUILD.gn
@@ -28,7 +28,6 @@ ":list_model", "//base", "//ios/chrome/test:test_support", - "//ios/chrome/test/base", "//testing/gtest", ] }
diff --git a/ios/chrome/browser/ui/main_content/BUILD.gn b/ios/chrome/browser/ui/main_content/BUILD.gn index f996527..a3168782 100644 --- a/ios/chrome/browser/ui/main_content/BUILD.gn +++ b/ios/chrome/browser/ui/main_content/BUILD.gn
@@ -62,7 +62,6 @@ "//ios/chrome/browser/ui/main_content/test", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web_state_list", - "//ios/chrome/test/base", "//ios/web/public/test", "//ios/web/public/test/fakes", "//testing/gtest",
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/shortcuts/BUILD.gn index 115ae4e..0f0ebd0 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/BUILD.gn
@@ -87,7 +87,6 @@ "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant", "//ios/chrome/browser/ui/omnibox:omnibox_popup_shared", "//ios/chrome/test/app:test_support", - "//ios/chrome/test/base:base", "//ios/chrome/test/earl_grey:test_support", "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link", @@ -118,7 +117,6 @@ "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant", "//ios/chrome/browser/ui/omnibox:omnibox_popup_shared", - "//ios/chrome/test/base", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib",
diff --git a/ios/chrome/browser/ui/presenters/BUILD.gn b/ios/chrome/browser/ui/presenters/BUILD.gn index 585e8e5..a167500 100644 --- a/ios/chrome/browser/ui/presenters/BUILD.gn +++ b/ios/chrome/browser/ui/presenters/BUILD.gn
@@ -30,7 +30,6 @@ ":presenters", "//base", "//base/test:test_support", - "//ios/chrome/test/base", "//testing/gtest", ] }
diff --git a/ios/chrome/browser/ui/safe_mode/BUILD.gn b/ios/chrome/browser/ui/safe_mode/BUILD.gn index b2a04a3..e31b7a1 100644 --- a/ios/chrome/browser/ui/safe_mode/BUILD.gn +++ b/ios/chrome/browser/ui/safe_mode/BUILD.gn
@@ -44,8 +44,8 @@ "//ios/chrome/browser/ui/main", "//ios/chrome/browser/ui/util", "//ios/chrome/test/app:test_support", - "//ios/chrome/test/base", "//ios/chrome/test/earl_grey:test_support", + "//ios/testing:block_swizzler", "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link", ] @@ -109,8 +109,8 @@ ":eg_test_support+eg2", "//base:base", "//ios/chrome/app/strings:ios_chromium_strings_grit", - "//ios/chrome/test/base:base", "//ios/chrome/test/earl_grey:eg_test_support+eg2", + "//ios/testing:block_swizzler", "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib", ] @@ -129,8 +129,8 @@ "//base", "//base/test:test_support", "//ios/chrome/browser/crash_report", - "//ios/chrome/test/base", "//ios/chrome/test/ocmock", + "//ios/testing:block_swizzler", "//testing/gtest", "//third_party/breakpad:client", "//third_party/ocmock",
diff --git a/ios/chrome/browser/ui/safe_mode/safe_mode_egtest.mm b/ios/chrome/browser/ui/safe_mode/safe_mode_egtest.mm index 65c7083..ad98f27 100644 --- a/ios/chrome/browser/ui/safe_mode/safe_mode_egtest.mm +++ b/ios/chrome/browser/ui/safe_mode/safe_mode_egtest.mm
@@ -8,7 +8,6 @@ #include "base/mac/foundation_util.h" #include "ios/chrome/browser/ui/safe_mode/safe_mode_app_interface.h" #include "ios/chrome/grit/ios_chromium_strings.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" @@ -16,6 +15,7 @@ #import "ios/chrome/test/earl_grey/earl_grey_scoped_block_swizzler.h" #import "ios/testing/earl_grey/app_launch_manager.h" #import "ios/testing/earl_grey/earl_grey_test.h" +#import "ios/testing/scoped_block_swizzler.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller_unittest.mm b/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller_unittest.mm index 196f9e7a..ec23bb9 100644 --- a/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller_unittest.mm
@@ -6,8 +6,8 @@ #import "base/test/ios/wait_util.h" #import "ios/chrome/browser/crash_report/breakpad_helper.h" #import "ios/chrome/browser/crash_report/main_thread_freeze_detector.h" -#import "ios/chrome/test/base/scoped_block_swizzler.h" #import "ios/chrome/test/ocmock/OCMockObject+BreakpadControllerTesting.h" +#import "ios/testing/scoped_block_swizzler.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #import "third_party/breakpad/breakpad/src/client/ios/BreakpadController.h"
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm index 1458708..3acc0a8 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
@@ -647,6 +647,11 @@ // Checks that deleting a saved password from password details view goes back // to the list-of-passwords view which doesn't display that form anymore. - (void)testSavedFormDeletionInDetailView { + // TODO(crbug.com/1023619): Enable the test on 13.2+ iPad once the bug is + // fixed. + if (base::ios::IsRunningOnOrLater(13, 2, 0) && [ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad and iOS 13.2+"); + } // Save form to be deleted later. SaveExamplePasswordForm(); @@ -698,6 +703,11 @@ // goes back to the list-of-passwords view which doesn't display that form // anymore. - (void)testDuplicatedSavedFormDeletionInDetailView { + // TODO(crbug.com/1023619): Enable the test on 13.2+ iPad once the bug is + // fixed. + if (base::ios::IsRunningOnOrLater(13, 2, 0) && [ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad and iOS 13.2+"); + } // Save form to be deleted later. SaveExamplePasswordForm(); // Save duplicate of the previously saved form to be deleted at the same time. @@ -757,6 +767,11 @@ // Checks that deleting a blacklisted form from password details view goes // back to the list-of-passwords view which doesn't display that form anymore. - (void)testBlacklistedFormDeletionInDetailView { + // TODO(crbug.com/1023619): Enable the test on 13.2+ iPad once the bug is + // fixed. + if (base::ios::IsRunningOnOrLater(13, 2, 0) && [ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad and iOS 13.2+"); + } // Save blacklisted form to be deleted later. PasswordForm blacklisted; blacklisted.origin = GURL("https://blacklisted.com"); @@ -809,6 +824,11 @@ // Checks that deleting a password from password details can be cancelled. - (void)testCancelDeletionInDetailView { + // TODO(crbug.com/1023619): Enable the test on 13.2+ iPad once the bug is + // fixed. + if (base::ios::IsRunningOnOrLater(13, 2, 0) && [ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad and iOS 13.2+"); + } // Save form to be deleted later. SaveExamplePasswordForm(); @@ -1503,6 +1523,11 @@ // Test export flow - (void)testExportFlow { + // TODO(crbug.com/1023619): Enable the test on 13.2+ iPad once the bug is + // fixed. + if (base::ios::IsRunningOnOrLater(13, 2, 0) && [ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad and iOS 13.2+"); + } // Saving a form is needed for exporting passwords. SaveExamplePasswordForm();
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 55768c1..24ba864 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -295,7 +295,6 @@ "//ios/chrome/common:unit_tests", "//ios/chrome/content_widget_extension:unit_tests", "//ios/chrome/search_widget_extension:unit_tests", - "//ios/chrome/test/base:unit_tests", "//ios/testing:http_server_bundle_data", ] if (ios_enable_firebase_sdk) {
diff --git a/ios/chrome/test/base/BUILD.gn b/ios/chrome/test/base/BUILD.gn index 02f8dfe..438c6c1 100644 --- a/ios/chrome/test/base/BUILD.gn +++ b/ios/chrome/test/base/BUILD.gn
@@ -5,25 +5,9 @@ source_set("base") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true - sources = [ - "scoped_block_swizzler.h", - "scoped_block_swizzler.mm", - ] - deps = [ - "//base", - ] -} - -source_set("unit_tests") { - configs += [ "//build/config/compiler:enable_arc" ] - testonly = true - sources = [ - "scoped_block_swizzler_unittest.mm", - ] - deps = [ - ":base", - "//base", - "//testing/gtest", + sources = [] + public_deps = [ + "//ios/testing:block_swizzler", ] }
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 0d3c33c..17b21d2 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -74,7 +74,6 @@ chrome_ios_eg_test("ios_chrome_ui_egtests") { deps = [ "//ios/chrome/browser/ui/activity_services:eg_tests", - "//ios/chrome/browser/ui/alert_coordinator:eg_tests", "//ios/chrome/browser/ui/browser_view:eg_tests", "//ios/chrome/browser/ui/dialogs:eg_tests", "//ios/chrome/browser/ui/download:eg_tests", @@ -282,7 +281,7 @@ "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/test/app:test_support", - "//ios/chrome/test/base", + "//ios/testing:block_swizzler", "//ios/testing:verify_custom_webkit", "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/material_components_ios", @@ -416,7 +415,7 @@ "//ios/chrome/browser/ui/util:eg_app_support+eg2", "//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/test/app:test_support", - "//ios/chrome/test/base", + "//ios/testing:block_swizzler", "//ios/testing:nserror_support", "//ios/testing:verify_custom_webkit", "//ios/testing/earl_grey:eg_app_support+eg2",
diff --git a/ios/chrome/test/earl_grey/earl_grey_scoped_block_swizzler_app_interface.mm b/ios/chrome/test/earl_grey/earl_grey_scoped_block_swizzler_app_interface.mm index 8dc9078..0485885 100644 --- a/ios/chrome/test/earl_grey/earl_grey_scoped_block_swizzler_app_interface.mm +++ b/ios/chrome/test/earl_grey/earl_grey_scoped_block_swizzler_app_interface.mm
@@ -7,7 +7,7 @@ #include <map> #include "base/logging.h" -#include "ios/chrome/test/base/scoped_block_swizzler.h" +#include "ios/testing/scoped_block_swizzler.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/testing/BUILD.gn b/ios/testing/BUILD.gn index acc55d5..296bf38d 100644 --- a/ios/testing/BUILD.gn +++ b/ios/testing/BUILD.gn
@@ -8,7 +8,7 @@ group("all_tests") { testonly = true deps = [ - ":ocmock_support_unittests", + ":ios_testing_unittests", ] } @@ -36,6 +36,18 @@ ] } +source_set("block_swizzler") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + sources = [ + "scoped_block_swizzler.h", + "scoped_block_swizzler.mm", + ] + deps = [ + "//base", + ] +} + source_set("nserror_support") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true @@ -76,9 +88,10 @@ ] } -test("ocmock_support_unittests") { +test("ios_testing_unittests") { configs += [ "//build/config/compiler:enable_arc" ] deps = [ + ":block_swizzler", ":ocmock_support", "//base/test:run_all_unittests", "//base/test:test_support", @@ -89,6 +102,7 @@ sources = [ "ocmock_complex_type_helper_unittest.mm", + "scoped_block_swizzler_unittest.mm", ] assert_no_deps = ios_assert_no_deps
diff --git a/ios/chrome/test/base/scoped_block_swizzler.h b/ios/testing/scoped_block_swizzler.h similarity index 89% rename from ios/chrome/test/base/scoped_block_swizzler.h rename to ios/testing/scoped_block_swizzler.h index ecfea71..c6c0abf7 100644 --- a/ios/chrome/test/base/scoped_block_swizzler.h +++ b/ios/testing/scoped_block_swizzler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#ifndef IOS_CHROME_TEST_BASE_SCOPED_BLOCK_SWIZZLER_H_ -#define IOS_CHROME_TEST_BASE_SCOPED_BLOCK_SWIZZLER_H_ +#ifndef IOS_TESTING_SCOPED_BLOCK_SWIZZLER_H_ +#define IOS_TESTING_SCOPED_BLOCK_SWIZZLER_H_ #include <objc/runtime.h> @@ -37,4 +37,4 @@ DISALLOW_COPY_AND_ASSIGN(ScopedBlockSwizzler); }; -#endif // IOS_CHROME_TEST_BASE_SCOPED_BLOCK_SWIZZLER_H_ +#endif // IOS_TESTING_SCOPED_BLOCK_SWIZZLER_H_
diff --git a/ios/chrome/test/base/scoped_block_swizzler.mm b/ios/testing/scoped_block_swizzler.mm similarity index 93% rename from ios/chrome/test/base/scoped_block_swizzler.mm rename to ios/testing/scoped_block_swizzler.mm index 2f2bee3..998d0de0 100644 --- a/ios/chrome/test/base/scoped_block_swizzler.mm +++ b/ios/testing/scoped_block_swizzler.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/chrome/test/base/scoped_block_swizzler.h" +#include "ios/testing/scoped_block_swizzler.h" #include "base/logging.h"
diff --git a/ios/chrome/test/base/scoped_block_swizzler_unittest.mm b/ios/testing/scoped_block_swizzler_unittest.mm similarity index 97% rename from ios/chrome/test/base/scoped_block_swizzler_unittest.mm rename to ios/testing/scoped_block_swizzler_unittest.mm index 2af049c..2a8524a 100644 --- a/ios/chrome/test/base/scoped_block_swizzler_unittest.mm +++ b/ios/testing/scoped_block_swizzler_unittest.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/chrome/test/base/scoped_block_swizzler.h" +#include "ios/testing/scoped_block_swizzler.h" #include "base/mac/foundation_util.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h"
diff --git a/ios/web/web_view_only/wk_web_view_configuration_util_unittests.mm b/ios/web/web_view_only/wk_web_view_configuration_util_unittests.mm index da65183..566a4699 100644 --- a/ios/web/web_view_only/wk_web_view_configuration_util_unittests.mm +++ b/ios/web/web_view_only/wk_web_view_configuration_util_unittests.mm
@@ -34,4 +34,4 @@ [web_controller() removeWebView]; } -} // namespace +} // namespace web
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_client.h b/ios/web_view/internal/passwords/web_view_password_manager_client.h index 05cc5831..f8bb7e1 100644 --- a/ios/web_view/internal/passwords/web_view_password_manager_client.h +++ b/ios/web_view/internal/passwords/web_view_password_manager_client.h
@@ -115,6 +115,7 @@ scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; bool IsIsolationForPasswordSitesEnabled() const override; bool IsNewTabPage() const override; + password_manager::FieldInfoManager* GetFieldInfoManager() const override; private: __weak id<CWVPasswordManagerClientDelegate> delegate_;
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_client.mm b/ios/web_view/internal/passwords/web_view_password_manager_client.mm index bb28e55..09b7cf0c 100644 --- a/ios/web_view/internal/passwords/web_view_password_manager_client.mm +++ b/ios/web_view/internal/passwords/web_view_password_manager_client.mm
@@ -233,4 +233,9 @@ return false; } +password_manager::FieldInfoManager* +WebViewPasswordManagerClient::GetFieldInfoManager() const { + return nullptr; +} + } // namespace ios_web_view
diff --git a/ipc/ipc_channel_common.cc b/ipc/ipc_channel_common.cc index 7afb12d..3a141172 100644 --- a/ipc/ipc_channel_common.cc +++ b/ipc/ipc_channel_common.cc
@@ -5,6 +5,7 @@ #include "build/build_config.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_channel_mojo.h" +#include "mojo/public/cpp/bindings/lib/message_quota_checker.h" #include "mojo/public/cpp/system/message_pipe.h" namespace IPC { @@ -39,7 +40,8 @@ return ChannelMojo::Create( mojo::ScopedMessagePipeHandle(channel_handle.mojo_handle), Channel::MODE_CLIENT, listener, ipc_task_runner, - base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get(), + mojo::internal::MessageQuotaChecker::MaybeCreate()); #endif } @@ -55,7 +57,8 @@ return ChannelMojo::Create( mojo::ScopedMessagePipeHandle(channel_handle.mojo_handle), Channel::MODE_SERVER, listener, ipc_task_runner, - base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get(), + mojo::internal::MessageQuotaChecker::MaybeCreate()); #endif }
diff --git a/ipc/ipc_channel_factory.cc b/ipc/ipc_channel_factory.cc index 655c0eb..decaf831 100644 --- a/ipc/ipc_channel_factory.cc +++ b/ipc/ipc_channel_factory.cc
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ipc/ipc_channel_factory.h" #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "ipc/ipc_channel_factory.h" #include "ipc/ipc_channel_mojo.h" +#include "mojo/public/cpp/bindings/lib/message_quota_checker.h" namespace IPC { @@ -17,7 +18,10 @@ ChannelHandle handle, Channel::Mode mode, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) - : handle_(handle), mode_(mode), ipc_task_runner_(ipc_task_runner) {} + : handle_(handle), + mode_(mode), + ipc_task_runner_(ipc_task_runner), + quota_checker_(mojo::internal::MessageQuotaChecker::MaybeCreate()) {} std::unique_ptr<Channel> BuildChannel(Listener* listener) override { #if defined(OS_NACL_SFI) @@ -26,7 +30,7 @@ DCHECK(handle_.is_mojo_channel_handle()); return ChannelMojo::Create( mojo::ScopedMessagePipeHandle(handle_.mojo_handle), mode_, listener, - ipc_task_runner_, base::ThreadTaskRunnerHandle::Get()); + ipc_task_runner_, base::ThreadTaskRunnerHandle::Get(), quota_checker_); #endif } @@ -34,10 +38,16 @@ return ipc_task_runner_; } + scoped_refptr<mojo::internal::MessageQuotaChecker> GetQuotaChecker() + override { + return quota_checker_; + } + private: ChannelHandle handle_; Channel::Mode mode_; scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_; + scoped_refptr<mojo::internal::MessageQuotaChecker> quota_checker_; DISALLOW_COPY_AND_ASSIGN(PlatformChannelFactory); };
diff --git a/ipc/ipc_channel_factory.h b/ipc/ipc_channel_factory.h index 03d9626..8051cba 100644 --- a/ipc/ipc_channel_factory.h +++ b/ipc/ipc_channel_factory.h
@@ -14,6 +14,12 @@ #include "base/single_thread_task_runner.h" #include "ipc/ipc_channel.h" +namespace mojo { +namespace internal { +class MessageQuotaChecker; +} // namespace internal +} // namespace mojo + namespace IPC { // Encapsulates how a Channel is created. A ChannelFactory can be @@ -31,6 +37,8 @@ virtual ~ChannelFactory() { } virtual std::unique_ptr<Channel> BuildChannel(Listener* listener) = 0; virtual scoped_refptr<base::SingleThreadTaskRunner> GetIPCTaskRunner() = 0; + virtual scoped_refptr<mojo::internal::MessageQuotaChecker> + GetQuotaChecker() = 0; }; } // namespace IPC
diff --git a/ipc/ipc_channel_mojo.cc b/ipc/ipc_channel_mojo.cc index 6e34266f..0affc26 100644 --- a/ipc/ipc_channel_mojo.cc +++ b/ipc/ipc_channel_mojo.cc
@@ -27,6 +27,7 @@ #include "ipc/ipc_mojo_handle_attachment.h" #include "ipc/native_handle_type_converters.h" #include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/lib/message_quota_checker.h" #include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "mojo/public/cpp/system/platform_handle.h" @@ -44,22 +45,30 @@ : handle_(std::move(handle)), mode_(mode), ipc_task_runner_(ipc_task_runner), - proxy_task_runner_(proxy_task_runner) {} + proxy_task_runner_(proxy_task_runner), + quota_checker_(mojo::internal::MessageQuotaChecker::MaybeCreate()) {} std::unique_ptr<Channel> BuildChannel(Listener* listener) override { return ChannelMojo::Create(std::move(handle_), mode_, listener, - ipc_task_runner_, proxy_task_runner_); + ipc_task_runner_, proxy_task_runner_, + quota_checker_); } scoped_refptr<base::SingleThreadTaskRunner> GetIPCTaskRunner() override { return ipc_task_runner_; } + scoped_refptr<mojo::internal::MessageQuotaChecker> GetQuotaChecker() + override { + return quota_checker_; + } + private: mojo::ScopedMessagePipeHandle handle_; const Channel::Mode mode_; scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner_; + scoped_refptr<mojo::internal::MessageQuotaChecker> quota_checker_; DISALLOW_COPY_AND_ASSIGN(MojoChannelFactory); }; @@ -86,9 +95,11 @@ Mode mode, Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, - const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner) { + const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner, + const scoped_refptr<mojo::internal::MessageQuotaChecker>& quota_checker) { return base::WrapUnique(new ChannelMojo(std::move(handle), mode, listener, - ipc_task_runner, proxy_task_runner)); + ipc_task_runner, proxy_task_runner, + quota_checker)); } // static @@ -116,11 +127,12 @@ Mode mode, Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, - const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner) + const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner, + const scoped_refptr<mojo::internal::MessageQuotaChecker>& quota_checker) : task_runner_(ipc_task_runner), pipe_(handle.get()), listener_(listener) { weak_ptr_ = weak_factory_.GetWeakPtr(); bootstrap_ = MojoBootstrap::Create(std::move(handle), mode, ipc_task_runner, - proxy_task_runner); + proxy_task_runner, quota_checker); } void ChannelMojo::ForwardMessageFromThreadSafePtr(mojo::Message message) {
diff --git a/ipc/ipc_channel_mojo.h b/ipc/ipc_channel_mojo.h index 3445708..49ba1a8 100644 --- a/ipc/ipc_channel_mojo.h +++ b/ipc/ipc_channel_mojo.h
@@ -51,7 +51,8 @@ Mode mode, Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, - const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner); + const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner, + const scoped_refptr<mojo::internal::MessageQuotaChecker>& quota_checker); // Create a factory object for ChannelMojo. // The factory is used to create Mojo-based ChannelProxy family. @@ -101,7 +102,8 @@ Mode mode, Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, - const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner); + const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner, + const scoped_refptr<mojo::internal::MessageQuotaChecker>& quota_checker); void ForwardMessageFromThreadSafePtr(mojo::Message message); void ForwardMessageWithResponderFromThreadSafePtr(
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc index 54179c0..8b7729b 100644 --- a/ipc/ipc_channel_proxy.cc +++ b/ipc/ipc_channel_proxy.cc
@@ -224,6 +224,9 @@ // Called on the IPC::Channel thread void ChannelProxy::Context::OnSendMessage(std::unique_ptr<Message> message) { + if (quota_checker_) + quota_checker_->AfterMessagesDequeued(1); + if (!channel_) { OnChannelClosed(); return; @@ -419,6 +422,9 @@ } void ChannelProxy::Context::Send(Message* message) { + if (quota_checker_) + quota_checker_->BeforeMessagesEnqueued(1); + ipc_task_runner()->PostTask( FROM_HERE, base::BindOnce(&ChannelProxy::Context::OnSendMessage, this, base::WrapUnique(message))); @@ -497,6 +503,9 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!did_init_); + DCHECK(!context_->quota_checker_); + context_->quota_checker_ = factory->GetQuotaChecker(); + if (create_pipe_now) { // Create the channel immediately. This effectively sets up the // low-level pipe so that the client can connect. Without creating
diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h index 1260761..ab1d8d3c 100644 --- a/ipc/ipc_channel_proxy.h +++ b/ipc/ipc_channel_proxy.h
@@ -27,6 +27,7 @@ #include "mojo/public/cpp/bindings/associated_interface_ptr.h" #include "mojo/public/cpp/bindings/associated_interface_request.h" #include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/lib/message_quota_checker.h" #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" #include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h" @@ -376,6 +377,9 @@ std::unique_ptr<Channel> channel_; bool channel_connected_called_; + // The quota checker associated with this channel, if any. + scoped_refptr<mojo::internal::MessageQuotaChecker> quota_checker_; + // Lock for |channel_| value. This is only relevant in the context of // thread-safe send. base::Lock channel_lifetime_lock_;
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc index 39d29dd..47cd62ef 100644 --- a/ipc/ipc_mojo_bootstrap.cc +++ b/ipc/ipc_mojo_bootstrap.cc
@@ -120,9 +120,11 @@ ChannelAssociatedGroupController( bool set_interface_id_namespace_bit, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, - const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner) + const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner, + const scoped_refptr<mojo::internal::MessageQuotaChecker>& quota_checker) : task_runner_(ipc_task_runner), proxy_task_runner_(proxy_task_runner), + quota_checker_(quota_checker), set_interface_id_namespace_bit_(set_interface_id_namespace_bit), dispatcher_(this), control_message_handler_(this), @@ -172,6 +174,8 @@ base::Unretained(this))); connector_->set_enforce_errors_from_incoming_receiver(false); connector_->SetWatcherHeapProfilerTag("IPC Channel"); + if (quota_checker_) + connector_->SetMessageQuotaChecker(quota_checker_); // Don't let the Connector do any sort of queuing on our behalf. Individual // messages bound for the IPC::ChannelProxy thread (i.e. that vast majority @@ -198,6 +202,9 @@ base::AutoLock lock(outgoing_messages_lock_); std::swap(outgoing_messages, outgoing_messages_); } + if (quota_checker_ && outgoing_messages.size()) + quota_checker_->AfterMessagesDequeued(outgoing_messages.size()); + for (auto& message : outgoing_messages) SendMessage(&message); } @@ -243,6 +250,9 @@ connector_.reset(); base::AutoLock lock(outgoing_messages_lock_); + if (quota_checker_ && outgoing_messages_.size()) + quota_checker_->AfterMessagesDequeued(outgoing_messages_.size()); + outgoing_messages_.clear(); } @@ -706,6 +716,8 @@ if (!connector_ || paused_) { if (!shut_down_) { base::AutoLock lock(outgoing_messages_lock_); + if (quota_checker_) + quota_checker_->BeforeMessagesEnqueued(1); outgoing_messages_.emplace_back(std::move(*message)); } return true; @@ -983,6 +995,7 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner_; + const scoped_refptr<mojo::internal::MessageQuotaChecker> quota_checker_; const bool set_interface_id_namespace_bit_; bool paused_ = false; std::unique_ptr<mojo::Connector> connector_; @@ -1100,11 +1113,12 @@ mojo::ScopedMessagePipeHandle handle, Channel::Mode mode, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, - const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner) { + const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner, + const scoped_refptr<mojo::internal::MessageQuotaChecker>& quota_checker) { return std::make_unique<MojoBootstrapImpl>( - std::move(handle), - new ChannelAssociatedGroupController(mode == Channel::MODE_SERVER, - ipc_task_runner, proxy_task_runner)); + std::move(handle), new ChannelAssociatedGroupController( + mode == Channel::MODE_SERVER, ipc_task_runner, + proxy_task_runner, quota_checker)); } } // namespace IPC
diff --git a/ipc/ipc_mojo_bootstrap.h b/ipc/ipc_mojo_bootstrap.h index 89262846..d231ab2c 100644 --- a/ipc/ipc_mojo_bootstrap.h +++ b/ipc/ipc_mojo_bootstrap.h
@@ -19,6 +19,7 @@ #include "ipc/ipc_listener.h" #include "mojo/public/cpp/bindings/associated_group.h" #include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/lib/message_quota_checker.h" #include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "mojo/public/cpp/system/message_pipe.h" @@ -42,7 +43,8 @@ mojo::ScopedMessagePipeHandle handle, Channel::Mode mode, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, - const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner); + const scoped_refptr<base::SingleThreadTaskRunner>& proxy_task_runner, + const scoped_refptr<mojo::internal::MessageQuotaChecker>& quota_checker); // Start the handshake over the underlying message pipe. virtual void Connect(
diff --git a/ipc/ipc_mojo_bootstrap_unittest.cc b/ipc/ipc_mojo_bootstrap_unittest.cc index 2b6dd97..d91d475 100644 --- a/ipc/ipc_mojo_bootstrap_unittest.cc +++ b/ipc/ipc_mojo_bootstrap_unittest.cc
@@ -113,7 +113,7 @@ IPC::MojoBootstrap::Create( helper_.StartChild("IPCMojoBootstrapTestClient"), IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get()), + base::ThreadTaskRunnerHandle::Get(), nullptr), kTestServerPid); mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver; @@ -138,7 +138,7 @@ IPC::MojoBootstrap::Create( std::move(mojo::core::test::MultiprocessTestHelper::primordial_pipe), IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get()), + base::ThreadTaskRunnerHandle::Get(), nullptr), kTestClientPid); mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver; @@ -159,7 +159,7 @@ IPC::MojoBootstrap::Create( helper_.StartChild("IPCMojoBootstrapTestEmptyMessage"), IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get()), + base::ThreadTaskRunnerHandle::Get(), nullptr), kTestServerPid); mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver; @@ -186,7 +186,7 @@ IPC::MojoBootstrap::Create( std::move(mojo::core::test::MultiprocessTestHelper::primordial_pipe), IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get()), + base::ThreadTaskRunnerHandle::Get(), nullptr), kTestClientPid); mojo::PendingAssociatedReceiver<IPC::mojom::Channel> receiver;
diff --git a/ipc/ipc_test_base.cc b/ipc/ipc_test_base.cc index 4194194..2030cb7 100644 --- a/ipc/ipc_test_base.cc +++ b/ipc/ipc_test_base.cc
@@ -38,9 +38,10 @@ } void IPCChannelMojoTestBase::CreateChannel(IPC::Listener* listener) { - channel_ = IPC::ChannelMojo::Create( - TakeHandle(), IPC::Channel::MODE_SERVER, listener, - base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get()); + channel_ = + IPC::ChannelMojo::Create(TakeHandle(), IPC::Channel::MODE_SERVER, + listener, base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), nullptr); } bool IPCChannelMojoTestBase::ConnectChannel() { @@ -64,9 +65,10 @@ } void IpcChannelMojoTestClient::Connect(IPC::Listener* listener) { - channel_ = IPC::ChannelMojo::Create( - std::move(handle_), IPC::Channel::MODE_CLIENT, listener, - base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get()); + channel_ = + IPC::ChannelMojo::Create(std::move(handle_), IPC::Channel::MODE_CLIENT, + listener, base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), nullptr); CHECK(channel_->Connect()); }
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn index 2c44d3b..7682756e 100644 --- a/mojo/public/cpp/bindings/BUILD.gn +++ b/mojo/public/cpp/bindings/BUILD.gn
@@ -160,6 +160,8 @@ "lib/interface_ptr_state.h", "lib/interface_serialization.h", "lib/message_dispatcher.cc", + "lib/message_quota_checker.cc", + "lib/message_quota_checker.h", "lib/multiplex_router.cc", "lib/multiplex_router.h", "lib/native_enum_data.h",
diff --git a/mojo/public/cpp/bindings/connector.h b/mojo/public/cpp/bindings/connector.h index 761f06e7..03e6e68b 100644 --- a/mojo/public/cpp/bindings/connector.h +++ b/mojo/public/cpp/bindings/connector.h
@@ -18,7 +18,6 @@ #include "base/optional.h" #include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" -#include "mojo/public/c/system/quota.h" #include "mojo/public/cpp/bindings/connection_group.h" #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/sequence_local_sync_event_watcher.h" @@ -32,6 +31,9 @@ } namespace mojo { +namespace internal { +class MessageQuotaChecker; +} // The Connector class is responsible for performing read/write operations on a // MessagePipe. It writes messages it receives through the MessageReceiver @@ -197,6 +199,10 @@ // |tag| must be a const string literal. void SetWatcherHeapProfilerTag(const char* tag); + // Sets the quota checker. + void SetMessageQuotaChecker( + scoped_refptr<internal::MessageQuotaChecker> checker); + // Allows testing environments to override the default serialization behavior // of newly constructed Connector instances. Must be called before any // Connector instances are constructed. @@ -315,10 +321,8 @@ SEQUENCE_CHECKER(sequence_checker_); - // If this instance was selected for unread message measurement, contains - // the max send quota usage seen so far. If this instance was not selected - // contains MOJO_QUOTA_LIMIT_NONE as a sentinel value. - uint64_t max_unread_message_quota_used_ = MOJO_QUOTA_LIMIT_NONE; + // The quota checker associate with this connector, if any. + scoped_refptr<internal::MessageQuotaChecker> quota_checker_; base::Lock connected_lock_; bool connected_ = true;
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc index 5f77d2d..c9e84c9 100644 --- a/mojo/public/cpp/bindings/lib/connector.cc +++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -8,8 +8,6 @@ #include "base/bind.h" #include "base/compiler_specific.h" -#include "base/debug/alias.h" -#include "base/debug/dump_without_crashing.h" #include "base/location.h" #include "base/logging.h" #include "base/macros.h" @@ -23,8 +21,10 @@ #include "base/synchronization/lock.h" #include "base/threading/sequence_local_storage_slot.h" #include "base/trace_event/trace_event.h" +#include "mojo/public/c/system/quota.h" #include "mojo/public/cpp/bindings/features.h" #include "mojo/public/cpp/bindings/lib/may_auto_lock.h" +#include "mojo/public/cpp/bindings/lib/message_quota_checker.h" #include "mojo/public/cpp/bindings/lib/tracing_helper.h" #include "mojo/public/cpp/bindings/mojo_buildflags.h" #include "mojo/public/cpp/bindings/sync_handle_watcher.h" @@ -56,62 +56,6 @@ return enable; } -const base::FeatureParam<int> kMojoRecordUnreadMessageCountSampleRate = { - &features::kMojoRecordUnreadMessageCount, "SampleRate", - 100 // Sample 1% of Connectors by default. -}; - -const base::FeatureParam<int> kMojoRecordUnreadMessageCountQuotaValue = { - &features::kMojoRecordUnreadMessageCount, "QuotaValue", - 100 // Use a 100 message quote by default. -}; - -const base::FeatureParam<int> kMojoRecordUnreadMessageCountCrashThreshold = { - &features::kMojoRecordUnreadMessageCount, "CrashThreshold", - 0 // Set to zero to disable crash dumps by default. -}; - -int UnreadMessageCountQuota() { - static const bool enabled = - base::FeatureList::IsEnabled(features::kMojoRecordUnreadMessageCount); - if (!enabled) - return 0; - - static const int sample_rate = kMojoRecordUnreadMessageCountSampleRate.Get(); - if (base::RandInt(0, sample_rate - 1) != 0) - return 0; - - static const int quota = kMojoRecordUnreadMessageCountQuotaValue.Get(); - return quota; -} - -// Disable inlining for this function to make sure it appears in the stack -// trace on crash. -NOINLINE void MaybeDumpWithoutCrashing(int quota_used) { - static const int crash_threshold = - kMojoRecordUnreadMessageCountCrashThreshold.Get(); - if (crash_threshold == 0 || quota_used < crash_threshold) - return; - - static bool have_crashed = false; - if (have_crashed) - return; - - // Only crash once per process/per run. Note that this is slightly racy - // against concurrent quota overruns on multiple threads, but that's fine. - have_crashed = true; - - // This is happening because the user of the interface implicated on the crash - // stack has queued up an unreasonable number of messages, namely - // |quota_used|. - base::debug::DumpWithoutCrashing(); - - // Defeat tail-call optimization and ensure these two variables are available - // on the stack. - base::debug::Alias(&crash_threshold); - base::debug::Alias("a_used); -} - } // namespace // Used to efficiently maintain a doubly-linked list of all Connectors @@ -220,25 +164,14 @@ // Even though we don't have an incoming receiver, we still want to monitor // the message pipe to know if is closed or encounters an error. WaitToReadMore(); - - int unread_message_count_quota = UnreadMessageCountQuota(); - if (unread_message_count_quota != 0) { - // This connector has been sampled to record the max unread message count. - // Note that setting the quota to N results in over-counting usage by up to - // N/2, in addition to overcounting due to message transit delays. As result - // it's best to treat the resulting metric as N-granular. - MojoResult rv = MojoSetQuota(message_pipe_.get().value(), - MOJO_QUOTA_TYPE_UNREAD_MESSAGE_COUNT, - unread_message_count_quota, nullptr); - if (rv == MOJO_RESULT_OK) - max_unread_message_quota_used_ = 0U; - } } Connector::~Connector() { - if (max_unread_message_quota_used_ != MOJO_QUOTA_LIMIT_NONE) { + if (quota_checker_) { + // Clear the message pipe handle in the checker. + quota_checker_->SetMessagePipe(MessagePipeHandle()); UMA_HISTOGRAM_COUNTS_1M("Mojo.Connector.MaxUnreadMessageQuotaUsed", - max_unread_message_quota_used_); + quota_checker_->GetMaxQuotaUsage()); } { @@ -393,17 +326,9 @@ DCHECK(dump_result); } #endif - if (max_unread_message_quota_used_ != MOJO_QUOTA_LIMIT_NONE) { - uint64_t limit = 0; - uint64_t usage = 0; - MojoResult rv = MojoQueryQuota(message_pipe_.get().value(), - MOJO_QUOTA_TYPE_UNREAD_MESSAGE_COUNT, - nullptr, &limit, &usage); - if (rv == MOJO_RESULT_OK && usage > max_unread_message_quota_used_) { - MaybeDumpWithoutCrashing(usage); - max_unread_message_quota_used_ = usage; - } - } + + if (quota_checker_) + quota_checker_->BeforeWrite(); MojoResult rv = WriteMessageNew(message_pipe_.get(), message->TakeMojoMessage(), @@ -458,6 +383,14 @@ } } +void Connector::SetMessageQuotaChecker( + scoped_refptr<internal::MessageQuotaChecker> checker) { + DCHECK(checker && !quota_checker_); + + quota_checker_ = std::move(checker); + quota_checker_->SetMessagePipe(message_pipe_.get()); +} + // static void Connector::OverrideDefaultSerializationBehaviorForTesting( OutgoingSerializationMode outgoing_mode,
diff --git a/mojo/public/cpp/bindings/lib/message_quota_checker.cc b/mojo/public/cpp/bindings/lib/message_quota_checker.cc new file mode 100644 index 0000000..f276506 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/message_quota_checker.cc
@@ -0,0 +1,192 @@ +// 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 "mojo/public/cpp/bindings/lib/message_quota_checker.h" + +#include <algorithm> + +#include "base/debug/alias.h" +#include "base/debug/dump_without_crashing.h" +#include "base/logging.h" +#include "base/metrics/field_trial_params.h" +#include "base/no_destructor.h" +#include "base/rand_util.h" +#include "base/synchronization/lock.h" +#include "mojo/public/c/system/quota.h" +#include "mojo/public/cpp/bindings/features.h" +#include "mojo/public/cpp/bindings/mojo_buildflags.h" + +namespace mojo { +namespace internal { +namespace { + +const base::FeatureParam<int> kMojoRecordUnreadMessageCountSampleRate = { + &features::kMojoRecordUnreadMessageCount, "SampleRate", + 100 // Sample 1% of Connectors by default. */ +}; + +const base::FeatureParam<int> kMojoRecordUnreadMessageCountQuotaValue = { + &features::kMojoRecordUnreadMessageCount, "QuotaValue", + 100 // Use a 100 message quote by default. +}; + +const base::FeatureParam<int> kMojoRecordUnreadMessageCountCrashThreshold = { + &features::kMojoRecordUnreadMessageCount, "CrashThreshold", + 0 // Set to zero to disable crash dumps by default. +}; + +NOINLINE void MaybeDumpWithoutCrashing(size_t quota_used) { + static bool have_crashed = false; + if (have_crashed) + return; + + // Only crash once per process/per run. Note that this is slightly racy + // against concurrent quota overruns on multiple threads, but that's fine. + have_crashed = true; + + // This is happening because the user of the interface implicated on the crash + // stack has queued up an unreasonable number of messages, namely + // |quota_used|. + base::debug::DumpWithoutCrashing(); + + base::debug::Alias("a_used); +} + +} // namespace + +// static +scoped_refptr<MessageQuotaChecker> MessageQuotaChecker::MaybeCreate() { + static const Configuration config = GetConfiguration(); + return MaybeCreateImpl(config); +} + +void MessageQuotaChecker::BeforeWrite() { + QuotaCheckImpl(0u); +} + +void MessageQuotaChecker::BeforeMessagesEnqueued(size_t num) { + DCHECK_NE(num, 0u); + QuotaCheckImpl(num); +} + +void MessageQuotaChecker::AfterMessagesDequeued(size_t num) { + base::AutoLock hold(lock_); + DCHECK_LE(num, consumed_quota_); + DCHECK_NE(num, 0u); + + consumed_quota_ -= num; +} + +size_t MessageQuotaChecker::GetMaxQuotaUsage() { + base::AutoLock hold(lock_); + return max_consumed_quota_; +} + +void MessageQuotaChecker::SetMessagePipe(MessagePipeHandle message_pipe) { + base::AutoLock hold(lock_); + message_pipe_ = message_pipe; + if (!message_pipe_) + return; + + MojoResult rv = + MojoSetQuota(message_pipe.value(), MOJO_QUOTA_TYPE_UNREAD_MESSAGE_COUNT, + config_->unread_message_count_quota, nullptr); + DCHECK_EQ(MOJO_RESULT_OK, rv); +} + +size_t MessageQuotaChecker::GetCurrentQuotaStatusForTesting() { + base::AutoLock hold(lock_); + return GetCurrentQuotaStatus(); +} + +// static +MessageQuotaChecker::Configuration +MessageQuotaChecker::GetConfigurationForTesting() { + return GetConfiguration(); +} + +// static +scoped_refptr<MessageQuotaChecker> MessageQuotaChecker::MaybeCreateForTesting( + const Configuration& config) { + return MaybeCreateImpl(config); +} + +MessageQuotaChecker::MessageQuotaChecker(const Configuration* config) + : config_(config) {} +MessageQuotaChecker::~MessageQuotaChecker() = default; + +// static +MessageQuotaChecker::Configuration MessageQuotaChecker::GetConfiguration() { + Configuration ret; + + ret.is_enabled = + base::FeatureList::IsEnabled(features::kMojoRecordUnreadMessageCount); + ret.sample_rate = kMojoRecordUnreadMessageCountSampleRate.Get(); + + // Lower-bound the quota value to 100, which implies roughly 2% message + // overhead for sampled pipes. + constexpr int kMinQuotaValue = 100; + ret.unread_message_count_quota = + std::max(kMinQuotaValue, kMojoRecordUnreadMessageCountQuotaValue.Get()); + ret.crash_threshold = kMojoRecordUnreadMessageCountCrashThreshold.Get(); + ret.maybe_crash_function = &MaybeDumpWithoutCrashing; + return ret; +} + +// static +scoped_refptr<MessageQuotaChecker> MessageQuotaChecker::MaybeCreateImpl( + const Configuration& config) { + if (!config.is_enabled) + return nullptr; + + if (base::RandInt(0, config.sample_rate - 1) != 0) + return nullptr; + + return new MessageQuotaChecker(&config); +} + +size_t MessageQuotaChecker::GetCurrentQuotaStatus() { + lock_.AssertAcquired(); + + size_t quota_status = consumed_quota_; + if (message_pipe_) { + uint64_t limit = 0; + uint64_t usage = 0; + MojoResult rv = MojoQueryQuota(message_pipe_.value(), + MOJO_QUOTA_TYPE_UNREAD_MESSAGE_COUNT, + nullptr, &limit, &usage); + if (rv == MOJO_RESULT_OK) + quota_status += usage; + } + + return quota_status; +} + +void MessageQuotaChecker::QuotaCheckImpl(size_t num_enqueued) { + bool new_max = false; + size_t quota_used = 0u; + { + base::AutoLock hold(lock_); + + consumed_quota_ += num_enqueued; + quota_used = GetCurrentQuotaStatus(); + + // Account for the message that will be written. + if (!num_enqueued) + ++quota_used; + + if (quota_used > max_consumed_quota_) { + max_consumed_quota_ = quota_used; + new_max = true; + } + } + + if (new_max && config_->crash_threshold != 0 && + quota_used >= config_->crash_threshold) { + config_->maybe_crash_function(quota_used); + } +} + +} // namespace internal +} // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/message_quota_checker.h b/mojo/public/cpp/bindings/lib/message_quota_checker.h new file mode 100644 index 0000000..499aeed --- /dev/null +++ b/mojo/public/cpp/bindings/lib/message_quota_checker.h
@@ -0,0 +1,103 @@ +// 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 MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_QUOTA_CHECKER_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_QUOTA_CHECKER_H_ + +#include <stdint.h> + +#include "base/component_export.h" +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "mojo/public/cpp/system/message_pipe.h" + +namespace mojo { +namespace internal { + +// This class keeps track of how many messages are in-flight for a message pipe, +// including messages that are posted or locally queued. +// +// Message pipe owners may have reason to implement their own mechanism for +// queuing outgoing messages before writing them to a pipe. This class helps +// with unread message quota monitoring in such cases, since Mojo's own +// quota monitoring on the pipe cannot account for such external queues. +// Callers are responsible for invoking |BeforeMessagesEnqueued()| and +// |AfterMessagesDequeued()| when making respective changes to their local +// outgoing queue. Additionally, |BeforeWrite()| should be called immediately +// before writing each message to the corresponding message pipe. +// +// Also note that messages posted to a different sequence with +// |base::PostTask()| and the like, need to be treated as locally queued. Task +// queues can grow arbitrarily long, and it's ideal to perform unread quota +// checks before posting. +// +// Either |BeforeMessagesEnqueued()| or |BeforeWrite()| may cause the quota +// to be exceeded, thus invoking the |maybe_crash_function| set in this +// object's Configuration. +class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) MessageQuotaChecker + : public base::RefCountedThreadSafe<MessageQuotaChecker> { + public: + // Returns a new instance if this invocation has been sampled for quota + // checking. + static scoped_refptr<MessageQuotaChecker> MaybeCreate(); + + // Call before writing a message to |message_pipe_|. + void BeforeWrite(); + + // Call before queueing |num| messages. + void BeforeMessagesEnqueued(size_t num); + // Call after de-queueing |num| messages. + void AfterMessagesDequeued(size_t num); + + // Returns the high watermark of quota usage observed by this instance. + size_t GetMaxQuotaUsage(); + + // Set or unset the message pipe associated with this quota checker. + void SetMessagePipe(MessagePipeHandle message_pipe); + + // Test support. + size_t GetCurrentQuotaStatusForTesting(); + struct Configuration; + static Configuration GetConfigurationForTesting(); + static scoped_refptr<MessageQuotaChecker> MaybeCreateForTesting( + const Configuration& config); + + private: + friend class base::RefCountedThreadSafe<MessageQuotaChecker>; + explicit MessageQuotaChecker(const Configuration* config); + ~MessageQuotaChecker(); + static Configuration GetConfiguration(); + static scoped_refptr<MessageQuotaChecker> MaybeCreateImpl( + const Configuration& config); + + size_t GetCurrentQuotaStatus(); + void QuotaCheckImpl(size_t num_enqueued); + + const Configuration* config_; + + // Locks all local state. + base::Lock lock_; + // The locally consumed quota, e.g. the difference between the counts passed + // to |BeforeMessagesEnqueued()| and |BeforeMessagesDequeued()|. + size_t consumed_quota_ = 0u; + // The high watermark consumed quota observed. + size_t max_consumed_quota_ = 0u; + // The quota level that triggers a crash dump, or zero to disable crashing. + size_t crash_threshold_ = 0u; + // The message pipe this instance observes, if any. + MessagePipeHandle message_pipe_; +}; + +struct MessageQuotaChecker::Configuration { + bool is_enabled = false; + size_t sample_rate = 0u; + size_t unread_message_count_quota = 0u; + size_t crash_threshold = 0u; + void (*maybe_crash_function)(size_t quota_used); +}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_QUOTA_CHECKER_H_
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc index c87cacc..7420cade 100644 --- a/mojo/public/cpp/bindings/lib/multiplex_router.cc +++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -18,6 +18,7 @@ #include "mojo/public/cpp/bindings/interface_endpoint_client.h" #include "mojo/public/cpp/bindings/interface_endpoint_controller.h" #include "mojo/public/cpp/bindings/lib/may_auto_lock.h" +#include "mojo/public/cpp/bindings/lib/message_quota_checker.h" #include "mojo/public/cpp/bindings/sequence_local_sync_event_watcher.h" namespace mojo { @@ -313,9 +314,9 @@ MultiplexRouter::MultiplexRouter( ScopedMessagePipeHandle message_pipe, Config config, - bool set_interface_id_namesapce_bit, + bool set_interface_id_namespace_bit, scoped_refptr<base::SequencedTaskRunner> runner) - : set_interface_id_namespace_bit_(set_interface_id_namesapce_bit), + : set_interface_id_namespace_bit_(set_interface_id_namespace_bit), task_runner_(runner), dispatcher_(this), connector_(std::move(message_pipe), @@ -342,6 +343,11 @@ base::BindOnce(&MultiplexRouter::OnPipeConnectionError, base::Unretained(this), false /* force_async_dispatch */)); + scoped_refptr<internal::MessageQuotaChecker> quota_checker = + internal::MessageQuotaChecker::MaybeCreate(); + if (quota_checker) + connector_.SetMessageQuotaChecker(std::move(quota_checker)); + std::unique_ptr<MessageHeaderValidator> header_validator = std::make_unique<MessageHeaderValidator>(); header_validator_ = header_validator.get();
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn index 4c2588b..34203da 100644 --- a/mojo/public/cpp/bindings/tests/BUILD.gn +++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -29,6 +29,7 @@ "map_unittest.cc", "message_queue.cc", "message_queue.h", + "message_quota_checker_unittest.cc", "message_unittest.cc", "multiplex_router_unittest.cc", "native_struct_unittest.cc",
diff --git a/mojo/public/cpp/bindings/tests/message_quota_checker_unittest.cc b/mojo/public/cpp/bindings/tests/message_quota_checker_unittest.cc new file mode 100644 index 0000000..fd68005 --- /dev/null +++ b/mojo/public/cpp/bindings/tests/message_quota_checker_unittest.cc
@@ -0,0 +1,189 @@ +// 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 "mojo/public/cpp/bindings/lib/message_quota_checker.h" + +#include "base/test/scoped_feature_list.h" +#include "mojo/public/c/system/quota.h" +#include "mojo/public/cpp/bindings/features.h" +#include "mojo/public/cpp/system/message_pipe.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { +namespace test { +namespace { + +class MessageQuotaCheckerTest : public testing::Test { + public: + MessageQuotaCheckerTest() { + EXPECT_EQ(nullptr, instance_); + instance_ = this; + } + ~MessageQuotaCheckerTest() override { + EXPECT_EQ(this, instance_); + instance_ = nullptr; + } + + protected: + using MessageQuotaChecker = internal::MessageQuotaChecker; + using Configuration = MessageQuotaChecker::Configuration; + + static void RecordDumpAttempt(size_t quota_used) { + ++instance_->num_dumps_; + instance_->last_dump_quota_used_ = quota_used; + } + + size_t num_dumps_ = false; + size_t last_dump_quota_used_ = 0u; + + static const Configuration enabled_config_; + + static MessageQuotaCheckerTest* instance_; +}; + +const MessageQuotaCheckerTest::Configuration + MessageQuotaCheckerTest::enabled_config_ = {true, 1, 100, 200, + &RecordDumpAttempt}; +MessageQuotaCheckerTest* MessageQuotaCheckerTest::instance_ = nullptr; + +TEST_F(MessageQuotaCheckerTest, ReadsConfigurationFromFeatures) { + base::FieldTrialParams params; + params["SampleRate"] = "19"; + // Quota value parameter below the minimum the checker will allow. + params["QuotaValue"] = "57"; + params["CrashThreshold"] = "225"; + + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeatureWithParameters( + features::kMojoRecordUnreadMessageCount, params); + + // Validate that the configuration reads from the feature configuration. + const MessageQuotaChecker::Configuration config = + MessageQuotaChecker::GetConfigurationForTesting(); + + EXPECT_TRUE(config.is_enabled); + EXPECT_EQ(19u, config.sample_rate); + EXPECT_EQ(100u, config.unread_message_count_quota); + EXPECT_EQ(225u, config.crash_threshold); + EXPECT_NE(nullptr, config.maybe_crash_function); +} + +TEST_F(MessageQuotaCheckerTest, DisabledByDefault) { + const MessageQuotaChecker::Configuration config = + MessageQuotaChecker::GetConfigurationForTesting(); + EXPECT_FALSE(config.is_enabled); + + // Validate that no MessageQuoteCheckers are created in the default feature + // configuration. Run a bunch of iterations, as this function returns an + // instance randomly. + for (size_t i = 0; i < 1000; ++i) + ASSERT_EQ(nullptr, MessageQuotaChecker::MaybeCreate()); +} + +TEST_F(MessageQuotaCheckerTest, CreatesWhenEnabled) { + // Run a bunch of iterations, as this function returns an instance randomly. + for (size_t i = 0; i < 1000; ++i) + EXPECT_NE(nullptr, + MessageQuotaChecker::MaybeCreateForTesting(enabled_config_)); +} + +TEST_F(MessageQuotaCheckerTest, CountsRight) { + scoped_refptr<MessageQuotaChecker> checker = + MessageQuotaChecker::MaybeCreateForTesting(enabled_config_); + + ASSERT_EQ(0u, checker->GetCurrentQuotaStatusForTesting()); + ASSERT_EQ(0u, checker->GetMaxQuotaUsage()); + + checker->BeforeMessagesEnqueued(10); + ASSERT_EQ(10u, checker->GetCurrentQuotaStatusForTesting()); + ASSERT_EQ(10u, checker->GetMaxQuotaUsage()); + + checker->AfterMessagesDequeued(5); + ASSERT_EQ(5u, checker->GetCurrentQuotaStatusForTesting()); + ASSERT_EQ(10u, checker->GetMaxQuotaUsage()); + + ASSERT_EQ(0u, num_dumps_); +} + +TEST_F(MessageQuotaCheckerTest, CountsMessagePipeAlso) { + MessagePipe pipe; + scoped_refptr<MessageQuotaChecker> checker = + MessageQuotaChecker::MaybeCreateForTesting(enabled_config_); + + uint64_t limit = 0; + uint64_t usage = 0; + MojoResult rv = MojoQueryQuota(pipe.handle0.get().value(), + MOJO_QUOTA_TYPE_UNREAD_MESSAGE_COUNT, nullptr, + &limit, &usage); + ASSERT_EQ(MOJO_RESULT_OK, rv); + ASSERT_EQ(MOJO_QUOTA_LIMIT_NONE, limit); + + checker->SetMessagePipe(pipe.handle0.get()); + + // Validate that the checker sets an unread message quota on the pipe, and + // that it clamps to the minimum of 100. + rv = MojoQueryQuota(pipe.handle0.get().value(), + MOJO_QUOTA_TYPE_UNREAD_MESSAGE_COUNT, nullptr, &limit, + &usage); + ASSERT_EQ(MOJO_RESULT_OK, rv); + ASSERT_EQ(100u, limit); + + ASSERT_EQ(0u, checker->GetCurrentQuotaStatusForTesting()); + + const char kMessage[] = "hello"; + for (size_t i = 0; i < 10; ++i) { + checker->BeforeWrite(); + ASSERT_EQ(MOJO_RESULT_OK, + WriteMessageRaw(pipe.handle0.get(), kMessage, sizeof(kMessage), + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); + } + + ASSERT_EQ(10u, checker->GetMaxQuotaUsage()); + ASSERT_EQ(10u, checker->GetCurrentQuotaStatusForTesting()); + + checker->BeforeMessagesEnqueued(10); + ASSERT_EQ(20u, checker->GetMaxQuotaUsage()); + ASSERT_EQ(20u, checker->GetCurrentQuotaStatusForTesting()); + + ASSERT_EQ(0u, num_dumps_); +} + +TEST_F(MessageQuotaCheckerTest, DumpsCoreOnOverrun) { + MessagePipe pipe; + scoped_refptr<MessageQuotaChecker> checker = + MessageQuotaChecker::MaybeCreateForTesting(enabled_config_); + + // Queue up 100 messages. + checker->SetMessagePipe(pipe.handle0.get()); + const char kMessage[] = "hello"; + for (size_t i = 0; i < 100; ++i) { + checker->BeforeWrite(); + ASSERT_EQ(MOJO_RESULT_OK, + WriteMessageRaw(pipe.handle0.get(), kMessage, sizeof(kMessage), + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); + } + + // The crash threshold is at 200 per the config, so shouldn't have attempted + // a core dump yet. + ASSERT_EQ(0u, num_dumps_); + + checker->BeforeMessagesEnqueued(50); + ASSERT_EQ(0u, num_dumps_); + + checker->BeforeMessagesEnqueued(50); + ASSERT_EQ(1u, num_dumps_); + ASSERT_EQ(200u, last_dump_quota_used_); + + checker->BeforeWrite(); + ASSERT_EQ(MOJO_RESULT_OK, + WriteMessageRaw(pipe.handle0.get(), kMessage, sizeof(kMessage), + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); + + ASSERT_EQ(2u, num_dumps_); + ASSERT_EQ(201u, last_dump_quota_used_); +} + +} // namespace +} // namespace test +} // namespace mojo
diff --git a/net/http/http_auth_controller.cc b/net/http/http_auth_controller.cc index 0e11a5d..1ef08d8 100644 --- a/net/http/http_auth_controller.cc +++ b/net/http/http_auth_controller.cc
@@ -142,15 +142,13 @@ const NetworkIsolationKey& network_isolation_key, HttpAuthCache* http_auth_cache, HttpAuthHandlerFactory* http_auth_handler_factory, - HostResolver* host_resolver, - HttpAuthPreferences::DefaultCredentials allow_default_credentials) + HostResolver* host_resolver) : target_(target), auth_url_(auth_url), auth_origin_(auth_url.GetOrigin()), auth_path_(auth_url.path()), network_isolation_key_(network_isolation_key), embedded_identity_used_(false), - allow_default_credentials_(allow_default_credentials), default_credentials_used_(false), http_auth_cache_(http_auth_cache), http_auth_handler_factory_(http_auth_handler_factory), @@ -539,12 +537,7 @@ // infinite loop. We use default credentials after checking the auth cache so // that if single sign-on doesn't work, we won't try default credentials for // future transactions. - if (!default_credentials_used_ && handler_->AllowsDefaultCredentials() && - // TODO(https://crbug.com/458508): Refactor |AllowsDefaultCredentials| - // to internally process |allow_default_credentials_| once it is - // passed along with the other |HttpAuthPreferences|. - allow_default_credentials_ == - HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS) { + if (!default_credentials_used_ && handler_->AllowsDefaultCredentials()) { identity_.source = HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS; identity_.invalid = false; default_credentials_used_ = true;
diff --git a/net/http/http_auth_controller.h b/net/http/http_auth_controller.h index 27a78f2..3a47c430 100644 --- a/net/http/http_auth_controller.h +++ b/net/http/http_auth_controller.h
@@ -83,14 +83,12 @@ // // * |allow_default_credentials| is used for determining if the current // context allows ambient authentication using default credentials. - HttpAuthController( - HttpAuth::Target target, - const GURL& auth_url, - const NetworkIsolationKey& network_isolation_key, - HttpAuthCache* http_auth_cache, - HttpAuthHandlerFactory* http_auth_handler_factory, - HostResolver* host_resolver, - HttpAuthPreferences::DefaultCredentials allow_default_credentials); + HttpAuthController(HttpAuth::Target target, + const GURL& auth_url, + const NetworkIsolationKey& network_isolation_key, + HttpAuthCache* http_auth_cache, + HttpAuthHandlerFactory* http_auth_handler_factory, + HostResolver* host_resolver); // Generate an authentication token for |target| if necessary. The return // value is a net error code. |OK| will be returned both in the case that @@ -228,13 +226,6 @@ // preventing an infinite auth restart loop. bool embedded_identity_used_; - // If the current context allows ambient authentication using default - // credentials. - // TODO(https://crbug.com/458508): Refactor |allow_default_credentials_| - // to be passed along with the other |HttpAuthPreferences|, rather then being - // passed directly to |HttpAuthController|. - HttpAuthPreferences::DefaultCredentials allow_default_credentials_; - // True if default credentials have already been tried for this transaction // in response to an HTTP authentication challenge. bool default_credentials_used_;
diff --git a/net/http/http_auth_controller_unittest.cc b/net/http/http_auth_controller_unittest.cc index d05f247..21df2ef 100644 --- a/net/http/http_auth_controller_unittest.cc +++ b/net/http/http_auth_controller_unittest.cc
@@ -80,7 +80,7 @@ base::MakeRefCounted<HttpAuthController>( HttpAuth::AUTH_PROXY, GURL("http://example.com"), NetworkIsolationKey(), &dummy_auth_cache, &auth_handler_factory, - host_resolver.get(), HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS)); + host_resolver.get())); SSLInfo null_ssl_info; ASSERT_EQ(OK, controller->HandleAuthChallenge(headers, null_ssl_info, false, false, net_log)); @@ -265,7 +265,7 @@ base::MakeRefCounted<HttpAuthController>( HttpAuth::AUTH_SERVER, GURL("http://example.com"), NetworkIsolationKey(), &dummy_auth_cache, &auth_handler_factory, - host_resolver.get(), HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS)); + host_resolver.get())); SSLInfo null_ssl_info; ASSERT_EQ(OK, controller->HandleAuthChallenge(headers, null_ssl_info, false, false, dummy_log));
diff --git a/net/http/http_auth_preferences.cc b/net/http/http_auth_preferences.cc index 15ab440..c0e4539 100644 --- a/net/http/http_auth_preferences.cc +++ b/net/http/http_auth_preferences.cc
@@ -47,7 +47,8 @@ bool HttpAuthPreferences::CanUseDefaultCredentials( const GURL& auth_origin) const { - return security_manager_->CanUseDefaultCredentials(auth_origin); + return allow_default_credentials_ == ALLOW_DEFAULT_CREDENTIALS && + security_manager_->CanUseDefaultCredentials(auth_origin); } using DelegationType = HttpAuth::DelegationType; @@ -63,6 +64,10 @@ return DelegationType::kUnconstrained; } +void HttpAuthPreferences::SetAllowDefaultCredentials(DefaultCredentials creds) { + allow_default_credentials_ = creds; +} + void HttpAuthPreferences::SetServerAllowlist( const std::string& server_allowlist) { std::unique_ptr<HttpAuthFilter> allowlist;
diff --git a/net/http/http_auth_preferences.h b/net/http/http_auth_preferences.h index 8045bdd6..f59c36aa 100644 --- a/net/http/http_auth_preferences.h +++ b/net/http/http_auth_preferences.h
@@ -79,6 +79,8 @@ void SetDelegateAllowlist(const std::string& delegate_allowlist); + void SetAllowDefaultCredentials(DefaultCredentials creds); + #if defined(OS_ANDROID) void set_auth_android_negotiate_account_type( const std::string& account_type) { @@ -91,6 +93,8 @@ bool negotiate_disable_cname_lookup_ = false; bool negotiate_enable_port_ = false; + DefaultCredentials allow_default_credentials_ = ALLOW_DEFAULT_CREDENTIALS; + #if defined(OS_POSIX) || defined(OS_FUCHSIA) bool ntlm_v2_enabled_ = true; #endif
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index e40d233..bd3d44a2 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc
@@ -93,8 +93,6 @@ enable_quic(false), enable_quic_proxies_for_https_urls(false), disable_idle_sockets_close_on_memory_pressure(false), - allow_default_credentials(HttpAuthPreferences::DefaultCredentials:: - DISALLOW_DEFAULT_CREDENTIALS), key_auth_cache_server_entries_by_network_isolation_key(false) { enable_early_data = base::FeatureList::IsEnabled(features::kEnableTLS13EarlyData);
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index 64039ac..e36e169b 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h
@@ -27,7 +27,6 @@ #include "net/base/host_port_pair.h" #include "net/base/net_export.h" #include "net/http/http_auth_cache.h" -#include "net/http/http_auth_preferences.h" #include "net/http/http_stream_factory.h" #include "net/net_buildflags.h" #include "net/quic/quic_stream_factory.h" @@ -150,10 +149,6 @@ // If true, idle sockets won't be closed when memory pressure happens. bool disable_idle_sockets_close_on_memory_pressure; - // If authentication APIs that support ambient authentication are allowed - // to use the default credentials. - HttpAuthPreferences::DefaultCredentials allow_default_credentials; - bool key_auth_cache_server_entries_by_network_isolation_key; };
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index dff329b..01f673874 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -886,8 +886,7 @@ auth_controllers_[target] = base::MakeRefCounted<HttpAuthController>( target, AuthURL(target), request_->network_isolation_key, session_->http_auth_cache(), session_->http_auth_handler_factory(), - session_->host_resolver(), - session_->params().allow_default_credentials); + session_->host_resolver()); return auth_controllers_[target]->MaybeGenerateAuthToken(request_, io_callback_, net_log_); @@ -907,8 +906,7 @@ auth_controllers_[target] = base::MakeRefCounted<HttpAuthController>( target, AuthURL(target), request_->network_isolation_key, session_->http_auth_cache(), session_->http_auth_handler_factory(), - session_->host_resolver(), - session_->params().allow_default_credentials); + session_->host_resolver()); if (request_->load_flags & LOAD_DO_NOT_USE_EMBEDDED_IDENTITY) auth_controllers_[target]->DisableEmbeddedIdentity(); }
diff --git a/net/http/http_proxy_client_socket_fuzzer.cc b/net/http/http_proxy_client_socket_fuzzer.cc index 2b416158..9221e49 100644 --- a/net/http/http_proxy_client_socket_fuzzer.cc +++ b/net/http/http_proxy_client_socket_fuzzer.cc
@@ -23,7 +23,6 @@ #include "net/http/http_auth_handler_basic.h" #include "net/http/http_auth_handler_digest.h" #include "net/http/http_auth_handler_factory.h" -#include "net/http/http_auth_preferences.h" #include "net/http/http_auth_scheme.h" #include "net/log/test_net_log.h" #include "net/socket/fuzzed_socket.h" @@ -60,7 +59,7 @@ base::MakeRefCounted<net::HttpAuthController>( net::HttpAuth::AUTH_PROXY, GURL("http://proxy:42/"), net::NetworkIsolationKey(), &auth_cache, &auth_handler_factory, - nullptr, net::HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS)); + nullptr)); // Determine if the HttpProxyClientSocket should be told the underlying socket // is HTTPS. net::HttpProxyClientSocket socket(
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc index 13efec42..232484d 100644 --- a/net/http/http_proxy_connect_job.cc +++ b/net/http/http_proxy_connect_job.cc
@@ -188,8 +188,7 @@ params_->network_isolation_key(), common_connect_job_params->http_auth_cache, common_connect_job_params->http_auth_handler_factory, - host_resolver(), - HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS) + host_resolver()) : nullptr) {} HttpProxyConnectJob::~HttpProxyConnectJob() {}
diff --git a/net/quic/quic_proxy_client_socket_unittest.cc b/net/quic/quic_proxy_client_socket_unittest.cc index 8681f1f..576602c2 100644 --- a/net/quic/quic_proxy_client_socket_unittest.cc +++ b/net/quic/quic_proxy_client_socket_unittest.cc
@@ -294,12 +294,11 @@ sock_.reset(new QuicProxyClientSocket( std::move(stream_handle), std::move(session_handle_), user_agent_, endpoint_host_port_, net_log_.bound(), - new HttpAuthController( - HttpAuth::AUTH_PROXY, - GURL("https://" + proxy_host_port_.ToString()), - NetworkIsolationKey(), &http_auth_cache_, - http_auth_handler_factory_.get(), host_resolver_.get(), - HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS))); + new HttpAuthController(HttpAuth::AUTH_PROXY, + GURL("https://" + proxy_host_port_.ToString()), + NetworkIsolationKey(), &http_auth_cache_, + http_auth_handler_factory_.get(), + host_resolver_.get()))); session_->StartReading(); }
diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc index abe16d4..d63dbcc 100644 --- a/net/spdy/spdy_proxy_client_socket_unittest.cc +++ b/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -17,7 +17,6 @@ #include "net/base/test_completion_callback.h" #include "net/base/winsock_init.h" #include "net/dns/mock_host_resolver.h" -#include "net/http/http_auth_preferences.h" #include "net/http/http_proxy_connect_job.h" #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" @@ -270,8 +269,7 @@ new HttpAuthController( HttpAuth::AUTH_PROXY, GURL("https://" + proxy_host_port_.ToString()), NetworkIsolationKey(), session_->http_auth_cache(), - session_->http_auth_handler_factory(), session_->host_resolver(), - HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS)); + session_->http_auth_handler_factory(), session_->host_resolver())); } scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc index 791b27c1..41b6396 100644 --- a/net/spdy/spdy_test_util_common.cc +++ b/net/spdy/spdy_test_util_common.cc
@@ -344,7 +344,6 @@ net_log(nullptr), disable_idle_sockets_close_on_memory_pressure(false), enable_early_data(false), - allow_default_credentials(HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS), key_auth_cache_server_entries_by_network_isolation_key(false) { http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = kDefaultInitialWindowSize; @@ -399,7 +398,6 @@ params.disable_idle_sockets_close_on_memory_pressure = session_deps->disable_idle_sockets_close_on_memory_pressure; params.enable_early_data = session_deps->enable_early_data; - params.allow_default_credentials = session_deps->allow_default_credentials; params.key_auth_cache_server_entries_by_network_isolation_key = session_deps->key_auth_cache_server_entries_by_network_isolation_key; return params;
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h index 18c10087..514ea3b2 100644 --- a/net/spdy/spdy_test_util_common.h +++ b/net/spdy/spdy_test_util_common.h
@@ -25,7 +25,6 @@ #include "net/cert/cert_verifier.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_auth_handler_factory.h" -#include "net/http/http_auth_preferences.h" #include "net/http/http_network_session.h" #include "net/http/http_response_info.h" #include "net/http/http_server_properties.h" @@ -237,7 +236,6 @@ NetLog* net_log; bool disable_idle_sockets_close_on_memory_pressure; bool enable_early_data; - HttpAuthPreferences::DefaultCredentials allow_default_credentials; bool key_auth_cache_server_entries_by_network_isolation_key; };
diff --git a/printing/backend/cups_connection.cc b/printing/backend/cups_connection.cc index caa244c..79dd875 100644 --- a/printing/backend/cups_connection.cc +++ b/printing/backend/cups_connection.cc
@@ -155,8 +155,8 @@ temp_queues.emplace_back(); QueueStatus* queue_status = &temp_queues.back(); - if (!GetPrinterStatus(cups_http_.get(), id, - &queue_status->printer_status)) { + if (!printing::GetPrinterStatus(cups_http_.get(), id, + &queue_status->printer_status)) { LOG(WARNING) << "Could not retrieve printer status for " << id; return false; } @@ -178,6 +178,16 @@ return true; } +bool CupsConnection::GetPrinterStatus(const std::string& printer_id, + PrinterStatus* printer_status) { + if (!Connect()) { + LOG(ERROR) << "Could not establish connection to CUPS"; + return false; + } + return printing::GetPrinterStatus(cups_http_.get(), printer_id, + printer_status); +} + std::string CupsConnection::server_name() const { return print_server_url_.host(); }
diff --git a/printing/backend/cups_connection.h b/printing/backend/cups_connection.h index 3fcb995..6d7f766 100644 --- a/printing/backend/cups_connection.h +++ b/printing/backend/cups_connection.h
@@ -55,6 +55,11 @@ bool GetJobs(const std::vector<std::string>& printer_ids, std::vector<QueueStatus>* jobs); + // Queries CUPS for printer status for |printer_id|. + // Returns true if the query was successful. + bool GetPrinterStatus(const std::string& printer_id, + PrinterStatus* printer_status); + std::string server_name() const; int last_error() const;
diff --git a/services/device/geolocation/wifi_data_provider_mac.mm b/services/device/geolocation/wifi_data_provider_mac.mm index 83cae22..585208f 100644 --- a/services/device/geolocation/wifi_data_provider_mac.mm +++ b/services/device/geolocation/wifi_data_provider_mac.mm
@@ -21,7 +21,13 @@ #include "services/device/geolocation/wifi_data_provider_common.h" #include "services/device/geolocation/wifi_data_provider_manager.h" +#if !defined(MAC_OS_X_VERSION_10_15) +// This API is so deprecated that this symbol is no longer present at all in the +// 10.15 SDK. For the moment, hack this functionality out entirely when building +// with the 10.15 SDK. +// https://crbug.com/1022821 extern "C" NSString* const kCWScanKeyMerge; +#endif @interface CWInterface (Private) - (NSArray*)scanForNetworksWithParameters:(NSDictionary*)params @@ -47,7 +53,11 @@ @autoreleasepool { // Initialize the scan parameters with scan key merging // disabled, so we get // every AP listed in the scan without any SSID de-duping logic. +#if defined(MAC_OS_X_VERSION_10_15) + NSDictionary* params = @{}; +#else NSDictionary* params = @{kCWScanKeyMerge : @NO}; +#endif NSSet* supported_interfaces = [CWInterface interfaceNames]; NSUInteger interface_error_count = 0;
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 160a006b..ad25f45 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -366,6 +366,12 @@ origin_policy_manager_ = std::make_unique<OriginPolicyManager>(this); + if (params_->http_auth_static_network_context_params) { + http_auth_merged_preferences_.SetAllowDefaultCredentials( + params_->http_auth_static_network_context_params + ->allow_default_credentials); + } + InitializeCorsParams(); } @@ -1573,6 +1579,40 @@ std::move(callback).Run(base::nullopt); } +const net::HttpAuthPreferences* NetworkContext::GetHttpAuthPreferences() const + noexcept { + return &http_auth_merged_preferences_; +} + +void NetworkContext::OnHttpAuthDynamicParamsChanged( + const mojom::HttpAuthDynamicParams* + http_auth_dynamic_network_service_params) { + http_auth_merged_preferences_.SetServerAllowlist( + http_auth_dynamic_network_service_params->server_allowlist); + http_auth_merged_preferences_.SetDelegateAllowlist( + http_auth_dynamic_network_service_params->delegate_allowlist); + http_auth_merged_preferences_.set_delegate_by_kdc_policy( + http_auth_dynamic_network_service_params->delegate_by_kdc_policy); + http_auth_merged_preferences_.set_negotiate_disable_cname_lookup( + http_auth_dynamic_network_service_params->negotiate_disable_cname_lookup); + http_auth_merged_preferences_.set_negotiate_enable_port( + http_auth_dynamic_network_service_params->enable_negotiate_port); +#if defined(OS_POSIX) || defined(OS_FUCHSIA) + http_auth_merged_preferences_.set_ntlm_v2_enabled( + http_auth_dynamic_network_service_params->ntlm_v2_enabled); +#endif + +#if defined(OS_ANDROID) + http_auth_merged_preferences_.set_auth_android_negotiate_account_type( + http_auth_dynamic_network_service_params->android_negotiate_account_type); +#endif + +#if defined(OS_CHROMEOS) + http_auth_merged_preferences_.set_allow_gssapi_library_load( + http_auth_dynamic_network_service_params->allow_gssapi_library_load); +#endif +} + URLRequestContextOwner NetworkContext::MakeURLRequestContext() { URLRequestContextBuilderMojo builder; const base::CommandLine* command_line = @@ -1861,8 +1901,6 @@ *base::CommandLine::ForCurrentProcess(), is_quic_force_disabled, params_->quic_user_agent_id, &session_params); - session_params.allow_default_credentials = params_->allow_default_credentials; - session_params.disable_idle_sockets_close_on_memory_pressure = params_->disable_idle_sockets_close_on_memory_pressure;
diff --git a/services/network/network_context.h b/services/network/network_context.h index 47d8a9e1..aed41d8 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -33,6 +33,7 @@ #include "net/cert/cert_verify_result.h" #include "net/dns/dns_config_overrides.h" #include "net/dns/host_resolver.h" +#include "net/http/http_auth_preferences.h" #include "services/network/cors/preflight_controller.h" #include "services/network/http_cache_data_counter.h" #include "services/network/http_cache_data_remover.h" @@ -448,6 +449,14 @@ bool IsCorsEnabled() const { return cors_enabled_; } + // The http_auth_dynamic_params_ would be used to populate + // the |http_auth_merged_preferences| of the given NetworkContext. + void OnHttpAuthDynamicParamsChanged( + const mojom::HttpAuthDynamicParams* + http_auth_dynamic_network_service_params); + + const net::HttpAuthPreferences* GetHttpAuthPreferences() const; + private: URLRequestContextOwner MakeURLRequestContext(); @@ -649,6 +658,13 @@ std::unique_ptr<OriginPolicyManager> origin_policy_manager_; + // Each network context holds its own HttpAuthPreferences. + // The dynamic preferences of |NetworkService| and the static + // preferences from |NetworkContext| would be merged to + // `http_auth_merged_preferences_` which would then be used to create + // HttpAuthHandle via |NetworkContext::CreateHttpAuthHandlerFactory|. + net::HttpAuthPreferences http_auth_merged_preferences_; + DISALLOW_COPY_AND_ASSIGN(NetworkContext); };
diff --git a/services/network/network_service.cc b/services/network/network_service.cc index 6a121f6..4e3373f 100644 --- a/services/network/network_service.cc +++ b/services/network/network_service.cc
@@ -329,6 +329,15 @@ network_contexts_.insert(network_context); if (quic_disabled_) network_context->DisableQuic(); + + // The params may already be present, so we propagate it + // to this new network_context. When params gets changed + // via ConfigureHttpAuthPrefs method, we propagate the change + // to all NetworkContexts in |network_contexts_| + if (http_auth_dynamic_network_service_params_) { + network_context->OnHttpAuthDynamicParamsChanged( + http_auth_dynamic_network_service_params_.get()); + } } void NetworkService::DeregisterNetworkContext(NetworkContext* network_context) { @@ -453,37 +462,24 @@ void NetworkService::SetUpHttpAuth( mojom::HttpAuthStaticParamsPtr http_auth_static_params) { - DCHECK(!http_auth_static_params_); - http_auth_static_params_ = std::move(http_auth_static_params); + DCHECK(!http_auth_static_network_service_params_); + DCHECK(network_contexts_.empty()); + http_auth_static_network_service_params_ = std::move(http_auth_static_params); } void NetworkService::ConfigureHttpAuthPrefs( mojom::HttpAuthDynamicParamsPtr http_auth_dynamic_params) { - http_auth_preferences_.SetServerAllowlist( - http_auth_dynamic_params->server_allowlist); - http_auth_preferences_.SetDelegateAllowlist( - http_auth_dynamic_params->delegate_allowlist); - http_auth_preferences_.set_delegate_by_kdc_policy( - http_auth_dynamic_params->delegate_by_kdc_policy); - http_auth_preferences_.set_negotiate_disable_cname_lookup( - http_auth_dynamic_params->negotiate_disable_cname_lookup); - http_auth_preferences_.set_negotiate_enable_port( - http_auth_dynamic_params->enable_negotiate_port); + // We need to store it as a member variable because the method + // NetworkService::RegisterNetworkContext(NetworkContext *network_context) + // uses it to populate the HttpAuthPreferences of the incoming network_context + // with the latest dynamic params of the NetworkService. + http_auth_dynamic_network_service_params_ = + std::move(http_auth_dynamic_params); -#if defined(OS_POSIX) || defined(OS_FUCHSIA) - http_auth_preferences_.set_ntlm_v2_enabled( - http_auth_dynamic_params->ntlm_v2_enabled); -#endif - -#if defined(OS_ANDROID) - http_auth_preferences_.set_auth_android_negotiate_account_type( - http_auth_dynamic_params->android_negotiate_account_type); -#endif - -#if defined(OS_CHROMEOS) - http_auth_preferences_.set_allow_gssapi_library_load( - http_auth_dynamic_params->allow_gssapi_library_load); -#endif + for (NetworkContext* network_context : network_contexts_) { + network_context->OnHttpAuthDynamicParamsChanged( + http_auth_dynamic_network_service_params_.get()); + } } void NetworkService::SetRawHeadersAccess( @@ -662,21 +658,22 @@ std::unique_ptr<net::HttpAuthHandlerFactory> NetworkService::CreateHttpAuthHandlerFactory(NetworkContext* network_context) { - if (!http_auth_static_params_) { + if (!http_auth_static_network_service_params_) { return net::HttpAuthHandlerFactory::CreateDefault( - &http_auth_preferences_ + network_context->GetHttpAuthPreferences() #if defined(OS_ANDROID) && BUILDFLAG(USE_KERBEROS) - , + , base::BindRepeating(&CreateAuthSystem, network_context) #endif ); } return net::HttpAuthHandlerRegistryFactory::Create( - &http_auth_preferences_, http_auth_static_params_->supported_schemes + network_context->GetHttpAuthPreferences(), + http_auth_static_network_service_params_->supported_schemes #if BUILDFLAG(USE_EXTERNAL_GSSAPI) , - http_auth_static_params_->gssapi_library_name + http_auth_static_network_service_params_->gssapi_library_name #endif #if defined(OS_ANDROID) && BUILDFLAG(USE_KERBEROS) ,
diff --git a/services/network/network_service.h b/services/network/network_service.h index 3fe829b..356c83e 100644 --- a/services/network/network_service.h +++ b/services/network/network_service.h
@@ -27,7 +27,6 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/dns/dns_config.h" -#include "net/http/http_auth_preferences.h" #include "net/log/net_log.h" #include "net/log/trace_net_log_observer.h" #include "services/network/keepalive_statistics_recorder.h" @@ -273,11 +272,14 @@ std::unique_ptr<net::HostResolverManager> host_resolver_manager_; std::unique_ptr<net::HostResolver::Factory> host_resolver_factory_; std::unique_ptr<NetworkUsageAccumulator> network_usage_accumulator_; - - net::HttpAuthPreferences http_auth_preferences_; - mojom::HttpAuthStaticParamsPtr http_auth_static_params_; std::unique_ptr<HttpAuthCacheCopier> http_auth_cache_copier_; + // Members that would store the http auth network_service related params. + // These Params are later used by NetworkContext to create + // HttpAuthPreferences. + mojom::HttpAuthDynamicParamsPtr http_auth_dynamic_network_service_params_; + mojom::HttpAuthStaticParamsPtr http_auth_static_network_service_params_; + // NetworkContexts created by CreateNetworkContext(). They call into the // NetworkService when their connection is closed so that it can delete // them. It will also delete them when the NetworkService itself is torn
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 80b5b4d..f7c195f 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -182,6 +182,13 @@ pending_receiver<TrustedHeaderClient> header_client); }; +struct HttpAuthStaticNetworkContextParams { + // Whether authentication APIs that support fallback to the default account + // on the system can be used without specifying an account. + DefaultCredentials allow_default_credentials + = DefaultCredentials.ALLOW_DEFAULT_CREDENTIALS; +}; + // Parameters for constructing a network context. struct NetworkContextParams { // Name used by memory tools to identify the context. @@ -269,11 +276,6 @@ // If true, idle sockets won't be closed when memory pressure happens. bool disable_idle_sockets_close_on_memory_pressure = false; - // Whether authentication APIs that support fallback to the default account - // on the system can be used without specifying an account. - DefaultCredentials allow_default_credentials = - DefaultCredentials.ALLOW_DEFAULT_CREDENTIALS; - // SSL configuration. |initial_proxy_config| is the initial SSL configuration // to use. If nullptr, uses the default configuration. Updated SSL // configurations can be passed in via |ssl_config_client_receiver|. @@ -440,6 +442,11 @@ // regardless. This field should not be used if the ENABLE_REPORTING build // flag is false. mojo_base.mojom.FilePath? reporting_and_nel_store_path; + + // The params are network context specific which will be merged with + // the dynamic preference from NetworkService side, to populate + // HttpAuthPreference. + HttpAuthStaticNetworkContextParams? http_auth_static_network_context_params; }; struct NetworkConditions {
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 86a92329..8b6a411 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -54,12 +54,15 @@ } defines = [ - "SK_GL", "SK_HAS_PNG_LIBRARY", "SK_HAS_WEBP_LIBRARY", "SK_USER_CONFIG_HEADER=\"../../skia/config/SkUserConfig.h\"", ] + if (skia_use_gl) { + defines += [ "SK_GL" ] + } + if (!is_ios) { defines += [ "SK_HAS_JPEG_LIBRARY" ] if (enable_skia_wuffs_gif) { @@ -569,6 +572,9 @@ sources += skia_gpu_sources sources += skia_null_gpu_sources sources += skia_sksl_gpu_sources + if (skia_use_gl) { + sources += skia_gl_gpu_sources + } if (enable_vulkan) { sources += skia_vk_sources sources += [
diff --git a/skia/features.gni b/skia/features.gni index f8ee32ea..2a94ac2 100644 --- a/skia/features.gni +++ b/skia/features.gni
@@ -5,4 +5,5 @@ declare_args() { # Enable experimental SkiaRenderer Dawn backend. skia_use_dawn = false + skia_use_gl = true }
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py index 7a21bcd..0a4e0fd 100755 --- a/testing/buildbot/generate_buildbot_json.py +++ b/testing/buildbot/generate_buildbot_json.py
@@ -1096,7 +1096,9 @@ # These waterfalls have their bot configs in a different repo. # so we don't know about their bot names. continue # pragma: no cover - if waterfall['name'] in ['client.devtools-frontend.integration']: + if waterfall['name'] in [ + 'client.devtools-frontend.integration', + 'tryserver.devtools-frontend']: continue # pragma: no cover raise self.unknown_bot(bot_name, waterfall['name'])
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index d3dc0195..aca4359 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -2124,9 +2124,9 @@ "label": "//third_party/opus:opus_tests", "type": "console_test_launcher", }, - "ocmock_support_unittests": { + "ios_testing_unittests": { "args": [], - "label": "//ios/testing:ocmock_support_unittests", + "label": "//ios/testing:ios_testing_unittests", "type": "raw", }, "origin_policy_parser_fuzzer": {
diff --git a/testing/buildbot/manage.py b/testing/buildbot/manage.py index e0ad3aed..40e14354 100755 --- a/testing/buildbot/manage.py +++ b/testing/buildbot/manage.py
@@ -115,7 +115,7 @@ 'ios_web_unittests', 'ios_web_view_inttests', 'ios_web_view_unittests', - 'ocmock_support_unittests', + 'ios_testing_unittests', # These are listed in Builders that are skipped for other reasons. 'chrome_junit_tests',
diff --git a/testing/buildbot/tryserver.devtools-frontend.json b/testing/buildbot/tryserver.devtools-frontend.json new file mode 100644 index 0000000..92b5ea3 --- /dev/null +++ b/testing/buildbot/tryserver.devtools-frontend.json
@@ -0,0 +1,31 @@ +{ + "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, + "AAAAA2 See generate_buildbot_json.py to make changes": {}, + "devtools_frontend_linux_blink_light_rel": { + "isolated_scripts": [ + { + "args": [ + "--num-retries=3" + ], + "isolate_name": "blink_web_tests_exparchive", + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "webkit_layout_tests", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "shards": 12 + } + } + ] + } +}
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 73f7d3f3..2e26b2d 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -4463,6 +4463,19 @@ }, }, { + 'name': 'tryserver.devtools-frontend', + 'machines': { + 'devtools_frontend_linux_blink_light_rel': { + 'mixins': [ + 'linux-xenial', + ], + 'test_suites': { + 'isolated_scripts': 'chromium_webkit_isolated_scripts', + }, + }, + } + }, + { 'name': 'tryserver.webrtc', 'machines': { 'android_chromium_compile': {
diff --git a/testing/scripts/OWNERS b/testing/scripts/OWNERS index cf3d58aa..540926e6 100644 --- a/testing/scripts/OWNERS +++ b/testing/scripts/OWNERS
@@ -9,5 +9,8 @@ per-file check_static_initializers.py=thakis@chromium.org per-file check_static_initializers.py=thomasanderson@chromium.org +per-file run-wpt_tests.py=lpz@chromium.org +per-file run_wpt_tests.py=robertma@chromium.org + # TEAM: infra-dev@chromium.org # COMPONENT: Infra>Client>Chrome
diff --git a/testing/scripts/run_wpt_tests.py b/testing/scripts/run_wpt_tests.py index 5c3556af..e635ed8 100755 --- a/testing/scripts/run_wpt_tests.py +++ b/testing/scripts/run_wpt_tests.py
@@ -72,8 +72,10 @@ #"--no-manifest-update", "--manifest=../../third_party/blink/web_tests/external/" "WPT_BASE_MANIFEST_6.json", - # Enable mach logging to aid debugging - "--log-mach=-" + # (crbug.com/1023835) The flags below are temporary to aid debugging + "--log-mach=-", + "--log-mach-verbose", + "--exclude=webdriver" ]) return rest_args
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index c4b3f31..eaf5226 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1585,6 +1585,21 @@ ] } ], + "CloudPolicyOverFcm": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "CloudPolicyOverFCM" + } + ] + } + ], "CompositorImageAnimation": [ { "platforms": [ @@ -6707,10 +6722,30 @@ ], "experiments": [ { - "name": "UKM_Enabled", + "name": "UMA_Enabled", "enable_features": [ - "DemographicMetricsReporting", - "UkmReportNoisedUserBirthYearAndGender" + "DemographicMetricsReporting" + ] + } + ] + } + ], + "UnidoOnSignIn": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SharingDeriveVapidKey", + "SharingUseDeviceInfo", + "SyncDeviceInfoInTransportMode" ] } ]
diff --git a/components/chrome_cleaner/public/typemaps/OWNERS b/third_party/blink/common/frame/OWNERS similarity index 79% rename from components/chrome_cleaner/public/typemaps/OWNERS rename to third_party/blink/common/frame/OWNERS index 03fa9a5d..0f95157 100644 --- a/components/chrome_cleaner/public/typemaps/OWNERS +++ b/third_party/blink/common/frame/OWNERS
@@ -1,7 +1,4 @@ -set noparent -file://ipc/SECURITY_OWNERS - per-file *_mojom_traits*.*=set noparent per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS per-file *.typemap=set noparent -per-file *.typemap=file://ipc/SECURITY_OWNERS +per-file *.typemap=file://ipc/SECURITY_OWNERS \ No newline at end of file
diff --git a/third_party/blink/common/frame/frame_policy.typemap b/third_party/blink/common/frame/frame_policy.typemap new file mode 100644 index 0000000..cf90829a --- /dev/null +++ b/third_party/blink/common/frame/frame_policy.typemap
@@ -0,0 +1,16 @@ +# 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. + +mojom = "//third_party/blink/public/mojom/frame/frame_policy.mojom" +public_headers = [ + "//third_party/blink/public/common/frame/frame_policy.h", + "//third_party/blink/public/common/feature_policy/policy_value.h", + "//third_party/blink/public/common/frame/sandbox_flags.h", +] +traits_headers = + [ "//third_party/blink/common/frame/frame_policy_mojom_traits.h" ] +sources = [ + "//third_party/blink/common/frame/frame_policy_mojom_traits.cc", +] +type_mappings = [ "blink.mojom.FramePolicy=::blink::FramePolicy" ]
diff --git a/third_party/blink/common/frame/frame_policy_mojom_traits.cc b/third_party/blink/common/frame/frame_policy_mojom_traits.cc new file mode 100644 index 0000000..fdc90788 --- /dev/null +++ b/third_party/blink/common/frame/frame_policy_mojom_traits.cc
@@ -0,0 +1,19 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/common/frame/frame_policy_mojom_traits.h" + +namespace mojo { + +bool StructTraits<blink::mojom::FramePolicyDataView, blink::FramePolicy>::Read( + blink::mojom::FramePolicyDataView in, + blink::FramePolicy* out) { + out->allowed_to_download_without_user_activation = + in.allowed_to_download_without_user_activation(); + + return in.ReadSandboxFlags(&out->sandbox_flags) && + in.ReadContainerPolicy(&out->container_policy); +} + +} // namespace mojo
diff --git a/third_party/blink/common/frame/frame_policy_mojom_traits.h b/third_party/blink/common/frame/frame_policy_mojom_traits.h new file mode 100644 index 0000000..afe109a --- /dev/null +++ b/third_party/blink/common/frame/frame_policy_mojom_traits.h
@@ -0,0 +1,39 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_COMMON_FRAME_FRAME_POLICY_MOJOM_TRAITS_H_ +#define THIRD_PARTY_BLINK_COMMON_FRAME_FRAME_POLICY_MOJOM_TRAITS_H_ + +#include "third_party/blink/common/feature_policy/feature_policy_mojom_traits.h" +#include "third_party/blink/public/common/frame/frame_policy.h" +#include "third_party/blink/public/mojom/frame/frame_policy.mojom-shared.h" + +namespace mojo { + +template <> +class BLINK_COMMON_EXPORT + StructTraits<blink::mojom::FramePolicyDataView, blink::FramePolicy> { + public: + static bool allowed_to_download_without_user_activation( + const blink::FramePolicy& frame_policy) { + return frame_policy.allowed_to_download_without_user_activation; + } + + static const std::vector<blink::ParsedFeaturePolicyDeclaration>& + container_policy(const blink::FramePolicy& frame_policy) { + return frame_policy.container_policy; + } + + static blink::WebSandboxFlags sandbox_flags( + const blink::FramePolicy& frame_policy) { + return frame_policy.sandbox_flags; + } + + static bool Read(blink::mojom::FramePolicyDataView in, + blink::FramePolicy* out); +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_COMMON_FRAME_FRAME_POLICY_MOJOM_TRAITS_H_
diff --git a/third_party/blink/common/typemaps.gni b/third_party/blink/common/typemaps.gni index f0f89bd..b4bbb0de 100644 --- a/third_party/blink/common/typemaps.gni +++ b/third_party/blink/common/typemaps.gni
@@ -5,6 +5,7 @@ typemaps = [ "//third_party/blink/common/bluetooth/web_bluetooth_device_id.typemap", "//third_party/blink/common/feature_policy/feature_policy.typemap", + "//third_party/blink/common/frame/frame_policy.typemap", "//third_party/blink/common/messaging/cloneable_message.typemap", "//third_party/blink/common/messaging/transferable_message.typemap", ]
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 7f2c31b..48820a1 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -126,7 +126,6 @@ "platform/mac/web_sandbox_support.h", "platform/mac/web_scrollbar_theme.h", "platform/media/webmediaplayer_delegate.h", - "platform/modules/indexeddb/web_idb_database_exception.h", "platform/modules/mediastream/media_stream_audio_deliverer.h", "platform/modules/mediastream/media_stream_audio_track.h", "platform/modules/mediastream/media_stream_types.h",
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 6a78c29..502ccf7 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -53,6 +53,7 @@ "filesystem/file_system.mojom", "frame/find_in_page.mojom", "frame/frame.mojom", + "frame/frame_policy.mojom", "frame/fullscreen.mojom", "frame/lifecycle.mojom", "frame/navigation_initiator.mojom",
diff --git a/third_party/blink/public/mojom/frame/frame_policy.mojom b/third_party/blink/public/mojom/frame/frame_policy.mojom new file mode 100644 index 0000000..6f93e66 --- /dev/null +++ b/third_party/blink/public/mojom/frame/frame_policy.mojom
@@ -0,0 +1,17 @@ +// 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. + +module blink.mojom; + +import "third_party/blink/public/mojom/feature_policy/feature_policy.mojom"; + +// This struct holds frame policy value that needs to be passed around between +// renderer process and browser process during navigation. It is used as a data +// member of CommonNavigationParams. For details, please refer to +// navigation_params.mojom. +struct FramePolicy { + blink.mojom.WebSandboxFlags sandbox_flags; + array<blink.mojom.ParsedFeaturePolicyDeclaration> container_policy; + bool allowed_to_download_without_user_activation = true; +};
diff --git a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom index bc44681..745eadbef 100644 --- a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom +++ b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
@@ -147,6 +147,19 @@ IOError, }; +// These values need to match core/dom/exception_code.h +enum IDBException { + kNoError = 0, + kUnknownError = 28, + kConstraintError = 29, + kDataError = 30, + kVersionError = 33, + kAbortError = 20, + kIgnorableAbortError = 11, + kQuotaError = 22, + kTimeoutError = 23, +}; + struct IDBIndexMetadata { int64 id; mojo_base.mojom.String16 name; @@ -233,7 +246,7 @@ // TODO(https://crbug.com/627484): Many of these could be replaced with // replies associated with particular messages. interface IDBCallbacks { - Error(int32 code, mojo_base.mojom.String16 message); + Error(IDBException code, mojo_base.mojom.String16 message); // Factory::GetDatabaseInfo SuccessNamesAndVersionsList(array<IDBNameAndVersion> value); @@ -267,14 +280,14 @@ interface IDBDatabaseCallbacks { ForcedClose(); VersionChange(int64 old_version, int64 new_version); - Abort(int64 transaction_id, int32 code, + Abort(int64 transaction_id, IDBException code, mojo_base.mojom.String16 message); Complete(int64 transaction_id); Changes(IDBObserverChanges changes); }; struct IDBError { - int32 error_code; + IDBException error_code; mojo_base.mojom.String16 error_message; };
diff --git a/third_party/blink/public/platform/modules/indexeddb/OWNERS b/third_party/blink/public/platform/modules/indexeddb/OWNERS deleted file mode 100644 index a740487..0000000 --- a/third_party/blink/public/platform/modules/indexeddb/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -file://content/browser/indexed_db/OWNERS - -# TEAM: storage-dev@chromium.org -# COMPONENT: Blink>Storage>IndexedDB
diff --git a/third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h b/third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h deleted file mode 100644 index 32a2d63a..0000000 --- a/third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h +++ /dev/null
@@ -1,49 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_DATABASE_EXCEPTION_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_DATABASE_EXCEPTION_H_ - -namespace blink { - -enum WebIDBDatabaseException { - kWebIDBDatabaseExceptionUnknownError = 28, - kWebIDBDatabaseExceptionConstraintError = 29, - kWebIDBDatabaseExceptionDataError = 30, - kWebIDBDatabaseExceptionVersionError = 33, - kWebIDBDatabaseExceptionAbortError = 20, - kWebIDBDatabaseExceptionIgnorableAbortError = 11, - kWebIDBDatabaseExceptionQuotaError = 22, - kWebIDBDatabaseExceptionTimeoutError = 23, -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_DATABASE_EXCEPTION_H_
diff --git a/third_party/blink/public/web/web_navigation_params.h b/third_party/blink/public/web/web_navigation_params.h index d3e8c0b..6e7cfb8 100644 --- a/third_party/blink/public/web/web_navigation_params.h +++ b/third_party/blink/public/web/web_navigation_params.h
@@ -14,6 +14,7 @@ #include "mojo/public/cpp/system/message_pipe.h" #include "services/network/public/mojom/ip_address_space.mojom-shared.h" #include "services/network/public/mojom/referrer_policy.mojom-shared.h" +#include "third_party/blink/public/common/frame/frame_policy.h" #include "third_party/blink/public/common/navigation/triggering_event_info.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h" @@ -148,6 +149,10 @@ // The navigation initiator's address space. network::mojom::IPAddressSpace initiator_address_space = network::mojom::IPAddressSpace::kUnknown; + + // The frame policy specified by the frame owner element. + // Should be base::nullopt for top level navigations + base::Optional<FramePolicy> frame_policy; }; // This structure holds all information provided by the embedder that is @@ -352,6 +357,10 @@ // The base URL which will be set for the document to support relative path // subresource loading in unsigned bundled exchanges file. WebURL base_url_override_for_bundled_exchanges; + + // The frame policy specified by the frame owner element. + // Should be base::nullopt for top level navigations + base::Optional<FramePolicy> frame_policy; }; } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc index 6cd8d3f..6844f4a 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
@@ -414,7 +414,7 @@ if (!image_data) return nullptr; DOMArrayBufferBase* pixel_buffer = image_data->BufferBase(); - DCHECK_EQ(pixel_buffer->ByteLength(), byte_length); + DCHECK_EQ(pixel_buffer->DeprecatedByteLengthAsUnsigned(), byte_length); memcpy(pixel_buffer->Data(), pixels, byte_length); return image_data; }
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc index 5c58c927..ac8e5462 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
@@ -331,7 +331,7 @@ WriteUint32(image_data->height()); DOMArrayBufferBase* pixel_buffer = image_data->BufferBase(); uint32_t pixel_buffer_length = - SafeCast<uint32_t>(pixel_buffer->ByteLength()); + pixel_buffer->DeprecatedByteLengthAsUnsigned(); WriteUint32(pixel_buffer_length); WriteRawBytes(pixel_buffer->Data(), pixel_buffer_length); return true;
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc index 981efb4bf..567640f2 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -794,8 +794,8 @@ new_image_data->getColorSettings(); EXPECT_EQ("p3", new_color_settings->colorSpace()); EXPECT_EQ("float32", new_color_settings->storageFormat()); - EXPECT_EQ(image_data->BufferBase()->ByteLength(), - new_image_data->BufferBase()->ByteLength()); + EXPECT_EQ(image_data->BufferBase()->ByteLengthAsSizeT(), + new_image_data->BufferBase()->ByteLengthAsSizeT()); EXPECT_EQ(200, static_cast<unsigned char*>( new_image_data->BufferBase()->Data())[0]); } @@ -850,7 +850,7 @@ new_image_data->getColorSettings(); EXPECT_EQ("p3", new_color_settings->colorSpace()); EXPECT_EQ("float32", new_color_settings->storageFormat()); - EXPECT_EQ(32u, new_image_data->BufferBase()->ByteLength()); + EXPECT_EQ(32u, new_image_data->BufferBase()->ByteLengthAsSizeT()); EXPECT_EQ(200, static_cast<unsigned char*>( new_image_data->BufferBase()->Data())[0]); }
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc index c6fa496e7..7dfcc82 100644 --- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc +++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
@@ -264,7 +264,7 @@ if (DOMArrayBuffer* buffer = V8ArrayBuffer::ToImplWithTypeCheck(isolate, value.V8Value())) { vector.Assign(reinterpret_cast<const unsigned char*>(buffer->Data()), - buffer->ByteLength()); + buffer->ByteLengthAsSizeT()); } return vector; }
diff --git a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc index c6eb591f..deaa1c6 100644 --- a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc +++ b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
@@ -203,7 +203,7 @@ return nullptr; } const char* start = static_cast<const char*>(buffer->Data()); - size_t length = buffer->ByteLength(); + size_t length = buffer->ByteLengthAsSizeT(); return IDBKey::CreateBinary(SharedBuffer::Create(start, length)); } if (value->IsArrayBufferView()) {
diff --git a/third_party/blink/renderer/core/css/font_face.cc b/third_party/blink/renderer/core/css/font_face.cc index 1291405..c627029 100644 --- a/third_party/blink/renderer/core/css/font_face.cc +++ b/third_party/blink/renderer/core/css/font_face.cc
@@ -142,7 +142,7 @@ FontFace* font_face = MakeGarbageCollected<FontFace>(context, family, descriptors); font_face->InitCSSFontFace(static_cast<const unsigned char*>(source->Data()), - source->ByteLength()); + source->ByteLengthAsSizeT()); return font_face; }
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index cc66dbc..ca95f62 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -868,8 +868,22 @@ } ParsedFeaturePolicy container_policy; - if (frame && frame->Owner()) - container_policy = frame->Owner()->GetFramePolicy().container_policy; + + if (frame && frame->Owner()) { + // TODO(chenleihu): Due to the data replication mechanism in + // multi-process site-per-process environment, the container_policy + // value in remote frame owner gets lazily updated only when the next + // navigation is initiated on the remote frame. We need a more robust way + // to enforce the validity of container_policy value. + // https://crbug.com/972089 + if (frame->Owner()->IsRemote()) { + container_policy = frame->Owner()->GetFramePolicy().container_policy; + } else { + container_policy = initializer.GetFramePolicy() + .value_or(FramePolicy()) + .container_policy; + } + } // TODO(icelland): This is problematic querying sandbox flags before // feature policy is initialized.
diff --git a/third_party/blink/renderer/core/dom/document_init.cc b/third_party/blink/renderer/core/dom/document_init.cc index bc4df38..8dfbdd3d 100644 --- a/third_party/blink/renderer/core/dom/document_init.cc +++ b/third_party/blink/renderer/core/dom/document_init.cc
@@ -275,4 +275,10 @@ return *this; } +DocumentInit& DocumentInit::WithFramePolicy( + const base::Optional<FramePolicy>& frame_policy) { + frame_policy_ = frame_policy; + return *this; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document_init.h b/third_party/blink/renderer/core/dom/document_init.h index 21d95304..b7e68d7 100644 --- a/third_party/blink/renderer/core/dom/document_init.h +++ b/third_party/blink/renderer/core/dom/document_init.h
@@ -31,6 +31,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_DOCUMENT_INIT_H_ #include "services/network/public/mojom/ip_address_space.mojom-shared.h" +#include "third_party/blink/public/common/frame/frame_policy.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/execution_context/security_context.h" @@ -139,6 +140,12 @@ return content_security_policy_; } + DocumentInit& WithFramePolicy( + const base::Optional<FramePolicy>& frame_policy); + const base::Optional<FramePolicy>& GetFramePolicy() const { + return frame_policy_; + } + private: DocumentInit(HTMLImportsController*); @@ -205,6 +212,9 @@ network::mojom::IPAddressSpace ip_address_space_ = network::mojom::IPAddressSpace::kUnknown; + + // The frame policy snapshot from the beginning of navigation. + base::Optional<FramePolicy> frame_policy_ = base::nullopt; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/commands/editor_command.cc b/third_party/blink/renderer/core/editing/commands/editor_command.cc index bc78d39d..93776a2 100644 --- a/third_party/blink/renderer/core/editing/commands/editor_command.cc +++ b/third_party/blink/renderer/core/editing/commands/editor_command.cc
@@ -1052,8 +1052,7 @@ const VisibleSelection& selection = CreateVisibleSelection(frame.GetEditor().SelectionForCommand(event)); return (selection.IsCaret() && - (selection.IsContentEditable() || - frame.GetSettings()->GetCaretBrowsingEnabled())) || + (selection.IsContentEditable() || frame.IsCaretBrowsingEnabled())) || selection.IsRange(); } @@ -1069,8 +1068,7 @@ const VisibleSelection& selection = CreateVisibleSelection(frame.GetEditor().SelectionForCommand(event)); return ((selection.IsCaret() && - (selection.IsContentEditable() || - frame.GetSettings()->GetCaretBrowsingEnabled())) || + (selection.IsContentEditable() || frame.IsCaretBrowsingEnabled())) || selection.IsRange()) && !frame.GetEditor().Mark().IsNone(); } @@ -1104,7 +1102,7 @@ static bool EnabledInEditableTextOrCaretBrowsing(LocalFrame& frame, Event* event, EditorCommandSource source) { - return frame.GetSettings()->GetCaretBrowsingEnabled() || + return frame.IsCaretBrowsingEnabled() || EnabledInEditableText(frame, event, source); }
diff --git a/third_party/blink/renderer/core/editing/commands/move_commands.cc b/third_party/blink/renderer/core/editing/commands/move_commands.cc index b84a4707..f11ec20 100644 --- a/third_party/blink/renderer/core/editing/commands/move_commands.cc +++ b/third_party/blink/renderer/core/editing/commands/move_commands.cc
@@ -47,7 +47,7 @@ unsigned MoveCommands::VerticalScrollDistance(LocalFrame& frame) { const Element* focused_element = frame.GetDocument()->FocusedElement(); if (!focused_element) { - if (frame.GetSettings()->GetCaretBrowsingEnabled()) { + if (frame.IsCaretBrowsingEnabled()) { focused_element = frame.GetDocument()->ActiveElement(); } @@ -63,8 +63,7 @@ return 0; if (!(style->OverflowY() == EOverflow::kScroll || style->OverflowY() == EOverflow::kAuto || - HasEditableStyle(*focused_element) || - frame.GetSettings()->GetCaretBrowsingEnabled())) + HasEditableStyle(*focused_element) || frame.IsCaretBrowsingEnabled())) return 0; const ScrollableArea& scrollable_area = *frame.View()->LayoutViewport(); const int height = std::min<int>(layout_box.ClientHeight().ToInt(), @@ -126,7 +125,7 @@ } void MoveCommands::UpdateFocusForCaretBrowsing(LocalFrame& frame) { - if (!frame.GetSettings()->GetCaretBrowsingEnabled()) + if (!frame.IsCaretBrowsingEnabled()) return; SelectionInDOMTree selection = frame.Selection().GetSelectionInDOMTree(); @@ -160,7 +159,7 @@ } void MoveCommands::UpdateSelectionForCaretBrowsing(LocalFrame& frame) { - if (!frame.GetSettings()->GetCaretBrowsingEnabled()) + if (!frame.IsCaretBrowsingEnabled()) return; if (frame.Selection().SelectionHasFocus())
diff --git a/third_party/blink/renderer/core/editing/frame_caret.cc b/third_party/blink/renderer/core/editing/frame_caret.cc index c0aa701..8ef1bff 100644 --- a/third_party/blink/renderer/core/editing/frame_caret.cc +++ b/third_party/blink/renderer/core/editing/frame_caret.cc
@@ -152,7 +152,7 @@ caret_visibility_ == CaretVisibility::kVisible && (IsEditablePosition( selection_editor_->ComputeVisibleSelectionInDOMTree().Start()) || - frame_->GetSettings()->GetCaretBrowsingEnabled()); + frame_->IsCaretBrowsingEnabled()); display_item_client_->UpdateStyleAndLayoutIfNeeded( should_paint_caret ? CaretPosition() : PositionWithAffinity()); @@ -202,7 +202,7 @@ } else { // Caret is not contained in editable content--see if caret browsing is // enabled. If it isn't, don't blink the caret. - if (!frame_->GetSettings()->GetCaretBrowsingEnabled()) + if (!frame_->IsCaretBrowsingEnabled()) return false; }
diff --git a/third_party/blink/renderer/core/editing/frame_selection.cc b/third_party/blink/renderer/core/editing/frame_selection.cc index 6775a112..c14d3bf 100644 --- a/third_party/blink/renderer/core/editing/frame_selection.cc +++ b/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -260,9 +260,8 @@ // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and // "FocusIn", |frame_| may associate to another document. if (!IsAvailable() || GetDocument() != current_document) { - // Once we get test case to reach here, we should change this - // if-statement to |DCHECK()|. - NOTREACHED(); + // editing/selection/move-selection-detached-frame-crash.html reaches + // here. See http://crbug.com/1015710. return; } } @@ -522,7 +521,7 @@ DCHECK(!result || (ComputeVisibleSelectionInDOMTree().IsCaret() && (IsEditablePosition(ComputeVisibleSelectionInDOMTree().Start()) || - frame_->GetSettings()->GetCaretBrowsingEnabled()))); + frame_->IsCaretBrowsingEnabled()))); return result; }
diff --git a/third_party/blink/renderer/core/editing/ime/edit_context.cc b/third_party/blink/renderer/core/editing/ime/edit_context.cc index e17df07..526460a 100644 --- a/third_party/blink/renderer/core/editing/ime/edit_context.cc +++ b/third_party/blink/renderer/core/editing/ime/edit_context.cc
@@ -24,7 +24,7 @@ namespace blink { EditContext::EditContext(ScriptState* script_state, const EditContextInit* dict) - : ContextClient(ExecutionContext::From(script_state)) { + : ContextLifecycleObserver(ExecutionContext::From(script_state)) { DCHECK(IsMainThread()); if (dict->hasText()) @@ -58,26 +58,30 @@ } ExecutionContext* EditContext::GetExecutionContext() const { - return ContextClient::GetExecutionContext(); + return ContextLifecycleObserver::GetExecutionContext(); +} + +bool EditContext::HasPendingActivity() const { + return GetExecutionContext() && HasEventListeners(); } InputMethodController& EditContext::GetInputMethodController() const { - return ContextClient::GetFrame()->GetInputMethodController(); + return ContextLifecycleObserver::GetFrame()->GetInputMethodController(); } void EditContext::DispatchCompositionEndEvent(const String& text) { auto* event = MakeGarbageCollected<CompositionEvent>( - event_type_names::kCompositionend, ContextClient::GetFrame()->DomWindow(), - text); + event_type_names::kCompositionend, + ContextLifecycleObserver::GetFrame()->DomWindow(), text); DispatchEvent(*event); } bool EditContext::DispatchCompositionStartEvent(const String& text) { auto* event = MakeGarbageCollected<CompositionEvent>( event_type_names::kCompositionstart, - ContextClient::GetFrame()->DomWindow(), text); + ContextLifecycleObserver::GetFrame()->DomWindow(), text); DispatchEvent(*event); - if (!ContextClient::GetFrame()) + if (!ContextLifecycleObserver::GetFrame()) return false; return true; } @@ -573,8 +577,9 @@ } void EditContext::Trace(Visitor* visitor) { - EventTarget::Trace(visitor); - ScriptWrappable::Trace(visitor); - ContextClient::Trace(visitor); + ActiveScriptWrappable::Trace(visitor); + ContextLifecycleObserver::Trace(visitor); + EventTargetWithInlineData::Trace(visitor); } + } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/ime/edit_context.h b/third_party/blink/renderer/core/editing/ime/edit_context.h index 2cb9626..38cdc12c 100644 --- a/third_party/blink/renderer/core/editing/ime/edit_context.h +++ b/third_party/blink/renderer/core/editing/ime/edit_context.h
@@ -11,10 +11,10 @@ #include "third_party/blink/public/platform/web_text_input_type.h" #include "third_party/blink/public/web/web_ime_text_span.h" #include "third_party/blink/public/web/web_input_method_controller.h" +#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" namespace blink { @@ -32,7 +32,8 @@ // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/EditContext/explainer.md class CORE_EXPORT EditContext final : public EventTargetWithInlineData, - public ContextClient, + public ActiveScriptWrappable<EditContext>, + public ContextLifecycleObserver, public WebInputMethodController { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(EditContext); @@ -134,9 +135,12 @@ void setInputPanelPolicy(const String& input_policy); // EventTarget overrides - bool HasEventTargetData() const { return has_event_target_data; } const AtomicString& InterfaceName() const override; - ExecutionContext* GetExecutionContext() const final; + ExecutionContext* GetExecutionContext() const override; + + // ActiveScriptWrappable overrides. + bool HasPendingActivity() const override; + void Trace(Visitor*) override; // WebInputMethodController overrides. @@ -231,7 +235,6 @@ ui::TextInputAction enter_key_hint_ = ui::TextInputAction::kEnter; EditContextInputPanelPolicy input_panel_policy_ = EditContextInputPanelPolicy::kManual; - bool has_event_target_data = false; WebRect control_bounds_; WebRect selection_bounds_; // This flag is set when the input method controller receives a
diff --git a/third_party/blink/renderer/core/editing/ime/edit_context.idl b/third_party/blink/renderer/core/editing/ime/edit_context.idl index b3987e60..18bc5d0 100644 --- a/third_party/blink/renderer/core/editing/ime/edit_context.idl +++ b/third_party/blink/renderer/core/editing/ime/edit_context.idl
@@ -10,6 +10,7 @@ Constructor(optional EditContextInit options), ConstructorCallWith=ScriptState, Exposed=Window, + ActiveScriptWrappable, RuntimeEnabled=EditContext ] interface EditContext : EventTarget { void focus();
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index 8c4c45d..0a7e97f 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -586,6 +586,10 @@ devtools->NavigationInitiatorInfo(web_frame_->GetFrame()); } + auto* owner = ToCoreFrame(web_frame_)->Owner(); + navigation_info->frame_policy = + owner ? base::make_optional(owner->GetFramePolicy()) : base::nullopt; + navigation_info->href_translate = href_translate; web_frame_->Client()->BeginNavigation(std::move(navigation_info));
diff --git a/third_party/blink/renderer/core/exported/web_array_buffer.cc b/third_party/blink/renderer/core/exported/web_array_buffer.cc index c16c7413..bff770599 100644 --- a/third_party/blink/renderer/core/exported/web_array_buffer.cc +++ b/third_party/blink/renderer/core/exported/web_array_buffer.cc
@@ -56,7 +56,7 @@ unsigned WebArrayBuffer::ByteLength() const { if (!IsNull()) - return private_->ByteLength(); + return private_->DeprecatedByteLengthAsUnsigned(); return 0; }
diff --git a/third_party/blink/renderer/core/exported/web_navigation_params.cc b/third_party/blink/renderer/core/exported/web_navigation_params.cc index 78f495d1..df6f05c 100644 --- a/third_party/blink/renderer/core/exported/web_navigation_params.cc +++ b/third_party/blink/renderer/core/exported/web_navigation_params.cc
@@ -42,6 +42,7 @@ result->initiator_origin_trial_features = info.initiator_origin_trial_features; result->ip_address_space = info.initiator_address_space; + result->frame_policy = info.frame_policy; return result; }
diff --git a/third_party/blink/renderer/core/fetch/body.cc b/third_party/blink/renderer/core/fetch/body.cc index 1ad4eb2..fcb6d67 100644 --- a/third_party/blink/renderer/core/fetch/body.cc +++ b/third_party/blink/renderer/core/fetch/body.cc
@@ -186,7 +186,7 @@ return ScriptPromise(); } } else { - resolver->Resolve(DOMArrayBuffer::Create(0u, 1)); + resolver->Resolve(DOMArrayBuffer::Create(size_t{0}, size_t{0})); } return promise; }
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc index d171bd5..22adda11b 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
@@ -388,7 +388,7 @@ EXPECT_FALSE(buffer->HasPendingActivity()); ASSERT_TRUE(array_buffer); EXPECT_EQ("hello", String(static_cast<const char*>(array_buffer->Data()), - array_buffer->ByteLength())); + array_buffer->ByteLengthAsSizeT())); } TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsBlob) {
diff --git a/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc b/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc index 41ff1e8..69aa8773 100644 --- a/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc +++ b/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
@@ -356,7 +356,7 @@ ASSERT_TRUE(array_buffer); ASSERT_EQ(kQuickBrownFoxLengthWithTerminatingNull, - array_buffer->ByteLength()); + array_buffer->ByteLengthAsSizeT()); EXPECT_STREQ(kQuickBrownFox, static_cast<const char*>(array_buffer->Data())); }
diff --git a/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc b/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc index b150ffc..0ecffc8e 100644 --- a/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc +++ b/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc
@@ -497,7 +497,8 @@ UTF8Encoding().Encode(string, WTF::kNoUnencodables)))) {} FormDataBytesConsumer::FormDataBytesConsumer(DOMArrayBuffer* buffer) - : FormDataBytesConsumer(buffer->Data(), buffer->ByteLength()) {} + : FormDataBytesConsumer(buffer->Data(), + buffer->DeprecatedByteLengthAsUnsigned()) {} FormDataBytesConsumer::FormDataBytesConsumer(DOMArrayBufferView* view) : FormDataBytesConsumer(view->BaseAddress(), view->byteLength()) {}
diff --git a/third_party/blink/renderer/core/fileapi/blob.cc b/third_party/blink/renderer/core/fileapi/blob.cc index e3701368..835db406 100644 --- a/third_party/blink/renderer/core/fileapi/blob.cc +++ b/third_party/blink/renderer/core/fileapi/blob.cc
@@ -157,7 +157,8 @@ for (const auto& item : parts) { if (item.IsArrayBuffer()) { DOMArrayBuffer* array_buffer = item.GetAsArrayBuffer(); - blob_data->AppendBytes(array_buffer->Data(), array_buffer->ByteLength()); + blob_data->AppendBytes(array_buffer->Data(), + array_buffer->ByteLengthAsSizeT()); } else if (item.IsArrayBufferView()) { DOMArrayBufferView* array_buffer_view = item.GetAsArrayBufferView().View();
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index ab831fd..f9da3c56 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -492,6 +492,10 @@ Frame::DidChangeVisibilityState(); } +bool LocalFrame::IsCaretBrowsingEnabled() const { + return GetSettings() ? GetSettings()->GetCaretBrowsingEnabled() : false; +} + void LocalFrame::HookBackForwardCacheEviction() { // Register a callback dispatched when JavaScript is executed on the frame. // The callback evicts the frame. If a frame is frozen by BackForwardCache,
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 02a1b084..945356f 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -200,6 +200,9 @@ // Returns ContentCaptureManager in LocalFrameRoot. ContentCaptureManager* GetContentCaptureManager(); + // Returns the current state of caret browsing mode. + bool IsCaretBrowsingEnabled() const; + // Activates the user activation states of the |LocalFrame| (provided it's // non-null) and all its ancestors. Also creates a |UserGestureIndicator| // that contains a |UserGestureToken| with the given status.
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc index 13d97cc2..3f16848 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
@@ -52,10 +52,16 @@ // Define the UMA for the primary metric. primary_metric_.uma_counter.reset( new CustomCountHistogram("Blink.MainFrame.UpdateTime", 0, 10000000, 50)); + primary_metric_.pre_fcp_uma_counter.reset(new CustomCountHistogram( + "Blink.MainFrame.UpdateTime.PreFCP", 0, 10000000, 50)); + primary_metric_.post_fcp_uma_counter.reset(new CustomCountHistogram( + "Blink.MainFrame.UpdateTime.PostFCP", 0, 10000000, 50)); // Set up the substrings to create the UMA names const String uma_preamble = "Blink."; const String uma_postscript = ".UpdateTime"; + const String uma_prefcp_postscript = ".PreFCP"; + const String uma_postfcp_postscript = ".PostFCP"; const String uma_percentage_preamble = "Blink.MainFrame."; const String uma_percentage_postscript = "Ratio"; @@ -83,23 +89,34 @@ for (unsigned i = 0; i < (unsigned)kCount; ++i) { const MetricInitializationData& metric_data = metrics_data()[i]; - // Absolute records report the absolute time for each metric, both - // average and worst case. They have an associated UMA too that we - // own and allocate here. + // Absolute records report the absolute time for each metric per frame. + // They also aggregate the time spent in each stage between navigation + // (LocalFrameView resets) and First Contentful Paint. + // They have an associated UMA too that we own and allocate here. auto& absolute_record = absolute_metric_records_.emplace_back(); absolute_record.reset(); - StringBuilder uma_name; - uma_name.Append(uma_preamble); - uma_name.Append(metric_data.name); - uma_name.Append(uma_postscript); if (metric_data.has_uma) { + StringBuilder uma_name; + uma_name.Append(uma_preamble); + uma_name.Append(metric_data.name); + uma_name.Append(uma_postscript); absolute_record.uma_counter.reset(new CustomCountHistogram( uma_name.ToString().Utf8().c_str(), 0, 10000000, 50)); + StringBuilder pre_fcp_uma_name; + pre_fcp_uma_name.Append(uma_name); + pre_fcp_uma_name.Append(uma_prefcp_postscript); + absolute_record.pre_fcp_uma_counter.reset(new CustomCountHistogram( + pre_fcp_uma_name.ToString().Utf8().c_str(), 0, 10000000, 50)); + StringBuilder post_fcp_uma_name; + post_fcp_uma_name.Append(uma_name); + post_fcp_uma_name.Append(uma_postfcp_postscript); + absolute_record.post_fcp_uma_counter.reset(new CustomCountHistogram( + post_fcp_uma_name.ToString().Utf8().c_str(), 0, 10000000, 50)); } - // Percentage records report the ratio of each metric to the primary metric, - // average and worst case. UMA counters are also associated with the - // ratios and we allocate and own them here. + // Percentage records report the ratio of each metric to the primary metric. + // UMA counters are also associated with the ratios and we allocate and own + // them here. auto& percentage_record = main_frame_percentage_records_.emplace_back(); percentage_record.reset(); for (auto bucket_substring : threshold_substrings) { @@ -177,6 +194,10 @@ if (!calls_to_next_forced_style_layout_uma_) { auto& record = absolute_metric_records_[kForcedStyleAndLayout]; record.uma_counter->CountMicroseconds(duration); + if (is_before_fcp_) + record.pre_fcp_uma_counter->CountMicroseconds(duration); + else + record.post_fcp_uma_counter->CountMicroseconds(duration); calls_to_next_forced_style_layout_uma_ = base::RandInt(0, mean_calls_between_forced_style_layout_uma_ * 2); } else { @@ -199,10 +220,16 @@ // the signed 32 counter for number of events in a 30 minute period. So // randomly record with probability 1/100. if (record.uma_counter) { - if (metric_index == static_cast<size_t>(kForcedStyleAndLayout)) + if (metric_index == static_cast<size_t>(kForcedStyleAndLayout)) { RecordForcedStyleLayoutUMA(duration); - else + } else { record.uma_counter->CountMicroseconds(duration); + if (is_before_fcp_) { + record.pre_fcp_uma_counter->CountMicroseconds(duration); + } else { + record.post_fcp_uma_counter->CountMicroseconds(duration); + } + } } // Only record ratios when inside a main frame. @@ -230,6 +257,10 @@ // Record UMA primary_metric_.uma_counter->CountMicroseconds(duration); + if (is_before_fcp_) + primary_metric_.pre_fcp_uma_counter->CountMicroseconds(duration); + else + primary_metric_.post_fcp_uma_counter->CountMicroseconds(duration); // Record primary time information primary_metric_.interval_duration = duration;
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h index d0d399b..e21c5cd 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
@@ -259,6 +259,8 @@ private: struct AbsoluteMetricRecord { std::unique_ptr<CustomCountHistogram> uma_counter; + std::unique_ptr<CustomCountHistogram> pre_fcp_uma_counter; + std::unique_ptr<CustomCountHistogram> post_fcp_uma_counter; // Accumulated at each sample, then reset with a call to // RecordEndOfFrameMetrics.
diff --git a/third_party/blink/renderer/core/html/canvas/image_data.cc b/third_party/blink/renderer/core/html/canvas/image_data.cc index 8c21a4e..9cfd352 100644 --- a/third_party/blink/renderer/core/html/canvas/image_data.cc +++ b/third_party/blink/renderer/core/html/canvas/image_data.cc
@@ -683,8 +683,8 @@ if (pixel_format == kRGBA8CanvasPixelFormat && storage_format == kUint8ClampedArrayStorageFormat) { DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(content); - return DOMUint8ClampedArray::Create(array_buffer, 0, - array_buffer->ByteLength()); + return DOMUint8ClampedArray::Create( + array_buffer, 0, array_buffer->DeprecatedByteLengthAsUnsigned()); } skcms_PixelFormat src_format = skcms_PixelFormat_RGBA_8888;
diff --git a/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js b/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js index 4cb0e033..d89a990 100644 --- a/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js +++ b/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js
@@ -2502,10 +2502,11 @@ ListView.prototype.onClick.call(this, event); var year = this.selectedRow + 1; if (this.selectedRow !== oldSelectedRow) { - var month = this.highlightedMonth ? this.highlightedMonth.month : 0; + // Always start with first month when changing the year. + const month = new Month(year, 0); + this.highlightMonth(month); this.dispatchEvent( - YearListView.EventTypeYearListViewDidSelectMonth, this, - new Month(year, month)); + YearListView.EventTypeYearListViewDidSelectMonth, this, month); this.scrollView.scrollTo(this.selectedRow * YearListCell.GetHeight(), true); } else { var monthButton = enclosingNodeOrSelfWithClass(
diff --git a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc index b052acc1..927a786 100644 --- a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc +++ b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
@@ -69,6 +69,10 @@ growth_limit_cap_ = growth_limit_cap; } +void GridTrack::SetCachedTrackSize(const GridTrackSize& cached_track_size) { + cached_track_size_ = cached_track_size; +} + bool GridTrack::IsGrowthLimitBiggerThanBaseSize() const { return GrowthLimitIsInfinite() || growth_limit_ >= base_size_; } @@ -195,8 +199,12 @@ // We may need to estimate the grid area size before running the track // sizing algorithm in order to perform the pre-layout of orthogonal // items. - GridTrackSize track_size = - WasSetup() ? GetGridTrackSize(direction, track_position) + // We cannot use Tracks(direction)[track_position].CachedTrackSize() + // because Tracks(direction) is empty, since we are either performing + // pre-layout or are running the track sizing algorithm in the opposite + // direction and haven't run it in the desired direction yet. + const GridTrackSize& track_size = + WasSetup() ? CalculateGridTrackSize(direction, track_position) : RawGridTrackSize(direction, track_position); GridLength max_track_size = track_size.MaxTrackBreadth(); if (max_track_size.IsContentSized() || max_track_size.IsFlex() || @@ -394,7 +402,8 @@ algorithm_.GetGrid().GridItemSpan(child, Direction()); LayoutUnit max_breadth; for (const auto& track_position : span) { - GridTrackSize track_size = GetGridTrackSize(Direction(), track_position); + const GridTrackSize& track_size = + GetCachedGridTrackSize(Direction(), track_position); if (!track_size.HasFixedMaxTrackBreadth()) return min_size; max_breadth += ValueForLength(track_size.MaxTrackBreadth().length(), @@ -658,9 +667,10 @@ // not to have to do that. flex_fraction = std::max( flex_fraction, - NormalizedFlexFraction( - all_tracks[track_index], - GetGridTrackSize(direction, track_index).MaxTrackBreadth().Flex())); + NormalizedFlexFraction(all_tracks[track_index], + GetCachedGridTrackSize(direction, track_index) + .MaxTrackBreadth() + .Flex())); } const Grid& grid = algorithm_.GetGrid(); @@ -894,7 +904,7 @@ return false; } -GridTrackSize GridTrackSizingAlgorithm::GetGridTrackSize( +GridTrackSize GridTrackSizingAlgorithm::CalculateGridTrackSize( GridTrackSizingDirection direction, size_t translated_index) const { DCHECK(WasSetup()); @@ -986,8 +996,9 @@ direction_ == kForRows && !layout_grid_->CachedHasDefiniteLogicalHeight(); size_t num_tracks = track_list.size(); for (size_t i = 0; i < num_tracks; ++i) { - GridTrackSize track_size = GetGridTrackSize(direction_, i); + const GridTrackSize& track_size = CalculateGridTrackSize(direction_, i); GridTrack& track = track_list[i]; + track.SetCachedTrackSize(track_size); track.SetBaseSize(InitialBaseSize(track_size)); track.SetGrowthLimit(InitialGrowthLimit(track_size, track.BaseSize())); track.SetInfinitelyGrowable(false); @@ -1019,7 +1030,8 @@ LayoutBox& grid_item, GridTrack& track) { const size_t track_position = span.StartLine(); - GridTrackSize track_size = GetGridTrackSize(direction_, track_position); + const GridTrackSize& track_size = + Tracks(direction_)[track_position].CachedTrackSize(); if (track_size.HasMinContentMinTrackBreadth()) { track.SetBaseSize( @@ -1049,9 +1061,10 @@ bool GridTrackSizingAlgorithm::SpanningItemCrossesFlexibleSizedTracks( const GridSpan& span) const { + const Vector<GridTrack>& track_list = Tracks(direction_); for (const auto& track_position : span) { const GridTrackSize& track_size = - GetGridTrackSize(direction_, track_position); + track_list[track_position].CachedTrackSize(); if (track_size.MinTrackBreadth().IsFlex() || track_size.MaxTrackBreadth().IsFlex()) return true; @@ -1358,8 +1371,8 @@ filtered_tracks.Shrink(0); LayoutUnit spanning_tracks_size; for (const auto& track_position : item_span) { - GridTrackSize track_size = GetGridTrackSize(direction_, track_position); - GridTrack& track = Tracks(direction_)[track_position]; + GridTrack& track = all_tracks[track_position]; + const GridTrackSize& track_size = track.CachedTrackSize(); spanning_tracks_size += TrackSizeForTrackSizeComputationPhase(phase, track, kForbidInfinity); if (!ShouldProcessTrackForTrackSizeComputationPhase(phase, track_size)) @@ -1399,12 +1412,13 @@ } void GridTrackSizingAlgorithm::ResolveIntrinsicTrackSizes() { + Vector<GridTrack>& all_tracks = Tracks(direction_); Vector<GridItemWithSpan> items_sorted_by_increasing_span; if (grid_.HasGridItems()) { HashSet<LayoutBox*> items_set; for (const auto& track_index : content_sized_tracks_index_) { auto iterator = grid_.CreateIterator(direction_, track_index); - GridTrack& track = Tracks(direction_)[track_index]; + GridTrack& track = all_tracks[track_index]; while (auto* grid_item = iterator->NextGridItem()) { if (items_set.insert(grid_item).is_new_entry) { const GridSpan& span = grid_.GridItemSpan(*grid_item, direction_); @@ -1440,7 +1454,7 @@ } for (const auto& track_index : content_sized_tracks_index_) { - GridTrack& track = Tracks(direction_)[track_index]; + GridTrack& track = all_tracks[track_index]; if (track.GrowthLimit() == kInfinity) track.SetGrowthLimit(track.BaseSize()); } @@ -1487,7 +1501,7 @@ double flex_factor_sum = 0; Vector<size_t, 8> flexible_tracks_indexes; for (const auto& track_index : tracks_span) { - GridTrackSize track_size = GetGridTrackSize(direction_, track_index); + const GridTrackSize& track_size = all_tracks[track_index].CachedTrackSize(); if (!track_size.MaxTrackBreadth().IsFlex()) { left_over_space -= all_tracks[track_index].BaseSize(); } else { @@ -1527,7 +1541,7 @@ continue; LayoutUnit base_size = tracks[index].BaseSize(); double flex_factor = - GetGridTrackSize(direction_, index).MaxTrackBreadth().Flex(); + tracks[index].CachedTrackSize().MaxTrackBreadth().Flex(); // treating all such tracks as inflexible. if (base_size > hypothetical_factor_unit_size * flex_factor) { left_over_space -= base_size; @@ -1557,7 +1571,7 @@ const Vector<GridTrack>& all_tracks = Tracks(direction_); for (size_t i = 0; i < num_flex_tracks; ++i) { size_t track_index = flexible_sized_tracks_index_[i]; - auto track_size = GetGridTrackSize(direction_, track_index); + const GridTrackSize& track_size = all_tracks[track_index].CachedTrackSize(); DCHECK(track_size.MaxTrackBreadth().IsFlex()); LayoutUnit old_base_size = all_tracks[track_index].BaseSize(); LayoutUnit new_base_size = std::max( @@ -1768,7 +1782,7 @@ bool GridTrackSizingAlgorithm::TracksAreWiderThanMinTrackBreadth() const { const Vector<GridTrack>& all_tracks = Tracks(direction_); for (size_t i = 0; i < all_tracks.size(); ++i) { - GridTrackSize track_size = GetGridTrackSize(direction_, i); + const GridTrackSize& track_size = all_tracks[i].CachedTrackSize(); if (InitialBaseSize(track_size) > all_tracks[i].BaseSize()) return false; }
diff --git a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h index 6107043..72655cb 100644 --- a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h +++ b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
@@ -66,6 +66,12 @@ } void SetGrowthLimitCap(base::Optional<LayoutUnit>); + const GridTrackSize CachedTrackSize() const { + DCHECK(cached_track_size_.has_value()); + return cached_track_size_.value(); + } + void SetCachedTrackSize(const GridTrackSize&); + private: bool IsGrowthLimitBiggerThanBaseSize() const; void EnsureGrowthLimitIsBiggerThanBaseSize(); @@ -76,6 +82,7 @@ LayoutUnit size_during_distribution_; base::Optional<LayoutUnit> growth_limit_cap_; bool infinitely_growable_; + base::Optional<GridTrackSize> cached_track_size_; }; class GridTrackSizingAlgorithm final { @@ -136,8 +143,8 @@ GridTrackSizingDirection) const; bool IsRelativeSizedTrackAsAuto(const GridTrackSize&, GridTrackSizingDirection) const; - GridTrackSize GetGridTrackSize(GridTrackSizingDirection, - size_t translated_index) const; + GridTrackSize CalculateGridTrackSize(GridTrackSizingDirection, + size_t translated_index) const; GridTrackSize RawGridTrackSize(GridTrackSizingDirection, size_t translated_index) const; @@ -318,9 +325,9 @@ return algorithm_.AvailableSpace(); } - GridTrackSize GetGridTrackSize(GridTrackSizingDirection direction, - size_t translated_index) const { - return algorithm_.GetGridTrackSize(direction, translated_index); + GridTrackSize GetCachedGridTrackSize(GridTrackSizingDirection direction, + size_t translated_index) const { + return algorithm_.Tracks(direction)[translated_index].CachedTrackSize(); } // Helper functions
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc index a6c43df..22199d3 100644 --- a/third_party/blink/renderer/core/layout/layout_block.cc +++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -159,46 +159,7 @@ void LayoutBlock::StyleWillChange(StyleDifference diff, const ComputedStyle& new_style) { - const ComputedStyle* old_style = Style(); - SetIsAtomicInlineLevel(new_style.IsDisplayInlineType()); - - if (old_style && Parent()) { - bool old_style_contains_fixed_position = ComputeIsFixedContainer(old_style); - bool old_style_contains_absolute_position = - ComputeIsAbsoluteContainer(old_style); - bool new_style_contains_fixed_position = - ComputeIsFixedContainer(&new_style); - bool new_style_contains_absolute_position = - ComputeIsAbsoluteContainer(&new_style); - - if ((old_style_contains_fixed_position && - !new_style_contains_fixed_position) || - (old_style_contains_absolute_position && - !new_style_contains_absolute_position)) { - // Clear our positioned objects list. Our absolute and fixed positioned - // descendants will be inserted into our containing block's positioned - // objects list during layout. - RemovePositionedObjects(nullptr, kNewContainingBlock); - } - if (!old_style_contains_absolute_position && - new_style_contains_absolute_position) { - // Remove our absolutely positioned descendants from their current - // containing block. - // They will be inserted into our positioned objects list during layout. - if (LayoutBlock* cb = ContainingBlockForAbsolutePosition()) - cb->RemovePositionedObjects(this, kNewContainingBlock); - } - if (!old_style_contains_fixed_position && - new_style_contains_fixed_position) { - // Remove our fixed positioned descendants from their current containing - // block. - // They will be inserted into our positioned objects list during layout. - if (LayoutBlock* cb = ContainingBlockForFixedPosition()) - cb->RemovePositionedObjects(this, kNewContainingBlock); - } - } - LayoutBox::StyleWillChange(diff, new_style); }
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc index a3b11376..ea7cb84 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -1235,7 +1235,14 @@ // Moving to a different page or column may mean that its height is // different. page_logical_height = PageLogicalHeightForOffset(new_logical_offset); - if (line_height > page_logical_height) { + // We need to insert a break now, either because there's no room for the + // line in the current column / page, or because we have determined that we + // need a break to satisfy widow requirements. + if (ShouldBreakAtLineToAvoidWidow() && + LineBreakToAvoidWidow() == line_index) { + ClearShouldBreakAtLineToAvoidWidow(); + SetDidBreakAtLineToAvoidWidow(); + } else if (line_height > page_logical_height) { // Too tall to fit in one page / column. Give up. Don't push to the next // page / column. // TODO(mstensho): Get rid of this. This is just utter weirdness, but the @@ -1246,14 +1253,6 @@ return; } - // We need to insert a break now, either because there's no room for the - // line in the current column / page, or because we have determined that we - // need a break to satisfy widow requirements. - if (ShouldBreakAtLineToAvoidWidow() && - LineBreakToAvoidWidow() == line_index) { - ClearShouldBreakAtLineToAvoidWidow(); - SetDidBreakAtLineToAvoidWidow(); - } if (ShouldSetStrutOnBlock(*this, line_box, logical_offset, line_index, page_logical_height)) { // Note that when setting the strut on a block, it may be propagated to
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc index d585612..fbaa0da 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -329,9 +329,11 @@ } } - if (old_style && - (could_contain_fixed != CanContainFixedPositionObjects() || - could_contain_absolute != CanContainAbsolutePositionObjects())) { + bool can_contain_fixed = CanContainFixedPositionObjects(); + bool can_contain_absolute = CanContainAbsolutePositionObjects(); + + if (old_style && (could_contain_fixed != can_contain_fixed || + could_contain_absolute != can_contain_absolute)) { // If out of flow element containment changed, then we need to force a // subtree paint property update, since the children elements may now be // referencing a different container. @@ -347,6 +349,32 @@ Layer()->SetNeedsCompositingInputsUpdate(); } + if (old_style && Parent()) { + LayoutBlock* block = FindNonAnonymousContainingBlock(this); + + if ((could_contain_fixed && !can_contain_fixed) || + (could_contain_absolute && !can_contain_absolute)) { + // Clear our positioned objects list. Our absolute and fixed positioned + // descendants will be inserted into our containing block's positioned + // objects list during layout. + block->RemovePositionedObjects(nullptr, kNewContainingBlock); + } + if (!could_contain_absolute && can_contain_absolute) { + // Remove our absolute positioned descendants from their current + // containing block. + // They will be inserted into our positioned objects list during layout. + if (LayoutBlock* cb = block->ContainingBlockForAbsolutePosition()) + cb->RemovePositionedObjects(this, kNewContainingBlock); + } + if (!could_contain_fixed && can_contain_fixed) { + // Remove our fixed positioned descendants from their current containing + // block. + // They will be inserted into our positioned objects list during layout. + if (LayoutBlock* cb = block->ContainingBlockForFixedPosition()) + cb->RemovePositionedObjects(this, kNewContainingBlock); + } + } + if (Layer()) { Layer()->StyleDidChange(diff, old_style); if (had_layer && Layer()->IsSelfPaintingLayer() != layer_was_self_painting)
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc index e011e82..aea0e46 100644 --- a/third_party/blink/renderer/core/layout/layout_inline.cc +++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -311,23 +311,6 @@ } } - bool old_style_is_containing_block = ComputeIsAbsoluteContainer(old_style); - bool new_style_is_containing_block = CanContainAbsolutePositionObjects(); - // If we are changing to/from static, we need to reposition - // out-of-flow positioned descendants. - if (old_style_is_containing_block != new_style_is_containing_block) { - LayoutBlock* abs_containing_block = nullptr; - if (!old_style_is_containing_block) { - abs_containing_block = ContainingBlockForAbsolutePosition(); - } else { - // When position was not static, containingBlockForAbsolutePosition - // for our children is our existing containingBlock. - abs_containing_block = FindNonAnonymousContainingBlock(this); - } - if (abs_containing_block) - abs_containing_block->RemovePositionedObjects(this, kNewContainingBlock); - } - PropagateStyleToAnonymousChildren(); }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h index 72623076..28cdeb5c 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -237,7 +237,7 @@ } WritingMode GetWritingMode() const { - DCHECK_EQ(Type(), kText); + DCHECK(Type() == kText || Type() == kGeneratedText) << this; return Style().GetWritingMode(); }
diff --git a/third_party/blink/renderer/core/layout/shapes/shape.cc b/third_party/blink/renderer/core/layout/shapes/shape.cc index a84d787..1f296d6 100644 --- a/third_party/blink/renderer/core/layout/shapes/shape.cc +++ b/third_party/blink/renderer/core/layout/shapes/shape.cc
@@ -285,8 +285,8 @@ const IntRect& image_rect, const IntRect& margin_rect) { DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents); - DOMUint8ClampedArray* pixel_array = - DOMUint8ClampedArray::Create(array_buffer, 0, array_buffer->ByteLength()); + DOMUint8ClampedArray* pixel_array = DOMUint8ClampedArray::Create( + array_buffer, 0, array_buffer->DeprecatedByteLengthAsUnsigned()); unsigned pixel_array_offset = 3; // Each pixel is four bytes: RGBA. uint8_t alpha_pixel_threshold = threshold * 255;
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index dd512c49..b323e07 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -173,6 +173,7 @@ ip_address_space_ = params_->ip_address_space; grant_load_local_resources_ = params_->grant_load_local_resources; force_fetch_cache_mode_ = params_->force_fetch_cache_mode; + frame_policy_ = params_->frame_policy; WebNavigationTimings& timings = params_->navigation_timings; if (!timings.input_start.is_null()) @@ -1487,6 +1488,7 @@ .WithSrcdocDocument(loading_srcdoc_) .WithBlockedByCSP(was_blocked_by_csp_) .WithGrantLoadLocalResources(grant_load_local_resources_) + .WithFramePolicy(frame_policy_) .WithNewRegistrationContext() .WithFeaturePolicyHeader(feature_policy.ToString()) .WithOriginTrialsHeader(
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index 5c20f73..2cf5fdbf 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -415,6 +415,7 @@ network::mojom::IPAddressSpace::kUnknown; bool grant_load_local_resources_ = false; base::Optional<blink::mojom::FetchCacheMode> force_fetch_cache_mode_; + base::Optional<FramePolicy> frame_policy_; // Params are saved in constructor and are cleared after StartLoading(). // TODO(dgozman): remove once StartLoading is merged with constructor.
diff --git a/third_party/blink/renderer/core/loader/document_loader_test.cc b/third_party/blink/renderer/core/loader/document_loader_test.cc index 06f85701..914a685 100644 --- a/third_party/blink/renderer/core/loader/document_loader_test.cc +++ b/third_party/blink/renderer/core/loader/document_loader_test.cc
@@ -8,6 +8,7 @@ #include "base/auto_reset.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-shared.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_url_loader_client.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" @@ -257,6 +258,31 @@ EXPECT_EQ(KURL("https://example.com"), child_document->Loader()->Url()); } +TEST_F(DocumentLoaderSimTest, FramePolicyIntegrityOnNavigationCommit) { + SimRequest main_resource("https://example.com", "text/html"); + SimRequest iframe_resource("https://example.com/foo.html", "text/html"); + LoadURL("https://example.com"); + + main_resource.Write(R"( + <iframe id='frame1'></iframe> + <script> + const iframe = document.getElementById('frame1'); + iframe.src = 'https://example.com/foo.html'; // navigation triggered + iframe.allow = "payment 'none'"; // should not take effect until the + // next navigation on iframe + </script> + )"); + + main_resource.Finish(); + iframe_resource.Finish(); + + auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild()); + auto* child_document = child_frame->GetFrame()->GetDocument(); + + EXPECT_TRUE(child_document->IsFeatureEnabled( + blink::mojom::FeaturePolicyFeature::kPayment)); +} + TEST_F(DocumentLoaderTest, CommitsDeferredOnSameOriginNavigation) { const KURL& requestor_url = KURL(NullURL(), "https://www.example.com/foo.html");
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 7f07a8b..69d405e 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -206,6 +206,10 @@ auto navigation_params = std::make_unique<WebNavigationParams>(); navigation_params->url = KURL(g_empty_string); + navigation_params->frame_policy = + frame_->Owner() ? base::make_optional(frame_->Owner()->GetFramePolicy()) + : base::nullopt; + provisional_document_loader_ = Client()->CreateDocumentLoader( frame_, kWebNavigationTypeOther, std::move(navigation_params), nullptr /* extra_data */);
diff --git a/third_party/blink/renderer/core/mathml/mathml_attribute_names.json5 b/third_party/blink/renderer/core/mathml/mathml_attribute_names.json5 index a50a993..7e4430d5 100644 --- a/third_party/blink/renderer/core/mathml/mathml_attribute_names.json5 +++ b/third_party/blink/renderer/core/mathml/mathml_attribute_names.json5
@@ -9,5 +9,8 @@ data: [ "definitionURL", "encoding", + "mathbackground", + "mathcolor", + "mathsize", ], }
diff --git a/third_party/blink/renderer/core/mathml/mathml_element.cc b/third_party/blink/renderer/core/mathml/mathml_element.cc index 16cf2e5b..52bb3e3f 100644 --- a/third_party/blink/renderer/core/mathml/mathml_element.cc +++ b/third_party/blink/renderer/core/mathml/mathml_element.cc
@@ -5,6 +5,8 @@ #include "third_party/blink/renderer/core/mathml/mathml_element.h" #include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h" +#include "third_party/blink/renderer/core/css/css_property_name.h" +#include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/html/html_element.h" namespace blink { @@ -16,6 +18,57 @@ MathMLElement::~MathMLElement() {} +static inline bool IsValidDirAttribute(const AtomicString& value) { + return DeprecatedEqualIgnoringCase(value, "ltr") || + DeprecatedEqualIgnoringCase(value, "rtl"); +} + +// Keywords from MathML3 and CSS font-size are skipped. +static inline bool IsDisallowedMathSizeAttribute(const AtomicString& value) { + return DeprecatedEqualIgnoringCase(value, "medium") || + value.EndsWith("large", kTextCaseASCIIInsensitive) || + value.EndsWith("small", kTextCaseASCIIInsensitive) || + DeprecatedEqualIgnoringCase(value, "smaller") || + DeprecatedEqualIgnoringCase(value, "larger"); +} + +bool MathMLElement::IsPresentationAttribute(const QualifiedName& name) const { + // TODO(crbug.com/1023292, crbug.com/1023296): add support for display, + // displaystyle and scriptlevel. + if (name == html_names::kDirAttr || name == mathml_names::kMathsizeAttr || + name == mathml_names::kMathcolorAttr || + name == mathml_names::kMathbackgroundAttr) + return true; + return Element::IsPresentationAttribute(name); +} + +void MathMLElement::CollectStyleForPresentationAttribute( + const QualifiedName& name, + const AtomicString& value, + MutableCSSPropertyValueSet* style) { + // TODO(crbug.com/1023292, crbug.com/1023296): add support for display, + // displaystyle and scriptlevel. + if (name == html_names::kDirAttr) { + if (IsValidDirAttribute(value)) { + AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kDirection, + value); + } + } else if (name == mathml_names::kMathsizeAttr) { + if (!IsDisallowedMathSizeAttribute(value)) { + AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kFontSize, + value); + } + } else if (name == mathml_names::kMathbackgroundAttr) { + AddPropertyToPresentationAttributeStyle( + style, CSSPropertyID::kBackgroundColor, value); + } else if (name == mathml_names::kMathcolorAttr) { + AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kColor, + value); + } else { + Element::CollectStyleForPresentationAttribute(name, value, style); + } +} + void MathMLElement::ParseAttribute(const AttributeModificationParams& param) { const AtomicString& event_name = HTMLElement::EventNameForAttributeName(param.name);
diff --git a/third_party/blink/renderer/core/mathml/mathml_element.h b/third_party/blink/renderer/core/mathml/mathml_element.h index ac9176f..62d6290 100644 --- a/third_party/blink/renderer/core/mathml/mathml_element.h +++ b/third_party/blink/renderer/core/mathml/mathml_element.h
@@ -26,6 +26,11 @@ } private: + bool IsPresentationAttribute(const QualifiedName&) const final; + void CollectStyleForPresentationAttribute(const QualifiedName&, + const AtomicString&, + MutableCSSPropertyValueSet*) final; + void ParseAttribute(const AttributeModificationParams&) final; bool IsMathMLElement() const =
diff --git a/third_party/blink/renderer/core/mojo/mojo_handle.cc b/third_party/blink/renderer/core/mojo/mojo_handle.cc index 02038395..22e24a9 100644 --- a/third_party/blink/renderer/core/mojo/mojo_handle.cc +++ b/third_party/blink/renderer/core/mojo/mojo_handle.cc
@@ -70,7 +70,7 @@ if (buffer.IsArrayBuffer()) { DOMArrayBuffer* array = buffer.GetAsArrayBuffer(); bytes = array->Data(); - num_bytes = array->ByteLength(); + num_bytes = array->ByteLengthAsSizeT(); } else { DOMArrayBufferView* view = buffer.GetAsArrayBufferView().View(); bytes = view->BaseAddress(); @@ -154,7 +154,7 @@ if (buffer.IsArrayBuffer()) { DOMArrayBuffer* array = buffer.GetAsArrayBuffer(); elements = array->Data(); - num_bytes = array->ByteLength(); + num_bytes = array->DeprecatedByteLengthAsUnsigned(); } else { DOMArrayBufferView* view = buffer.GetAsArrayBufferView().View(); elements = view->BaseAddress(); @@ -217,7 +217,7 @@ if (buffer.IsArrayBuffer()) { DOMArrayBuffer* array = buffer.GetAsArrayBuffer(); elements = array->Data(); - num_bytes = array->ByteLength(); + num_bytes = array->DeprecatedByteLengthAsUnsigned(); } else { DOMArrayBufferView* view = buffer.GetAsArrayBufferView().View(); elements = view->BaseAddress();
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc index b355c46..f4816f6 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
@@ -1556,30 +1556,52 @@ </div> )HTML"); - // The initial count should be zero. + // The initial counts should be zero. histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 0); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 0); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 0); - // After an initial compositing update, we should have one scrolling update. + // After an initial compositing update, we should have one scrolling update + // recorded as PreFCP. ForceFullCompositingUpdate(); histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 1); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 0); // An update with no scrolling changes should not cause a scrolling update. ForceFullCompositingUpdate(); histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 1); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 0); // A change to background color does not need to cause a scrolling update but, // because hit test display items paint, we also cause a scrolling coordinator - // update when the background paints. + // update when the background paints. Also render some text to get past FCP. auto* background = GetFrame()->GetDocument()->getElementById("bg"); background->removeAttribute(html_names::kStyleAttr); + background->SetInnerHTMLFromString("Some Text"); ForceFullCompositingUpdate(); histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 2); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 1); // Removing a scrollable area should cause a scrolling update. auto* scroller = GetFrame()->GetDocument()->getElementById("scroller"); scroller->removeAttribute(html_names::kStyleAttr); ForceFullCompositingUpdate(); histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 3); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1); + histogram_tester.ExpectTotalCount( + "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 2); } TEST_P(ScrollingCoordinatorTest, NonCompositedNonFastScrollableRegion) {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index fe6ea2c0..e208faa 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -2353,6 +2353,18 @@ if (layer_->Size().IsEmpty()) return false; + const auto* box = GetLayoutBox(); + + // Although trivial 3D transforms are not always a direct compositing reason + // (see CompositingReasonFinder::RequiresCompositingFor3DTransform), we treat + // them as one for composited scrolling. This is because of the amount of + // content that depends on this optimization, and because of the long-term + // desire to use composited scrolling whenever possible. + if (box->HasTransformRelatedProperty() && + box->StyleRef().Has3DTransformOperation()) { + return true; + } + if (!force_prefer_compositing_to_lcd_text && !LayerNodeMayNeedCompositedScrolling(layer_)) { return false; @@ -2362,7 +2374,6 @@ // TODO(flackr): Allow integer transforms as long as all of the ancestor // transforms are also integer. - const LayoutBox* box = GetLayoutBox(); bool background_supports_lcd_text = box->StyleRef().IsStackingContext() && (box->GetBackgroundPaintLocation(
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc index aa29b73..ba3c97a7 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -4,7 +4,9 @@ #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" +#include "base/test/scoped_feature_list.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" @@ -1287,4 +1289,55 @@ EXPECT_NE(paint_layer->GetScrollableArea()->Resizer(), nullptr); } +class PaintLayerScrollableAreaCompositingTest + : public PaintLayerScrollableAreaTestBase, + public testing::WithParamInterface<unsigned>, + private ScopedCompositeAfterPaintForTest { + public: + PaintLayerScrollableAreaCompositingTest() + : ScopedCompositeAfterPaintForTest(GetParam() & kCompositeAfterPaint) { + if (GetParam() & kDoNotCompositeTrivial3D) { + scoped_feature_list_.InitAndEnableFeature( + blink::features::kDoNotCompositeTrivial3D); + } else { + scoped_feature_list_.InitAndDisableFeature( + blink::features::kDoNotCompositeTrivial3D); + } + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +INSTANTIATE_DO_NOT_COMPOSITE_TRIVIAL_3D_P( + PaintLayerScrollableAreaCompositingTest); + +// Test that a trivial 3D transform results in composited scrolling. +TEST_P(PaintLayerScrollableAreaCompositingTest, CompositeWithTrivial3D) { + SetBodyInnerHTML(R"HTML( + <style> + #scroller { + width: 100px; + height: 100px; + overflow: scroll; + transform: translateZ(0); + } + #scrolled { + width: 200px; + height: 200px; + } + </style> + <div id="scroller"> + <div id="scrolled"></div> + </div> + )HTML"); + + LayoutBox* scroller = ToLayoutBox(GetLayoutObjectByElementId("scroller")); + PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + EXPECT_TRUE(scrollable_area->NeedsCompositedScrolling()); + const auto* properties = scroller->FirstFragment().PaintProperties(); + EXPECT_TRUE(properties->ScrollTranslation()->HasDirectCompositingReasons()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 4e2b22f..0d2cc62 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -2795,7 +2795,7 @@ scoped_refptr<SerializedScriptValue> Internals::deserializeBuffer( DOMArrayBuffer* buffer) const { return SerializedScriptValue::Create(static_cast<const char*>(buffer->Data()), - buffer->ByteLength()); + buffer->ByteLengthAsSizeT()); } DOMArrayBuffer* Internals::serializeWithInlineWasm(ScriptValue value) const {
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h index af65667..0056be39 100644 --- a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h +++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h
@@ -44,27 +44,27 @@ USING_FAST_MALLOC(ArrayBuffer); public: - static inline scoped_refptr<ArrayBuffer> Create(unsigned num_elements, - unsigned element_byte_size); + static inline scoped_refptr<ArrayBuffer> Create(size_t num_elements, + size_t element_byte_size); static inline scoped_refptr<ArrayBuffer> Create(ArrayBuffer*); static inline scoped_refptr<ArrayBuffer> Create(const void* source, size_t byte_length); static inline scoped_refptr<ArrayBuffer> Create(ArrayBufferContents&); static inline scoped_refptr<ArrayBuffer> CreateOrNull( - unsigned num_elements, - unsigned element_byte_size); + size_t num_elements, + size_t element_byte_size); // Only for use by DOMArrayBuffer::CreateUninitializedOrNull(). static inline scoped_refptr<ArrayBuffer> CreateUninitializedOrNull( - unsigned num_elements, - unsigned element_byte_size); + size_t num_elements, + size_t element_byte_size); static inline scoped_refptr<ArrayBuffer> CreateShared( - unsigned num_elements, - unsigned element_byte_size); + size_t num_elements, + size_t element_byte_size); static inline scoped_refptr<ArrayBuffer> CreateShared(const void* source, - unsigned byte_length); + size_t byte_length); inline void* Data(); inline const void* Data() const; @@ -98,16 +98,16 @@ private: static inline scoped_refptr<ArrayBuffer> Create( - unsigned num_elements, - unsigned element_byte_size, + size_t num_elements, + size_t element_byte_size, ArrayBufferContents::InitializationPolicy); static inline scoped_refptr<ArrayBuffer> CreateOrNull( - unsigned num_elements, - unsigned element_byte_size, + size_t num_elements, + size_t element_byte_size, ArrayBufferContents::InitializationPolicy); static inline scoped_refptr<ArrayBuffer> CreateShared( - unsigned num_elements, - unsigned element_byte_size, + size_t num_elements, + size_t element_byte_size, ArrayBufferContents::InitializationPolicy); inline unsigned ClampIndex(unsigned index) const; @@ -117,8 +117,8 @@ bool is_detached_; }; -scoped_refptr<ArrayBuffer> ArrayBuffer::Create(unsigned num_elements, - unsigned element_byte_size) { +scoped_refptr<ArrayBuffer> ArrayBuffer::Create(size_t num_elements, + size_t element_byte_size) { return Create(num_elements, element_byte_size, ArrayBufferContents::kZeroInitialize); } @@ -146,23 +146,22 @@ return base::AdoptRef(new ArrayBuffer(contents)); } -scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull( - unsigned num_elements, - unsigned element_byte_size) { +scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull(size_t num_elements, + size_t element_byte_size) { return CreateOrNull(num_elements, element_byte_size, ArrayBufferContents::kZeroInitialize); } scoped_refptr<ArrayBuffer> ArrayBuffer::CreateUninitializedOrNull( - unsigned num_elements, - unsigned element_byte_size) { + size_t num_elements, + size_t element_byte_size) { return CreateOrNull(num_elements, element_byte_size, ArrayBufferContents::kDontInitialize); } scoped_refptr<ArrayBuffer> ArrayBuffer::Create( - unsigned num_elements, - unsigned element_byte_size, + size_t num_elements, + size_t element_byte_size, ArrayBufferContents::InitializationPolicy policy) { ArrayBufferContents contents(num_elements, element_byte_size, ArrayBufferContents::kNotShared, policy); @@ -172,8 +171,8 @@ } scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull( - unsigned num_elements, - unsigned element_byte_size, + size_t num_elements, + size_t element_byte_size, ArrayBufferContents::InitializationPolicy policy) { ArrayBufferContents contents(num_elements, element_byte_size, ArrayBufferContents::kNotShared, policy); @@ -182,15 +181,14 @@ return base::AdoptRef(new ArrayBuffer(contents)); } -scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared( - unsigned num_elements, - unsigned element_byte_size) { +scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(size_t num_elements, + size_t element_byte_size) { return CreateShared(num_elements, element_byte_size, ArrayBufferContents::kZeroInitialize); } scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(const void* source, - unsigned byte_length) { + size_t byte_length) { ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kShared, ArrayBufferContents::kDontInitialize); CHECK(contents.DataShared()); @@ -200,8 +198,8 @@ } scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared( - unsigned num_elements, - unsigned element_byte_size, + size_t num_elements, + size_t element_byte_size, ArrayBufferContents::InitializationPolicy policy) { ArrayBufferContents contents(num_elements, element_byte_size, ArrayBufferContents::kShared, policy);
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc index bf7452e..5dd94539 100644 --- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc +++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
@@ -41,8 +41,8 @@ ArrayBufferContents& result) { DOMArrayBuffer* to_transfer = this; if (!IsDetachable(isolate)) { - to_transfer = DOMArrayBuffer::Create(Buffer()->Data(), - Buffer()->ByteLengthAsUnsigned()); + to_transfer = + DOMArrayBuffer::Create(Buffer()->Data(), Buffer()->ByteLengthAsSizeT()); } if (!to_transfer->Buffer()->Transfer(result)) @@ -59,8 +59,8 @@ } DOMArrayBuffer* DOMArrayBuffer::CreateUninitializedOrNull( - unsigned num_elements, - unsigned element_byte_size) { + size_t num_elements, + size_t element_byte_size) { scoped_refptr<ArrayBuffer> buffer = ArrayBuffer::CreateUninitializedOrNull(num_elements, element_byte_size); if (!buffer) @@ -78,7 +78,7 @@ v8::Local<v8::Object> wrapper; { v8::Context::Scope context_scope(creation_context->CreationContext()); - wrapper = v8::ArrayBuffer::New(isolate, Data(), ByteLength()); + wrapper = v8::ArrayBuffer::New(isolate, Data(), ByteLengthAsSizeT()); } return AssociateWithWrapper(isolate, wrapper_type_info, wrapper);
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h index b3cb9e0..0b47bc1 100644 --- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h +++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
@@ -20,11 +20,10 @@ static DOMArrayBuffer* Create(scoped_refptr<ArrayBuffer> buffer) { return MakeGarbageCollected<DOMArrayBuffer>(std::move(buffer)); } - static DOMArrayBuffer* Create(unsigned num_elements, - unsigned element_byte_size) { + static DOMArrayBuffer* Create(size_t num_elements, size_t element_byte_size) { return Create(ArrayBuffer::Create(num_elements, element_byte_size)); } - static DOMArrayBuffer* Create(const void* source, unsigned byte_length) { + static DOMArrayBuffer* Create(const void* source, size_t byte_length) { return Create(ArrayBuffer::Create(source, byte_length)); } static DOMArrayBuffer* Create(ArrayBufferContents& contents) { @@ -36,8 +35,8 @@ // Only for use by XMLHttpRequest::responseArrayBuffer, // Internals::serializeObject, and // FetchDataLoaderAsArrayBuffer::OnStateChange. - static DOMArrayBuffer* CreateUninitializedOrNull(unsigned num_elements, - unsigned element_byte_size); + static DOMArrayBuffer* CreateUninitializedOrNull(size_t num_elements, + size_t element_byte_size); explicit DOMArrayBuffer(scoped_refptr<ArrayBuffer> buffer) : DOMArrayBufferBase(std::move(buffer)) {}
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h index fa42233d..150510b 100644 --- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h +++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h
@@ -21,7 +21,17 @@ const void* Data() const { return Buffer()->Data(); } void* Data() { return Buffer()->Data(); } - unsigned ByteLength() const { return Buffer()->ByteLengthAsUnsigned(); } + + size_t ByteLengthAsSizeT() const { return Buffer()->ByteLengthAsSizeT(); } + + // This function is deprecated and should not be used. Use {ByteLengthAsSizeT} + // instead. + unsigned DeprecatedByteLengthAsUnsigned() const { + size_t size = ByteLengthAsSizeT(); + CHECK_LE(size, static_cast<size_t>(std::numeric_limits<unsigned>::max())); + return static_cast<unsigned>(size); + } + bool IsDetached() const { return Buffer()->IsDetached(); } bool IsShared() const { return Buffer()->IsShared(); }
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h b/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h index 98e910a4..a1ebc959c 100644 --- a/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h +++ b/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h
@@ -42,7 +42,7 @@ InitWithUnionOption = kTreatNullAsNull); bool operator==(const DOMArrayBuffer& other) const { - return ByteLength() == other.ByteLength() && + return ByteLength() == other.DeprecatedByteLengthAsUnsigned() && memcmp(Data(), other.Data(), ByteLength()) == 0; }
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc b/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc index aeee1b2..2aaa4b83 100644 --- a/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc +++ b/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc
@@ -14,8 +14,8 @@ DCHECK(!DOMDataStore::ContainsWrapper(this, isolate)); const WrapperTypeInfo* wrapper_type_info = this->GetWrapperTypeInfo(); - v8::Local<v8::Object> wrapper = - v8::SharedArrayBuffer::New(isolate, Buffer()->DataShared(), ByteLength()); + v8::Local<v8::Object> wrapper = v8::SharedArrayBuffer::New( + isolate, Buffer()->DataShared(), ByteLengthAsSizeT()); return AssociateWithWrapper(isolate, wrapper_type_info, wrapper); }
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc index dbaee70..cee86385b 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -429,7 +429,7 @@ binary_response_builder_->size(), 1); if (buffer) { bool result = binary_response_builder_->GetBytes( - buffer->Data(), static_cast<size_t>(buffer->ByteLength())); + buffer->Data(), buffer->ByteLengthAsSizeT()); DCHECK(result); response_array_buffer_ = buffer; } @@ -923,7 +923,7 @@ ExceptionState& exception_state) { NETWORK_DVLOG(1) << this << " send() ArrayBuffer " << body; - SendBytesData(body->Data(), body->ByteLength(), exception_state); + SendBytesData(body->Data(), body->ByteLengthAsSizeT(), exception_state); } void XMLHttpRequest::send(DOMArrayBufferView* body,
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc index e4b240c..6447ca4c 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -458,9 +458,10 @@ auto blob_data = std::make_unique<BlobData>(); blob_data->SetContentType(mime_type_); - blob_data->AppendBytes(array_buffer->Data(), array_buffer->ByteLength()); + blob_data->AppendBytes(array_buffer->Data(), + array_buffer->ByteLengthAsSizeT()); batch_operation->response->blob = BlobDataHandle::Create( - std::move(blob_data), array_buffer->ByteLength()); + std::move(blob_data), array_buffer->ByteLengthAsSizeT()); scoped_refptr<CachedMetadata> cached_metadata = GenerateFullCodeCache(array_buffer); @@ -520,7 +521,7 @@ return V8CodeCache::GenerateFullCodeCache( script_state_, text_decoder->Decode(static_cast<const char*>(array_buffer->Data()), - array_buffer->ByteLength()), + array_buffer->ByteLengthAsSizeT()), url_, text_decoder->Encoding(), opaque_mode_); }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index b16a090..9245e2cb 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -1632,7 +1632,7 @@ ImageData* imageData = ImageData::Create( image_data_rect.Size(), NotShared<DOMUint8ClampedArray>(DOMUint8ClampedArray::Create( - array_buffer, 0, array_buffer->ByteLength())), + array_buffer, 0, array_buffer->DeprecatedByteLengthAsUnsigned())), color_settings); if (!IsPaint2D()) {
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc index 9591363..6244ac5 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
@@ -33,8 +33,8 @@ DOMArrayBuffer* png_data) override { DCHECK(!IsMainThread()); std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create( - SegmentReader::CreateFromSkData( - SkData::MakeWithoutCopy(png_data->Data(), png_data->ByteLength())), + SegmentReader::CreateFromSkData(SkData::MakeWithoutCopy( + png_data->Data(), png_data->ByteLengthAsSizeT())), true, ImageDecoder::kAlphaPremultiplied, ImageDecoder::kDefaultBitDepth, ColorBehavior::Tag()); sk_sp<SkImage> image = nullptr; @@ -77,7 +77,7 @@ String wtf_string = String::FromUTF8(reinterpret_cast<const LChar*>(raw_data->Data()), - raw_data->ByteLength()); + raw_data->ByteLengthAsSizeT()); DCHECK(wtf_string.IsSafeToSendToAnotherThread()); PostCrossThreadTask( *task_runner, FROM_HERE,
diff --git a/third_party/blink/renderer/modules/compression/deflate_transformer.cc b/third_party/blink/renderer/modules/compression/deflate_transformer.cc index abc8186..65327f5 100644 --- a/third_party/blink/renderer/modules/compression/deflate_transformer.cc +++ b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
@@ -73,7 +73,7 @@ DCHECK(buffer_source.IsArrayBuffer()); const auto* array_buffer = buffer_source.GetAsArrayBuffer(); const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data()); - wtf_size_t length = array_buffer->ByteLength(); + wtf_size_t length = array_buffer->DeprecatedByteLengthAsUnsigned(); Deflate(start, length, IsFinished(false), controller, exception_state); return ScriptPromise::CastUndefined(script_state_);
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.cc b/third_party/blink/renderer/modules/compression/inflate_transformer.cc index ef9fa2b..fa873be 100644 --- a/third_party/blink/renderer/modules/compression/inflate_transformer.cc +++ b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
@@ -70,7 +70,7 @@ DCHECK(buffer_source.IsArrayBuffer()); const auto* array_buffer = buffer_source.GetAsArrayBuffer(); const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data()); - wtf_size_t length = array_buffer->ByteLength(); + wtf_size_t length = array_buffer->DeprecatedByteLengthAsUnsigned(); Inflate(start, length, IsFinished(false), controller, exception_state); return ScriptPromise::CastUndefined(script_state_);
diff --git a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc index c9274ba8..e0229ee 100644 --- a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc +++ b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
@@ -173,7 +173,7 @@ const blink::ArrayBufferOrArrayBufferView& buffer, unsigned length) { if (buffer.IsArrayBuffer() && - (buffer.GetAsArrayBuffer()->ByteLength() != length)) { + (buffer.GetAsArrayBuffer()->DeprecatedByteLengthAsUnsigned() != length)) { return Vector<uint8_t>(); } @@ -193,7 +193,7 @@ Vector<uint8_t> vector; if (buffer.IsArrayBuffer()) { vector.Append(static_cast<uint8_t*>(buffer.GetAsArrayBuffer()->Data()), - buffer.GetAsArrayBuffer()->ByteLength()); + buffer.GetAsArrayBuffer()->DeprecatedByteLengthAsUnsigned()); } else { DCHECK(buffer.IsArrayBufferView()); vector.Append(static_cast<uint8_t*>(
diff --git a/third_party/blink/renderer/modules/encoding/text_decoder.cc b/third_party/blink/renderer/modules/encoding/text_decoder.cc index 5dd63192..2b24a83 100644 --- a/third_party/blink/renderer/modules/encoding/text_decoder.cc +++ b/third_party/blink/renderer/modules/encoding/text_decoder.cc
@@ -91,7 +91,7 @@ DCHECK(input.IsArrayBuffer()); const char* start = static_cast<const char*>(input.GetAsArrayBuffer()->Data()); - uint32_t length = input.GetAsArrayBuffer()->ByteLength(); + uint32_t length = input.GetAsArrayBuffer()->DeprecatedByteLengthAsUnsigned(); return decode(start, length, options, exception_state); }
diff --git a/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc b/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc index 77c5d7f..be34feb7 100644 --- a/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc +++ b/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc
@@ -62,7 +62,7 @@ DCHECK(bufferSource.IsArrayBuffer()); const auto* array_buffer = bufferSource.GetAsArrayBuffer(); const char* start = static_cast<const char*>(array_buffer->Data()); - uint32_t length = array_buffer->ByteLength(); + uint32_t length = array_buffer->DeprecatedByteLengthAsUnsigned(); DecodeAndEnqueue(start, length, WTF::FlushBehavior::kDoNotFlush, controller, exception_state);
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc index c72276e1..f58ae9c9 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc
@@ -517,7 +517,7 @@ // initializeNewSession() in Chromium will execute steps 10.1 to 10.9. session_->InitializeNewSession( init_data_type, static_cast<unsigned char*>(init_data_buffer->Data()), - init_data_buffer->ByteLength(), session_type_, result->Result()); + init_data_buffer->ByteLengthAsSizeT(), session_type_, result->Result()); // Remaining steps (10.10) executed in finishGenerateRequest(), // called when |result| is resolved. @@ -732,7 +732,7 @@ // update() in Chromium will execute steps 6.1 through 6.8. session_->Update(static_cast<unsigned char*>(sanitized_response->Data()), - sanitized_response->ByteLength(), result->Result()); + sanitized_response->ByteLengthAsSizeT(), result->Result()); // Last step (6.8.2 Resolve promise) will be done when |result| is resolved. }
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc index a0655337..a81720d 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc
@@ -45,15 +45,15 @@ return b->KeyId(); // Compare the bytes. - int result = - memcmp(a->KeyId()->Data(), b->KeyId()->Data(), - std::min(a->KeyId()->ByteLength(), b->KeyId()->ByteLength())); + int result = memcmp(a->KeyId()->Data(), b->KeyId()->Data(), + std::min(a->KeyId()->ByteLengthAsSizeT(), + b->KeyId()->ByteLengthAsSizeT())); if (result != 0) return result < 0; // KeyIds are equal to the shared length, so the shorter string is <. - DCHECK_NE(a->KeyId()->ByteLength(), b->KeyId()->ByteLength()); - return a->KeyId()->ByteLength() < b->KeyId()->ByteLength(); + DCHECK_NE(a->KeyId()->ByteLengthAsSizeT(), b->KeyId()->ByteLengthAsSizeT()); + return a->KeyId()->ByteLengthAsSizeT() < b->KeyId()->ByteLengthAsSizeT(); } virtual void Trace(blink::Visitor* visitor) { visitor->Trace(key_id_); }
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc b/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc index 6197e7c..e243b5c 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
@@ -323,7 +323,7 @@ // 5.2 Use the cdm to process certificate. cdm->SetServerCertificate( static_cast<unsigned char*>(server_certificate->Data()), - server_certificate->ByteLength(), result->Result()); + server_certificate->ByteLengthAsSizeT(), result->Result()); // 5.3 If any of the preceding steps failed, reject promise with a // new DOMException whose name is the appropriate error name.
diff --git a/third_party/blink/renderer/modules/hid/hid_device.cc b/third_party/blink/renderer/modules/hid/hid_device.cc index d06e235..1c76028 100644 --- a/third_party/blink/renderer/modules/hid/hid_device.cc +++ b/third_party/blink/renderer/modules/hid/hid_device.cc
@@ -37,7 +37,7 @@ Vector<uint8_t> vector; if (buffer.IsArrayBuffer()) { vector.Append(static_cast<uint8_t*>(buffer.GetAsArrayBuffer()->Data()), - buffer.GetAsArrayBuffer()->ByteLength()); + buffer.GetAsArrayBuffer()->DeprecatedByteLengthAsUnsigned()); } else { vector.Append(static_cast<uint8_t*>( buffer.GetAsArrayBufferView().View()->BaseAddress()),
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/third_party/blink/renderer/modules/indexeddb/idb_database.cc index ba4706eb..3ff8a99 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_database.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -31,7 +31,7 @@ #include "base/atomic_sequence_num.h" #include "base/optional.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_idb_observer_callback.h" @@ -613,19 +613,21 @@ return ContextLifecycleObserver::GetExecutionContext(); } -STATIC_ASSERT_ENUM(kWebIDBDatabaseExceptionUnknownError, +STATIC_ASSERT_ENUM(mojom::blink::IDBException::kNoError, + DOMExceptionCode::kNoError); +STATIC_ASSERT_ENUM(mojom::blink::IDBException::kUnknownError, DOMExceptionCode::kUnknownError); -STATIC_ASSERT_ENUM(kWebIDBDatabaseExceptionConstraintError, +STATIC_ASSERT_ENUM(mojom::blink::IDBException::kConstraintError, DOMExceptionCode::kConstraintError); -STATIC_ASSERT_ENUM(kWebIDBDatabaseExceptionDataError, +STATIC_ASSERT_ENUM(mojom::blink::IDBException::kDataError, DOMExceptionCode::kDataError); -STATIC_ASSERT_ENUM(kWebIDBDatabaseExceptionVersionError, +STATIC_ASSERT_ENUM(mojom::blink::IDBException::kVersionError, DOMExceptionCode::kVersionError); -STATIC_ASSERT_ENUM(kWebIDBDatabaseExceptionAbortError, +STATIC_ASSERT_ENUM(mojom::blink::IDBException::kAbortError, DOMExceptionCode::kAbortError); -STATIC_ASSERT_ENUM(kWebIDBDatabaseExceptionQuotaError, +STATIC_ASSERT_ENUM(mojom::blink::IDBException::kQuotaError, DOMExceptionCode::kQuotaExceededError); -STATIC_ASSERT_ENUM(kWebIDBDatabaseExceptionTimeoutError, +STATIC_ASSERT_ENUM(mojom::blink::IDBException::kTimeoutError, DOMExceptionCode::kTimeoutError); } // namespace blink
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc index 82efc3f..c7b06b4c 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
@@ -95,7 +95,7 @@ void SetState(base::WeakPtr<WebIDBCursorImpl> cursor, int64_t transaction_id) override {} - void Error(int32_t code, const String& message) override { + void Error(mojom::blink::IDBException code, const String& message) override { if (!promise_resolver_) return;
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_factory_test.cc b/third_party/blink/renderer/modules/indexeddb/idb_factory_test.cc index e9849e00..3696404 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_factory_test.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_factory_test.cc
@@ -105,7 +105,7 @@ EXPECT_FALSE(on_fulfilled); EXPECT_FALSE(on_rejected); - callbacks->Error(0, String()); + callbacks->Error(mojom::blink::IDBException::kNoError, String()); EXPECT_FALSE(on_fulfilled); EXPECT_FALSE(on_rejected);
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc index 4b374f0..fced38c2 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/modules/indexeddb/idb_request_loader.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h"
diff --git a/third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.cc b/third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.cc index 9263a35..d9723ec 100644 --- a/third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.cc
@@ -31,7 +31,7 @@ } void IndexedDBDatabaseCallbacksImpl::Abort(int64_t transaction_id, - int32_t code, + mojom::blink::IDBException code, const String& message) { callbacks_->OnAbort( transaction_id,
diff --git a/third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.h b/third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.h index 702ea69..0a88c40 100644 --- a/third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.h +++ b/third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.h
@@ -26,7 +26,7 @@ void ForcedClose() override; void VersionChange(int64_t old_version, int64_t new_version) override; void Abort(int64_t transaction_id, - int32_t code, + mojom::blink::IDBException code, const WTF::String& message) override; void Complete(int64_t transaction_id) override; void Changes(mojom::blink::IDBObserverChangesPtr changes) override;
diff --git a/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h b/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h index c89042a..2fa7960c 100644 --- a/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h +++ b/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h
@@ -26,7 +26,7 @@ void SetState(base::WeakPtr<WebIDBCursorImpl>, int64_t); - MOCK_METHOD2(Error, void(int32_t, const String&)); + MOCK_METHOD2(Error, void(mojom::blink::IDBException, const String&)); void SuccessCursorContinue( std::unique_ptr<IDBKey>,
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc index 25fc617..e517aa4 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc
@@ -33,7 +33,6 @@ #include "base/memory/ptr_util.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/modules/indexed_db_names.h" @@ -104,7 +103,8 @@ transaction_id_ = transaction_id; } -void WebIDBCallbacksImpl::Error(int32_t code, const String& message) { +void WebIDBCallbacksImpl::Error(mojom::blink::IDBException code, + const String& message) { if (!request_) return; @@ -112,7 +112,7 @@ // destroys all pending tasks. If our callback was queued with a task that // gets cleared, we'll get a signal with an IgnorableAbortError as the task is // torn down. This means the error response can be safely ignored. - if (code == kWebIDBDatabaseExceptionIgnorableAbortError) { + if (code == mojom::blink::IDBException::kIgnorableAbortError) { Detach(); return; }
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h index 8ec637d..8c62e502 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h
@@ -33,7 +33,7 @@ #include "base/memory/weak_ptr.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/renderer/core/probe/async_task_id.h" #include "third_party/blink/renderer/modules/indexeddb/web_idb_callbacks.h" #include "third_party/blink/renderer/platform/heap/persistent.h" @@ -63,7 +63,7 @@ int64_t transaction_id) override; // Pointers transfer ownership. - void Error(int32_t code, const String& message) override; + void Error(mojom::blink::IDBException code, const String& message) override; void SuccessNamesAndVersionsList( Vector<mojom::blink::IDBNameAndVersionPtr>) override; void SuccessStringList(const Vector<String>&) override;
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc index e5605043..1bdee8792 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc
@@ -8,7 +8,7 @@ #include "base/single_thread_task_runner.h" #include "mojo/public/cpp/bindings/self_owned_associated_receiver.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_dispatcher.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -69,7 +69,7 @@ callbacks.reset(); return; } else if (result->is_empty()) { - callbacks->Error(blink::kWebIDBDatabaseExceptionUnknownError, + callbacks->Error(blink::mojom::IDBException::kUnknownError, "Invalid response"); callbacks.reset(); return; @@ -78,7 +78,7 @@ if (result->get_values()->keys.size() != 1u || result->get_values()->primary_keys.size() != 1u || result->get_values()->values.size() != 1u) { - callbacks->Error(blink::kWebIDBDatabaseExceptionUnknownError, + callbacks->Error(blink::mojom::IDBException::kUnknownError, "Invalid response"); callbacks.reset(); return; @@ -153,7 +153,7 @@ callbacks.reset(); return; } else if (result->is_empty()) { - callbacks->Error(blink::kWebIDBDatabaseExceptionUnknownError, + callbacks->Error(blink::mojom::IDBException::kUnknownError, "Invalid response"); callbacks.reset(); return; @@ -162,7 +162,7 @@ if (result->get_values()->keys.size() != 1u || result->get_values()->primary_keys.size() != 1u || result->get_values()->values.size() != 1u) { - callbacks->Error(blink::kWebIDBDatabaseExceptionUnknownError, + callbacks->Error(blink::mojom::IDBException::kUnknownError, "Invalid response"); callbacks.reset(); return; @@ -190,7 +190,7 @@ callbacks.reset(); return; } else if (result->is_empty()) { - callbacks->Error(blink::kWebIDBDatabaseExceptionUnknownError, + callbacks->Error(blink::mojom::IDBException::kUnknownError, "Invalid response"); callbacks.reset(); return; @@ -200,7 +200,7 @@ result->get_values()->primary_keys.size() || result->get_values()->keys.size() != result->get_values()->values.size()) { - callbacks->Error(blink::kWebIDBDatabaseExceptionUnknownError, + callbacks->Error(blink::mojom::IDBException::kUnknownError, "Invalid response"); callbacks.reset(); return;
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc index ce509c8..b99decb0 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc
@@ -6,7 +6,7 @@ #include "base/format_macros.h" #include "mojo/public/cpp/bindings/self_owned_associated_receiver.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" #include "third_party/blink/renderer/modules/indexeddb/idb_database_error.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h"
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.cc index 15d5a1f..13b7d55 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.cc
@@ -9,7 +9,7 @@ #include "base/format_macros.h" #include "mojo/public/cpp/bindings/strong_associated_binding.h" -#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/indexeddb/idb_database_error.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" @@ -64,7 +64,7 @@ value->DataSize() + primary_key->SizeEstimate() + index_keys_size; if (arg_size >= max_put_value_size_) { callbacks->Error( - blink::kWebIDBDatabaseExceptionUnknownError, + mojom::blink::IDBException::kUnknownError, String::Format("The serialized keys and/or value are too large" " (size=%" PRIuS " bytes, max=%" PRIuS " bytes).", arg_size, max_put_value_size_));
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.h index c49b629..b5787915 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.h
@@ -12,7 +12,7 @@ #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/indexeddb/web_idb_transaction.h" #include "third_party/blink/renderer/modules/modules_export.h"
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer.cc b/third_party/blink/renderer/modules/mediasource/source_buffer.cc index e6e82ed..c303731 100644 --- a/third_party/blink/renderer/modules/mediasource/source_buffer.cc +++ b/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -370,12 +370,12 @@ ExceptionState& exception_state) { double media_time = GetMediaTime(); DVLOG(2) << __func__ << " this=" << this << " media_time=" << media_time - << " size=" << data->ByteLength(); + << " size=" << data->DeprecatedByteLengthAsUnsigned(); // Section 3.2 appendBuffer() // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data AppendBufferInternal(media_time, static_cast<const unsigned char*>(data->Data()), - data->ByteLength(), exception_state); + data->DeprecatedByteLengthAsUnsigned(), exception_state); } void SourceBuffer::appendBuffer(NotShared<DOMArrayBufferView> data,
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index b6ee2a0..18907989 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -524,7 +524,6 @@ "xr/xr_reference_space_event.idl", "xr/xr_render_state.idl", "xr/xr_rigid_transform.idl", - "xr/xr_hit_test_options.idl", "xr/xr_hit_test_result.idl", "xr/xr_hit_test_source.idl", "xr/xr_session.idl",
diff --git a/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc b/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc index 7d9b73f..b140606 100644 --- a/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc +++ b/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc
@@ -46,7 +46,8 @@ Blob* blob = nullptr; if (data.IsArrayBuffer()) { DOMArrayBuffer* array_buffer = data.GetAsArrayBuffer(); - blob_data->AppendBytes(array_buffer->Data(), array_buffer->ByteLength()); + blob_data->AppendBytes(array_buffer->Data(), + array_buffer->ByteLengthAsSizeT()); } else if (data.IsArrayBufferView()) { DOMArrayBufferView* array_buffer_view = data.GetAsArrayBufferView().View(); blob_data->AppendBytes(array_buffer_view->BaseAddress(),
diff --git a/third_party/blink/renderer/modules/nfc/ndef_message.cc b/third_party/blink/renderer/modules/nfc/ndef_message.cc index 9891b136..642d5d8e 100644 --- a/third_party/blink/renderer/modules/nfc/ndef_message.cc +++ b/third_party/blink/renderer/modules/nfc/ndef_message.cc
@@ -47,7 +47,7 @@ WTF::Vector<uint8_t> payload_data; payload_data.Append( static_cast<uint8_t*>(source.GetAsArrayBuffer()->Data()), - source.GetAsArrayBuffer()->ByteLength()); + source.GetAsArrayBuffer()->DeprecatedByteLengthAsUnsigned()); NDEFMessage* message = MakeGarbageCollected<NDEFMessage>(); message->records_.push_back(MakeGarbageCollected<NDEFRecord>( std::move(payload_data), "application/octet-stream"));
diff --git a/third_party/blink/renderer/modules/nfc/ndef_record.cc b/third_party/blink/renderer/modules/nfc/ndef_record.cc index 11c673f..494763c5 100644 --- a/third_party/blink/renderer/modules/nfc/ndef_record.cc +++ b/third_party/blink/renderer/modules/nfc/ndef_record.cc
@@ -46,7 +46,7 @@ DOMArrayBuffer* array_buffer = V8ArrayBuffer::ToImpl(buffer_source.V8Value().As<v8::Object>()); bytes.Append(static_cast<uint8_t*>(array_buffer->Data()), - array_buffer->ByteLength()); + array_buffer->DeprecatedByteLengthAsUnsigned()); } else if (buffer_source.V8Value()->IsArrayBufferView()) { DOMArrayBufferView* array_buffer_view = V8ArrayBufferView::ToImpl(buffer_source.V8Value().As<v8::Object>()); @@ -224,7 +224,7 @@ V8ArrayBuffer::ToImpl(data.V8Value().As<v8::Object>()); WTF::Vector<uint8_t> bytes; bytes.Append(static_cast<uint8_t*>(array_buffer->Data()), - array_buffer->ByteLength()); + array_buffer->DeprecatedByteLengthAsUnsigned()); return MakeGarbageCollected<NDEFRecord>(custom_type, std::move(bytes)); }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc index 0a9bd28..ab22b49b 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
@@ -376,7 +376,7 @@ return; } - size_t data_length = data->ByteLength(); + size_t data_length = data->ByteLengthAsSizeT(); if (!data_length) return;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc index 1edb1af..bd25ad04 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc
@@ -158,9 +158,10 @@ der_cert.data(), static_cast<unsigned int>(der_cert.size())); // Don't replace the certificate if it's unchanged. // Should have been "if (*dab_cert != *remote_certificates_[i])" - if (dab_cert->ByteLength() != remote_certificates_[i]->ByteLength() || + if (dab_cert->ByteLengthAsSizeT() != + remote_certificates_[i]->ByteLengthAsSizeT() || memcmp(dab_cert->Data(), remote_certificates_[i]->Data(), - dab_cert->ByteLength()) != 0) { + dab_cert->ByteLengthAsSizeT()) != 0) { remote_certificates_[i] = dab_cert; } }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc index 0a68497..a369fbb 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
@@ -155,7 +155,7 @@ key_(key), certificates_(certificates), p2p_quic_transport_factory_(std::move(p2p_quic_transport_factory)) { - DCHECK_GT(key_->ByteLength(), 0u); + DCHECK_GT(key_->ByteLengthAsSizeT(), 0u); transport->ConnectConsumer(this); } @@ -184,7 +184,7 @@ } DOMArrayBuffer* RTCQuicTransport::getKey() const { - return DOMArrayBuffer::Create(key_->Data(), key_->ByteLength()); + return DOMArrayBuffer::Create(key_->Data(), key_->ByteLengthAsSizeT()); } void RTCQuicTransport::connect(ExceptionState& exception_state) { @@ -196,7 +196,7 @@ } start_reason_ = StartReason::kClientConnecting; std::string pre_shared_key(static_cast<const char*>(key_->Data()), - key_->ByteLength()); + key_->ByteLengthAsSizeT()); StartConnection(quic::Perspective::IS_CLIENT, P2PQuicTransport::StartConfig(pre_shared_key)); }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc index bde32ac6..d99bc69e 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc
@@ -79,7 +79,7 @@ static base::span<uint8_t> SpanFromDOMArrayBuffer(DOMArrayBuffer* buffer) { return base::span<uint8_t>(static_cast<uint8_t*>(buffer->Data()), - buffer->ByteLength()); + buffer->ByteLengthAsSizeT()); } } // namespace @@ -444,7 +444,7 @@ CreateQuicTransport(scope, ice_transport, {}, std::move(mock_transport)); DOMArrayBuffer* key = quic_transport->getKey(); std::string pre_shared_key(static_cast<const char*>(key->Data()), - key->ByteLength()); + key->ByteLengthAsSizeT()); EXPECT_CALL(*mock_transport_ptr, MockStart(_)) .WillOnce( @@ -659,7 +659,7 @@ CreateQuicTransport(scope, ice_transport, {}, std::move(mock_transport)); auto* key = quic_transport->getKey(); - EXPECT_GE(key->ByteLength(), 16u); + EXPECT_GE(key->ByteLengthAsSizeT(), 16u); } // Test that stats are converted correctly to the RTCQuicTransportStats
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection.cc b/third_party/blink/renderer/modules/presentation/presentation_connection.cc index fae2d02..9d1969b 100644 --- a/third_party/blink/renderer/modules/presentation/presentation_connection.cc +++ b/third_party/blink/renderer/modules/presentation/presentation_connection.cc
@@ -42,7 +42,7 @@ WTF::Vector<uint8_t>()); WTF::Vector<uint8_t>& data = message->get_data(); data.Append(static_cast<const uint8_t*>(buffer->Data()), - buffer->ByteLength()); + buffer->DeprecatedByteLengthAsUnsigned()); return message; }
diff --git a/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc b/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc index 54d6be8a..cfb1899 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc +++ b/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc
@@ -37,9 +37,9 @@ String application_server_key( reinterpret_cast<const char*>(output->applicationServerKey()->Data()), - output->applicationServerKey()->ByteLength()); + output->applicationServerKey()->DeprecatedByteLengthAsUnsigned()); - ASSERT_EQ(output->applicationServerKey()->ByteLength(), + ASSERT_EQ(output->applicationServerKey()->DeprecatedByteLengthAsUnsigned(), kApplicationServerKeyLength); ASSERT_EQ(reinterpret_cast<const char*>(sender_key),
diff --git a/third_party/blink/renderer/modules/push_messaging/push_message_data.cc b/third_party/blink/renderer/modules/push_messaging/push_message_data.cc index 3ba9a309..f80d0307 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_message_data.cc +++ b/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
@@ -38,7 +38,8 @@ : message_data.GetAsArrayBuffer(); return MakeGarbageCollected<PushMessageData>( - static_cast<const char*>(buffer->Data()), buffer->ByteLength()); + static_cast<const char*>(buffer->Data()), + buffer->DeprecatedByteLengthAsUnsigned()); } if (message_data.IsUSVString()) {
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc b/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc index 692dfc4..273922bd 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc +++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc
@@ -64,7 +64,7 @@ // If a developer provided an application server key in |options|, skip // fetching the manifest. - if (!options->applicationServerKey()->ByteLength()) { + if (!options->applicationServerKey()->ByteLengthAsSizeT()) { ManifestManager* manifest_manager = ManifestManager::From(*GetSupplementable()); manifest_manager->RequestManifest(
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.cc b/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.cc index 8f85f0a..9452bd7 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.cc +++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.cc
@@ -20,7 +20,7 @@ Vector<uint8_t> application_server_key; application_server_key.Append( reinterpret_cast<uint8_t*>(input->applicationServerKey()->Data()), - input->applicationServerKey()->ByteLength()); + input->applicationServerKey()->DeprecatedByteLengthAsUnsigned()); return blink::mojom::blink::PushSubscriptionOptions::New( input->userVisibleOnly(), application_server_key);
diff --git a/third_party/blink/renderer/modules/push_messaging/push_subscription.cc b/third_party/blink/renderer/modules/push_messaging/push_subscription.cc index e22e0c0..afadd498 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_subscription.cc +++ b/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
@@ -27,7 +27,7 @@ // based on the value of |buffer| while encoding, assuming a known length. String ToBase64URLWithoutPadding(DOMArrayBuffer* buffer) { String value = WTF::Base64URLEncode(static_cast<const char*>(buffer->Data()), - buffer->ByteLength()); + buffer->DeprecatedByteLengthAsUnsigned()); DCHECK_GT(value.length(), 0u); unsigned padding_to_remove = 0;
diff --git a/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc b/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc index 1db027ac..ad43b565 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc +++ b/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc
@@ -30,14 +30,15 @@ if (application_server_key.IsArrayBuffer()) { input = static_cast<char*>(application_server_key.GetAsArrayBuffer()->Data()); - length = application_server_key.GetAsArrayBuffer()->ByteLength(); + length = application_server_key.GetAsArrayBuffer() + ->DeprecatedByteLengthAsUnsigned(); } else if (application_server_key.IsArrayBufferView()) { input = static_cast<char*>( application_server_key.GetAsArrayBufferView().View()->buffer()->Data()); length = application_server_key.GetAsArrayBufferView() .View() ->buffer() - ->ByteLength(); + ->DeprecatedByteLengthAsUnsigned(); } else if (application_server_key.IsString()) { if (!Base64UnpaddedURLDecode(application_server_key.GetAsString(), decoded_application_server_key)) { @@ -101,7 +102,7 @@ bool PushSubscriptionOptions::IsApplicationServerKeyVapid() const { if (!application_server_key_) return false; - return application_server_key_->ByteLength() == 65 && + return application_server_key_->ByteLengthAsSizeT() == 65 && static_cast<uint8_t*>(application_server_key_->Data())[0] == 0x04; }
diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc index 9bc626b..6225708b 100644 --- a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc +++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
@@ -138,7 +138,7 @@ if (buffer_source_.IsArrayBuffer()) { DOMArrayBuffer* array = buffer_source_.GetAsArrayBuffer(); data = static_cast<const uint8_t*>(array->Data()); - length = array->ByteLength(); + length = array->DeprecatedByteLengthAsUnsigned(); } else { DOMArrayBufferView* view = buffer_source_.GetAsArrayBufferView().View(); data = static_cast<const uint8_t*>(view->BaseAddress());
diff --git a/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc b/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc index 8cab445a..f84bdbce 100644 --- a/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc +++ b/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc
@@ -73,7 +73,7 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner) { DCHECK(!IsMainThread()); scoped_refptr<AudioBus> bus = CreateBusFromInMemoryAudioFile( - audio_data->Data(), audio_data->ByteLength(), false, sample_rate); + audio_data->Data(), audio_data->ByteLengthAsSizeT(), false, sample_rate); // Decoding is finished, but we need to do the callbacks on the main thread. // A reference to |*bus| is retained by base::OnceCallback and will be removed
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index 84a58f78..cbe8070 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -2003,7 +2003,7 @@ SynthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data"); return; } - BufferDataImpl(target, data->ByteLength(), data->Data(), usage); + BufferDataImpl(target, data->ByteLengthAsSizeT(), data->Data(), usage); } void WebGLRenderingContextBase::bufferData(GLenum target, @@ -2041,7 +2041,7 @@ if (isContextLost()) return; DCHECK(data); - BufferSubDataImpl(target, offset, data->ByteLength(), data->Data()); + BufferSubDataImpl(target, offset, data->ByteLengthAsSizeT(), data->Data()); } void WebGLRenderingContextBase::bufferSubData(
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/third_party/blink/renderer/modules/websockets/dom_websocket.cc index c3a3cd6..bea8bb2 100644 --- a/third_party/blink/renderer/modules/websockets/dom_websocket.cc +++ b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -354,15 +354,15 @@ return; } if (common_.GetState() == kClosing || common_.GetState() == kClosed) { - UpdateBufferedAmountAfterClose(binary_data->ByteLength()); + UpdateBufferedAmountAfterClose(binary_data->ByteLengthAsSizeT()); return; } RecordSendTypeHistogram(kWebSocketSendTypeArrayBuffer); RecordSendMessageSizeHistogram(kWebSocketSendTypeArrayBuffer, - binary_data->ByteLength()); + binary_data->ByteLengthAsSizeT()); DCHECK(channel_); - buffered_amount_ += binary_data->ByteLength(); - channel_->Send(*binary_data, 0, binary_data->ByteLength(), + buffered_amount_ += binary_data->ByteLengthAsSizeT(); + channel_->Send(*binary_data, 0, binary_data->DeprecatedByteLengthAsUnsigned(), base::OnceClosure()); }
diff --git a/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc b/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc index dba95e67..d799ed86 100644 --- a/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc +++ b/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc
@@ -114,7 +114,8 @@ return true; DOMArrayBuffer* array_buffer = web_array_buffer; - private_->Send(*array_buffer, 0, array_buffer->ByteLength(), + private_->Send(*array_buffer, 0, + array_buffer->DeprecatedByteLengthAsUnsigned(), base::OnceClosure()); return true; }
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index 0c77ba9..4650f8e 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -684,7 +684,7 @@ CHECK(message->array_buffer); SendInternal(network::mojom::blink::WebSocketMessageType::BINARY, static_cast<const char*>(message->array_buffer->Data()), - message->array_buffer->ByteLength(), + message->array_buffer->DeprecatedByteLengthAsUnsigned(), &consumed_buffered_amount); break; case kMessageTypeClose: {
diff --git a/third_party/blink/renderer/modules/websockets/websocket_stream.cc b/third_party/blink/renderer/modules/websockets/websocket_stream.cc index c33cdbc2..80014c8 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_stream.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_stream.cc
@@ -291,7 +291,8 @@ auto* isolate = script_state->GetIsolate(); if (v8chunk->IsArrayBuffer()) { DOMArrayBuffer* data = V8ArrayBuffer::ToImpl(v8chunk.As<v8::ArrayBuffer>()); - SendArrayBuffer(script_state, data, 0, data->ByteLength(), resolver, + SendArrayBuffer(script_state, data, 0, + data->DeprecatedByteLengthAsUnsigned(), resolver, std::move(callback)); return; }
diff --git a/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h b/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h index 36c379e..ba72761 100644 --- a/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h +++ b/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h
@@ -21,7 +21,8 @@ static USBIsochronousInTransferResult* Create( DOMArrayBuffer* data, const HeapVector<Member<USBIsochronousInTransferPacket>>& packets) { - DOMDataView* data_view = DOMDataView::Create(data, 0, data->ByteLength()); + DOMDataView* data_view = + DOMDataView::Create(data, 0, data->DeprecatedByteLengthAsUnsigned()); return MakeGarbageCollected<USBIsochronousInTransferResult>(data_view, packets); }
diff --git a/third_party/blink/renderer/modules/xr/BUILD.gn b/third_party/blink/renderer/modules/xr/BUILD.gn index ac6f487..04c1ca0 100644 --- a/third_party/blink/renderer/modules/xr/BUILD.gn +++ b/third_party/blink/renderer/modules/xr/BUILD.gn
@@ -30,8 +30,6 @@ "xr_grip_space.h", "xr_hit_result.cc", "xr_hit_result.h", - "xr_hit_test_options.cc", - "xr_hit_test_options.h", "xr_hit_test_result.cc", "xr_hit_test_result.h", "xr_hit_test_source.cc",
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_options.cc b/third_party/blink/renderer/modules/xr/xr_hit_test_options.cc deleted file mode 100644 index 73d366ff..0000000 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_options.cc +++ /dev/null
@@ -1,39 +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 "third_party/blink/renderer/modules/xr/xr_hit_test_options.h" - -#include "third_party/blink/renderer/modules/xr/xr_hit_test_options_init.h" -#include "third_party/blink/renderer/modules/xr/xr_ray.h" -#include "third_party/blink/renderer/modules/xr/xr_space.h" - -namespace blink { - -XRHitTestOptions::XRHitTestOptions(XRHitTestOptionsInit* options_init) { - DCHECK(options_init); - - space_ = options_init->space(); - - if (options_init->hasOffsetRay()) { - ray_ = options_init->offsetRay(); - } else { - ray_ = MakeGarbageCollected<XRRay>(); - } -} - -void XRHitTestOptions::Trace(blink::Visitor* visitor) { - visitor->Trace(space_); - visitor->Trace(ray_); - ScriptWrappable::Trace(visitor); -} - -XRSpace* XRHitTestOptions::space() const { - return space_; -} - -XRRay* XRHitTestOptions::offsetRay() const { - return ray_; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_options.h b/third_party/blink/renderer/modules/xr/xr_hit_test_options.h deleted file mode 100644 index 0c671b1..0000000 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_options.h +++ /dev/null
@@ -1,34 +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 THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_TEST_OPTIONS_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_TEST_OPTIONS_H_ - -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" - -namespace blink { - -class XRRay; -class XRSpace; -class XRHitTestOptionsInit; - -class XRHitTestOptions : public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); - - public: - explicit XRHitTestOptions(XRHitTestOptionsInit* options_init); - - XRSpace* space() const; - XRRay* offsetRay() const; - - void Trace(blink::Visitor* visitor) override; - - private: - Member<XRSpace> space_; - Member<XRRay> ray_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_TEST_OPTIONS_H_
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_options.idl b/third_party/blink/renderer/modules/xr/xr_hit_test_options.idl deleted file mode 100644 index 6f90679..0000000 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_options.idl +++ /dev/null
@@ -1,9 +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. - -[SecureContext, Exposed=Window, RuntimeEnabled=WebXRHitTest] -interface XRHitTestOptions { - readonly attribute XRSpace space; - readonly attribute XRRay offsetRay; -};
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc b/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc index dd3bc4c2..9407db65 100644 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc +++ b/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc
@@ -15,10 +15,6 @@ : hit_test_source_(hit_test_source), pose_(std::make_unique<TransformationMatrix>(pose)) {} -XRHitTestOptions* XRHitTestResult::hitTestOptions() const { - return hit_test_source_->hitTestOptions(); -} - XRPose* XRHitTestResult::getPose(XRSpace* relative_to) { DCHECK(relative_to->MojoFromSpace());
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_result.h b/third_party/blink/renderer/modules/xr/xr_hit_test_result.h index 37526c0..3b38d7a 100644 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_result.h +++ b/third_party/blink/renderer/modules/xr/xr_hit_test_result.h
@@ -10,7 +10,6 @@ namespace blink { class TransformationMatrix; -class XRHitTestOptions; class XRHitTestSource; class XRPose; class XRSpace; @@ -22,8 +21,6 @@ XRHitTestResult(XRHitTestSource* hit_test_source, const TransformationMatrix& pose); - XRHitTestOptions* hitTestOptions() const; - XRPose* getPose(XRSpace* relative_to); void Trace(blink::Visitor* visitor) override;
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl b/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl index 7c3cd75e..0019eaa 100644 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl +++ b/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl
@@ -4,7 +4,5 @@ [SecureContext, Exposed=Window, RuntimeEnabled=WebXRHitTest] interface XRHitTestResult { - readonly attribute XRHitTestOptions hitTestOptions; - XRPose? getPose(XRSpace relative_to); };
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc b/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc index 0cfdd0c..be628e3a 100644 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc +++ b/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc
@@ -5,22 +5,16 @@ #include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h" #include "device/vr/public/mojom/vr_service.mojom-blink.h" -#include "third_party/blink/renderer/modules/xr/xr_hit_test_options.h" #include "third_party/blink/renderer/modules/xr/xr_hit_test_result.h" namespace blink { -XRHitTestSource::XRHitTestSource(uint64_t id, XRHitTestOptions* options) - : id_(id), options_(options) {} +XRHitTestSource::XRHitTestSource(uint64_t id) : id_(id) {} uint64_t XRHitTestSource::id() const { return id_; } -XRHitTestOptions* XRHitTestSource::hitTestOptions() const { - return options_; -} - HeapVector<Member<XRHitTestResult>> XRHitTestSource::Results() { HeapVector<Member<XRHitTestResult>> results; @@ -41,9 +35,4 @@ } } -void XRHitTestSource::Trace(blink::Visitor* visitor) { - visitor->Trace(options_); - ScriptWrappable::Trace(visitor); -} - } // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_source.h b/third_party/blink/renderer/modules/xr/xr_hit_test_source.h index 94af09d..41d6873a 100644 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_source.h +++ b/third_party/blink/renderer/modules/xr/xr_hit_test_source.h
@@ -14,19 +14,16 @@ namespace blink { -class XRHitTestOptions; class XRHitTestResult; class XRHitTestSource : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - XRHitTestSource(uint64_t id, XRHitTestOptions* options); + explicit XRHitTestSource(uint64_t id); uint64_t id() const; - XRHitTestOptions* hitTestOptions() const; - // Returns a vector of XRHitTestResults that were obtained during last frame // update. This method is not exposed to JavaScript. HeapVector<Member<XRHitTestResult>> Results(); @@ -34,13 +31,9 @@ void Update(const WTF::Vector<device::mojom::blink::XRHitResultPtr>& hit_test_results); - void Trace(blink::Visitor*) override; - private: const uint64_t id_; - Member<XRHitTestOptions> options_; - Vector<std::unique_ptr<TransformationMatrix>> last_frame_results_; };
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_source.idl b/third_party/blink/renderer/modules/xr/xr_hit_test_source.idl index b05fbee1..68dd21c9 100644 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_source.idl +++ b/third_party/blink/renderer/modules/xr/xr_hit_test_source.idl
@@ -4,5 +4,4 @@ [SecureContext, Exposed=Window, RuntimeEnabled=WebXRHitTest] interface XRHitTestSource { - readonly attribute XRHitTestOptions hitTestOptions; };
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc index e23f9f2..b62141c 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -31,7 +31,7 @@ #include "third_party/blink/renderer/modules/xr/xr_frame.h" #include "third_party/blink/renderer/modules/xr/xr_frame_provider.h" #include "third_party/blink/renderer/modules/xr/xr_hit_result.h" -#include "third_party/blink/renderer/modules/xr/xr_hit_test_options.h" +#include "third_party/blink/renderer/modules/xr/xr_hit_test_options_init.h" #include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h" #include "third_party/blink/renderer/modules/xr/xr_input_source_event.h" #include "third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h" @@ -631,12 +631,11 @@ DCHECK(options_init); // is this enforced by generated bindings? - XRHitTestOptions* options = - MakeGarbageCollected<XRHitTestOptions>(options_init); - // 1. Grab the native origin from the passed in XRSpace. base::Optional<XRNativeOriginInformation> maybe_native_origin = - options->space()->NativeOrigin(); + options_init && options_init->hasSpace() + ? options_init->space()->NativeOrigin() + : base::nullopt; if (!maybe_native_origin) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, @@ -648,13 +647,20 @@ // should only matter for spaces whose transforms are not fully known on the // device (for example any space containing origin-offset). TransformationMatrix origin_from_space = - options->space()->OriginOffsetMatrix(); + options_init->space() + ->OriginOffsetMatrix(); // Null checks not needed since native origin + // wouldn't be set if options_init or space() + // were null. DVLOG(3) << __func__ << ": origin_from_space = " << origin_from_space.ToString(true); // Transformation from passed in pose to |space|. - auto space_from_ray = options->offsetRay()->RawMatrix(); + + XRRay* offsetRay = options_init && options_init->hasOffsetRay() + ? options_init->offsetRay() + : MakeGarbageCollected<XRRay>(); + auto space_from_ray = offsetRay->RawMatrix(); auto origin_from_ray = origin_from_space * space_from_ray; DVLOG(3) << __func__ @@ -681,7 +687,7 @@ xr_->xrEnvironmentProviderRemote()->SubscribeToHitTest( maybe_native_origin->ToMojo(), std::move(ray_mojo), WTF::Bind(&XRSession::OnSubscribeToHitTestResult, WrapPersistent(this), - WrapPersistent(resolver), WrapPersistent(options))); + WrapPersistent(resolver))); request_hit_test_source_promises_.insert(resolver); return promise; @@ -709,7 +715,6 @@ void XRSession::OnSubscribeToHitTestResult( ScriptPromiseResolver* resolver, - XRHitTestOptions* options, device::mojom::SubscribeToHitTestResult result, uint64_t subscription_id) { DVLOG(2) << __func__ << ": result=" << result @@ -725,7 +730,7 @@ } XRHitTestSource* hit_test_source = - MakeGarbageCollected<XRHitTestSource>(subscription_id, options); + MakeGarbageCollected<XRHitTestSource>(subscription_id); hit_test_source_ids_to_hit_test_sources_.insert(subscription_id, hit_test_source);
diff --git a/third_party/blink/renderer/modules/xr/xr_session.h b/third_party/blink/renderer/modules/xr/xr_session.h index 4c574e0..40bafd7 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.h +++ b/third_party/blink/renderer/modules/xr/xr_session.h
@@ -39,7 +39,6 @@ class XRAnchor; class XRAnchorSet; class XRCanvasInputProvider; -class XRHitTestOptions; class XRHitTestOptionsInit; class XRHitTestSource; class XRPlane; @@ -311,7 +310,6 @@ void OnSubscribeToHitTestResult( ScriptPromiseResolver* resolver, - XRHitTestOptions* options, device::mojom::SubscribeToHitTestResult result, uint64_t subscription_id);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index 974909b..2dbb90bf 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -1908,7 +1908,6 @@ const auto& request = resource->GetResourceRequest(); ResourceResponse response; - resource->VirtualTimePauser().PauseVirtualTime(); if (resource_load_observer_) { DCHECK(!IsDetached()); resource_load_observer_->WillSendRequest( @@ -1943,6 +1942,7 @@ } else { non_blocking_loaders_.insert(loader); } + resource->VirtualTimePauser().PauseVirtualTime(); StorePerformanceTimingInitiatorInformation(resource); }
diff --git a/third_party/blink/renderer/platform/testing/paint_test_configurations.h b/third_party/blink/renderer/platform/testing/paint_test_configurations.h index d125cb30..00b0da0 100644 --- a/third_party/blink/renderer/platform/testing/paint_test_configurations.h +++ b/third_party/blink/renderer/platform/testing/paint_test_configurations.h
@@ -15,6 +15,7 @@ kCompositeAfterPaint = 1 << 0, kUnderInvalidationChecking = 1 << 1, kFastBorderRadius = 1 << 2, + kDoNotCompositeTrivial3D = 1 << 3, }; class PaintTestConfigurations @@ -51,6 +52,12 @@ INSTANTIATE_TEST_SUITE_P(All, test_class, \ ::testing::Values(0, kCompositeAfterPaint)) +#define INSTANTIATE_DO_NOT_COMPOSITE_TRIVIAL_3D_P(test_class) \ + INSTANTIATE_TEST_SUITE_P( \ + All, test_class, \ + ::testing::Values(0, kCompositeAfterPaint, kDoNotCompositeTrivial3D, \ + kCompositeAfterPaint | kDoNotCompositeTrivial3D)) + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_PAINT_TEST_CONFIGURATIONS_H_
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_metadata_builder_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_metadata_builder_unittest.py index 79b6c73..0088c9d 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_metadata_builder_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_metadata_builder_unittest.py
@@ -14,20 +14,29 @@ from blinkpy.w3c.wpt_metadata_builder import WPTMetadataBuilder -def _make_expectation(port, test_name, test_statuses): - """Creates an expectation object for a single test. +def _make_expectation(port, test_path, test_statuses, test_names=[]): + """Creates an expectation object for a single test or directory. Args: port: the port to run against - test_name: the name of the test + test_path: the path to set expectations for test_status: the statuses of the test + test_names: a set of tests under the 'test_path'. Should be non-empty + when the 'test_path' is a directory instead of a single test Returns: An expectation object with the given test and statuses. """ expectation_dict = OrderedDict() - expectation_dict["expectations"] = "Bug(test) %s [ %s ]" % (test_name, test_statuses) - return TestExpectations(port, tests=[test_name], expectations_dict=expectation_dict) + expectation_dict["expectations"] = "Bug(test) %s [ %s ]" % (test_path, test_statuses) + + # When test_path is a dir, we expect test_names to be provided. + is_dir = test_path.endswith('/') + assert is_dir == bool(test_names) + if not is_dir: + test_names = [test_path] + + return TestExpectations(port, tests=test_names, expectations_dict=expectation_dict) class WPTMetadataBuilderTest(unittest.TestCase): @@ -86,10 +95,11 @@ def test_skipped_directory(self): """A skipped WPT directory should get a dir-wide metadata file.""" - test_name = "external/wpt/test_dir/" - expectations = _make_expectation(self.port, test_name, "SKIP") + test_dir = "external/wpt/test_dir/" + test_name = "external/wpt/test_dir/test.html" + expectations = _make_expectation(self.port, test_dir, "SKIP", test_names=[test_name]) metadata_builder = WPTMetadataBuilder(expectations, self.port) - filename, contents = metadata_builder.get_metadata_filename_and_contents(test_name, 'SKIP') + filename, contents = metadata_builder.get_metadata_filename_and_contents(test_dir, 'SKIP') self.assertEqual(os.path.join("test_dir", "__dir__.ini"), filename) self.assertEqual("disabled: wpt_metadata_builder.py\n", contents)
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py index 7fff95a..117d631 100644 --- a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py +++ b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py
@@ -84,6 +84,77 @@ set(s.upper() for s in _BUILD_TYPE_TOKEN_LIST) ] + +class AllTests(object): + """A class to query for path-prefix matches against the list of all tests.""" + def __init__(self, list_of_tests): + self._tree = dict() + for test in list_of_tests: + assert not test.startswith('/') + assert not test.endswith('/') + assert test.replace('//', '/') == test + AllTests._add_path_to_tree(self._tree, test.split('/')) + + def find_matching_tests(self, path_prefix): + assert not path_prefix.startswith('/') + assert path_prefix.replace('//', '/') == path_prefix + + subtree = AllTests._find_subtree_with_prefix(self._tree, path_prefix.rstrip('/').split('/')) + if subtree is None: + # No match found. + return [] + if not subtree: + # We found a leaf node, an exact match on |path_prefix|. + return [path_prefix] + return AllTests._all_paths_under_subtree(subtree, path_prefix) + + @staticmethod + def _find_subtree_with_prefix(subtree, path_list): + # Reached the end of the path, we matched to this point in the + # dictionary tree. + if not path_list: + return subtree + path_component = path_list[0] + # A component of the path does not exist in the dictionary tree. + if not path_component in subtree: + return None + path_remainder = path_list[1:] + return AllTests._find_subtree_with_prefix(subtree[path_component], path_remainder) + + @staticmethod + def _all_paths_under_subtree(subtree, prefix): + if not subtree: + return [] + + if prefix and not prefix.endswith('/'): + prefix = prefix + '/' + + paths = [] + for child_path, child_tree in subtree.iteritems(): + if not child_tree: + paths.append(prefix + child_path) + else: + paths.extend(AllTests._all_paths_under_subtree(child_tree, prefix + child_path)) + return paths + + @staticmethod + def _add_path_to_tree(subtree, path_list): + # When |path_list| is empty, we reached the end of the path, + # so don't add anything more to |subtree|. + if not path_list: + # If subtree is not empty, then we have the same path listed + # twice in the initial list of tests. + assert len(subtree) == 0 + return + + path_component = path_list[0] + if not path_component in subtree: + subtree[path_component] = dict() + + path_remainder = path_list[1:] + AllTests._add_path_to_tree(subtree[path_component], path_remainder) + + class TestExpectationParser(object): """Provides parsing facilities for lines in the test_expectation.txt file.""" @@ -101,12 +172,7 @@ self._port = port self._test_configuration_converter = TestConfigurationConverter( set(port.all_test_configurations()), port.configuration_specifier_macros()) - - if all_tests: - self._all_tests = set(all_tests) - else: - self._all_tests = set() - + self._all_tests = AllTests(all_tests) if all_tests else None self._is_lint_mode = is_lint_mode def parse(self, filename, expectations_string): @@ -220,16 +286,7 @@ expectation_line.matching_tests = [expectation_line.path] return - if not expectation_line.is_file: - # this is a test category, return all the tests of the category. - expectation_line.matching_tests = [test for test in self._all_tests if test.startswith(expectation_line.path)] - return - - # this is a test file, do a quick check if it's in the - # full test suite. - if expectation_line.path in self._all_tests: - expectation_line.matching_tests.append(expectation_line.path) - + expectation_line.matching_tests = self._all_tests.find_matching_tests(expectation_line.path) class TestExpectationLine(object): """Represents a line in test expectations file."""
diff --git a/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item b/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item index 7b5f30b..17b55ef 100644 --- a/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item +++ b/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item
@@ -1,6 +1,6 @@ crbug.com/982194 accessibility/adjacent-continuations-cause-assertion-failure.html [ Failure ] crbug.com/982194 accessibility/aria-tables.html [ Failure ] -crbug.com/982194 accessibility/bounds-calc.html [ Failure ] +crbug.com/982194 accessibility/bounds-calc.html [ Failure Pass ] crbug.com/982194 accessibility/click-event.html [ Timeout ] crbug.com/982194 accessibility/first-letter-text-transform-causes-crash.html [ Failure ] crbug.com/982194 accessibility/first-letter-text-transform.html [ Failure ] @@ -173,7 +173,7 @@ crbug.com/982194 editing/selection/drag_with_unfocused_selection.html [ Failure ] crbug.com/982194 editing/selection/extend-selection-after-double-click.html [ Failure ] crbug.com/982194 editing/selection/first-letter-mouse-select-full-text.html [ Failure ] -crbug.com/982194 editing/selection/focus-and-display-none.html [ Failure ] +crbug.com/982194 editing/selection/focus-and-display-none.html [ Crash Failure ] crbug.com/982194 editing/selection/focus-crash.html [ Failure ] crbug.com/982194 editing/selection/inline-closest-leaf-child.html [ Failure ] crbug.com/982194 editing/selection/japanese-lr-selection.html [ Failure ] @@ -397,7 +397,7 @@ crbug.com/982194 external/wpt/css/css-writing-modes/vertical-alignment-vlr-025.xht [ Failure ] crbug.com/982194 external/wpt/css/css-writing-modes/vertical-alignment-vlr-027.xht [ Failure ] crbug.com/982194 external/wpt/css/css-writing-modes/wm-propagation-body-044.html [ Failure ] -crbug.com/982194 external/wpt/css/cssom-view/DOMRectList.html [ Failure ] +crbug.com/982194 external/wpt/css/cssom-view/DOMRectList.html [ Failure Pass ] crbug.com/982194 external/wpt/css/cssom-view/elementFromPoint-dynamic-anon-box.html [ Failure ] crbug.com/982194 external/wpt/css/cssom-view/elementFromPoint-list-001.html [ Failure ] crbug.com/982194 external/wpt/css/cssom-view/elementFromPoint-mixed-font-sizes.html [ Failure ] @@ -694,7 +694,7 @@ crbug.com/982194 fast/block/positioning/relative-overflow-replaced.html [ Failure ] crbug.com/982194 fast/block/positioning/vertical-lr/001.html [ Failure ] crbug.com/982194 fast/borders/border-image-inherits-with-border.html [ Failure Pass ] -crbug.com/982194 fast/borders/border-image-outset-split-inline.html [ Failure ] +crbug.com/982194 fast/borders/border-image-outset-split-inline.html [ Crash Failure ] crbug.com/982194 fast/borders/border-styles-split.html [ Failure ] crbug.com/982194 fast/borders/inline-mask-overlay-image-outset.html [ Failure ] crbug.com/982194 fast/borders/inline-mask-overlay-image.html [ Failure ] @@ -793,14 +793,14 @@ crbug.com/982194 fast/dom/HTMLAnchorElement/anchor-nodownload-set.html [ Timeout ] crbug.com/982194 fast/dom/HTMLAnchorElement/anchor-nodownload.html [ Timeout ] crbug.com/982194 fast/dom/HTMLAreaElement/area-download.html [ Timeout ] -crbug.com/982194 fast/dom/Range/collapsed-range-bounding-client-rect.html [ Failure ] -crbug.com/982194 fast/dom/Range/get-bounding-client-rect-empty-and-non-empty.html [ Failure ] -crbug.com/982194 fast/dom/Range/getBoundingClientRect-getClientRects-relative-to-viewport.html [ Failure ] -crbug.com/982194 fast/dom/Range/getBoundingClientRect-linebreak-character.html [ Failure ] -crbug.com/982194 fast/dom/Range/getBoundingClientRect.html [ Failure ] -crbug.com/982194 fast/dom/Range/getClientRects-character.html [ Failure ] -crbug.com/982194 fast/dom/Range/getClientRects-leading-trailing-whitespaces.html [ Failure ] -crbug.com/982194 fast/dom/Range/getClientRects.html [ Failure ] +crbug.com/982194 fast/dom/Range/collapsed-range-bounding-client-rect.html [ Failure Pass ] +crbug.com/982194 fast/dom/Range/get-bounding-client-rect-empty-and-non-empty.html [ Failure Pass ] +crbug.com/982194 fast/dom/Range/getBoundingClientRect-getClientRects-relative-to-viewport.html [ Failure Pass ] +crbug.com/982194 fast/dom/Range/getBoundingClientRect-linebreak-character.html [ Failure Pass ] +crbug.com/982194 fast/dom/Range/getBoundingClientRect.html [ Failure Pass ] +crbug.com/982194 fast/dom/Range/getClientRects-character.html [ Failure Pass ] +crbug.com/982194 fast/dom/Range/getClientRects-leading-trailing-whitespaces.html [ Failure Pass ] +crbug.com/982194 fast/dom/Range/getClientRects.html [ Failure Pass ] crbug.com/982194 fast/dom/Window/window-postmessage-clone-frames.html [ Failure ] crbug.com/982194 fast/dom/Window/window-postmessage-clone.html [ Timeout ] crbug.com/982194 fast/dom/elementFromPoint-relative-to-viewport.html [ Failure ] @@ -906,7 +906,7 @@ crbug.com/982194 fast/events/inputevents/beforeinput-remove-iframe-crash.html [ Failure ] crbug.com/982194 fast/events/keydown-1.html [ Failure ] crbug.com/982194 fast/events/max-tabindex-focus.html [ Pass Timeout ] -crbug.com/982194 fast/events/menu-key-context-menu-document-pinch-zoom.html [ Failure ] +crbug.com/982194 fast/events/menu-key-context-menu-document-pinch-zoom.html [ Failure Pass ] crbug.com/982194 fast/events/menu-key-context-menu-position.html [ Failure ] crbug.com/982194 fast/events/menu-key-context-menu.html [ Failure ] crbug.com/982194 fast/events/middleClickAutoscroll-click-hyperlink.html [ Failure ] @@ -977,7 +977,7 @@ crbug.com/982194 fast/events/selectstart-by-double-triple-clicks.html [ Failure ] crbug.com/982194 fast/events/selectstart-by-single-click-with-shift.html [ Failure ] crbug.com/982194 fast/events/sequential-focus-navigation-starting-point.html [ Failure ] -crbug.com/982194 fast/events/shift-drag-selection-on-image-triggers-drag-n-drop.html [ Failure ] +crbug.com/982194 fast/events/shift-drag-selection-on-image-triggers-drag-n-drop.html [ Crash Failure ] crbug.com/982194 fast/events/shift-drag-selection-on-link-triggers-drag-n-drop.html [ Failure ] crbug.com/982194 fast/events/simulated-click-coords.html [ Failure ] crbug.com/982194 fast/events/standalone-image-drag-to-editable.html [ Timeout ] @@ -1291,8 +1291,8 @@ crbug.com/982194 fast/scrolling/scrollable-area-frame-scrolling-yes.html [ Failure ] crbug.com/982194 fast/scrolling/scrollable-area-frame-visibility-hidden-child.html [ Failure ] crbug.com/982194 fast/scrolling/scrollable-area-frame.html [ Failure ] -crbug.com/982194 fast/scrolling/scrollbar-tickmarks-styled-after-onload.html [ Failure ] -crbug.com/982194 fast/scrolling/scrollbar-tickmarks-styled.html [ Failure ] +crbug.com/982194 fast/scrolling/scrollbar-tickmarks-styled-after-onload.html [ Failure Pass ] +crbug.com/982194 fast/scrolling/scrollbar-tickmarks-styled.html [ Failure Pass ] crbug.com/889952 fast/selectors/selection-window-inactive.html [ Failure ] crbug.com/591099 fast/selectors/shadow-host-div-with-span.html [ Failure ] crbug.com/591099 fast/selectors/shadow-host-div-with-text.html [ Failure ] @@ -1374,7 +1374,7 @@ crbug.com/982194 fast/writing-mode/border-styles-vertical-lr.html [ Failure ] crbug.com/982194 fast/writing-mode/english-lr-text.html [ Failure ] crbug.com/982194 fast/writing-mode/flipped-blocks-hit-test-line-edges.html [ Failure ] -crbug.com/982194 fast/writing-mode/flipped-blocks-text-map-local-to-container.html [ Failure ] +crbug.com/982194 fast/writing-mode/flipped-blocks-text-map-local-to-container.html [ Failure Pass ] crbug.com/982194 fast/writing-mode/japanese-lr-text.html [ Failure ] crbug.com/982194 fast/writing-mode/vertical-align-table-baseline.html [ Failure ] crbug.com/982194 fast/writing-mode/vertical-inline-block-hittest.html [ Failure ] @@ -1417,12 +1417,12 @@ crbug.com/982194 virtual/text-antialias/complex-text-opacity.html [ Failure ] crbug.com/982194 virtual/text-antialias/descent-clip-in-scaled-page.html [ Failure ] crbug.com/982194 virtual/text-antialias/emoji-vertical-origin-visual.html [ Failure ] -crbug.com/982194 virtual/text-antialias/get-client-rects-grapheme.html [ Failure ] -crbug.com/982194 virtual/text-antialias/glyph-reordering.html [ Failure ] -crbug.com/982194 virtual/text-antialias/international/iso-8859-8.html [ Failure ] -crbug.com/982194 virtual/text-antialias/international/rtl-selection-rect-with-fallback.html [ Failure ] -crbug.com/982194 virtual/text-antialias/line-break-after-inline-latin1.html [ Failure ] -crbug.com/982194 virtual/text-antialias/multiglyph-characters.html [ Failure ] +crbug.com/982194 virtual/text-antialias/get-client-rects-grapheme.html [ Failure Pass ] +crbug.com/982194 virtual/text-antialias/glyph-reordering.html [ Failure Pass ] +crbug.com/982194 virtual/text-antialias/international/iso-8859-8.html [ Failure Pass ] +crbug.com/982194 virtual/text-antialias/international/rtl-selection-rect-with-fallback.html [ Failure Pass ] +crbug.com/982194 virtual/text-antialias/line-break-after-inline-latin1.html [ Failure Pass ] +crbug.com/982194 virtual/text-antialias/multiglyph-characters.html [ Failure Pass ] crbug.com/982194 virtual/text-antialias/orientation-sideways.html [ Failure ] crbug.com/982194 virtual/text-antialias/recalc-position-of-linebox-after-deleting-ellipsis.html [ Failure ] crbug.com/982194 virtual/text-antialias/remove-zero-length-run.html [ Failure ] @@ -1439,14 +1439,14 @@ crbug.com/591099 virtual/text-antialias/selection/selection-rect-line-height-too-small.html [ Failure ] crbug.com/982194 virtual/text-antialias/selection/selection-with-inline-padding.html [ Crash ] crbug.com/982194 virtual/text-antialias/selection/thai-offsetForPosition-inside-character.html [ Failure ] -crbug.com/982194 virtual/text-antialias/text-range-bounds.html [ Failure ] +crbug.com/982194 virtual/text-antialias/text-range-bounds.html [ Failure Pass ] crbug.com/982194 virtual/text-antialias/whitespace/027.html [ Failure ] crbug.com/869364 crbug.com/874695 http/tests/devtools/console/console-correct-suggestions.js [ Crash Pass Timeout ] crbug.com/451577 crbug.com/924308 http/tests/devtools/console/console-dir-es6.js [ Crash Failure Pass Timeout ] crbug.com/451577 http/tests/devtools/console/console-error-on-call-frame.js [ Crash ] crbug.com/451577 crbug.com/924308 http/tests/devtools/console/console-format-es6-2.js [ Crash Failure Pass Timeout ] crbug.com/451577 http/tests/devtools/console/console-format-style.js [ Crash ] -crbug.com/451577 http/tests/devtools/console/console-prompt-keyboard.js [ Failure ] +crbug.com/451577 http/tests/devtools/console/console-prompt-keyboard.js [ Failure Pass ] crbug.com/451577 crbug.com/916975 http/tests/devtools/console/console-repeat-count.js [ Crash Failure Pass Timeout ] crbug.com/451577 http/tests/devtools/console/console-search.js [ Pass ] crbug.com/451577 http/tests/devtools/console/console-truncate-long-messages.js [ Crash ] @@ -1454,7 +1454,7 @@ crbug.com/982194 http/tests/devtools/coverage/decorations-after-script-formatter.js [ Pass Timeout ] crbug.com/846471 http/tests/devtools/coverage/reveal-autoformat.js [ Pass Timeout ] crbug.com/678482 http/tests/devtools/debugger/fetch-breakpoints.js [ Crash ] -crbug.com/982194 http/tests/devtools/editor/text-editor-accessibility.js [ Failure ] +crbug.com/982194 http/tests/devtools/editor/text-editor-accessibility.js [ Failure Pass ] crbug.com/982194 http/tests/devtools/editor/text-editor-block-indent.js [ Pass Timeout ] crbug.com/846997 http/tests/devtools/editor/text-editor-ctrl-d-1.js [ Timeout ] crbug.com/982194 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Pass Timeout ] @@ -1503,7 +1503,7 @@ crbug.com/451577 http/tests/devtools/elements/user-properties.js [ Pass ] crbug.com/941860 http/tests/devtools/extensions/extensions-events.js [ Crash ] crbug.com/246190 crbug.com/989860 http/tests/devtools/indexeddb/live-update-indexeddb-list.js [ Crash Failure Pass Timeout ] -crbug.com/336481 http/tests/devtools/jump-to-previous-editing-location.js [ Failure ] +crbug.com/336481 http/tests/devtools/jump-to-previous-editing-location.js [ Failure Pass ] crbug.com/327078 http/tests/devtools/network/long-script-content.js [ Pass ] crbug.com/938200 http/tests/devtools/network/network-blocked-reason.js [ Pass Timeout ] crbug.com/982194 http/tests/devtools/network/network-close-request-view.js [ Failure ] @@ -1571,10 +1571,10 @@ crbug.com/450493 http/tests/devtools/sources/debugger-frameworks/frameworks-sourcemap.js [ Crash Pass ] crbug.com/450493 http/tests/devtools/sources/debugger-frameworks/frameworks-step-into-skips-setTimeout.js [ Crash Pass ] crbug.com/450493 http/tests/devtools/sources/debugger-frameworks/frameworks-steppings.js [ Crash Pass ] -crbug.com/450493 http/tests/devtools/sources/debugger-pause/debugger-change-variable.js [ Crash ] +crbug.com/450493 http/tests/devtools/sources/debugger-pause/debugger-change-variable.js [ Crash Pass ] crbug.com/450493 http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js [ Crash ] crbug.com/450493 http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused-throws.js [ Crash ] -crbug.com/450493 http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused.js [ Crash ] +crbug.com/450493 http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused.js [ Crash Pass ] crbug.com/450493 http/tests/devtools/sources/debugger-pause/debugger-mute-exception.js [ Crash ] crbug.com/450493 http/tests/devtools/sources/debugger-pause/debugger-pause-in-internal.js [ Crash ] crbug.com/450493 http/tests/devtools/sources/debugger-pause/debugger-pause-infinite-loop.js [ Crash ] @@ -1603,7 +1603,7 @@ crbug.com/450493 http/tests/devtools/sources/debugger-ui/custom-element-lifecycle-events.js [ Crash Pass ] crbug.com/450493 http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js [ Crash ] crbug.com/450493 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Crash ] -crbug.com/450493 http/tests/devtools/sources/debugger-ui/popover-for-spread-operator.js [ Failure ] +crbug.com/450493 http/tests/devtools/sources/debugger-ui/popover-for-spread-operator.js [ Failure Pass ] crbug.com/450493 http/tests/devtools/sources/debugger-ui/reveal-not-skipped.js [ Crash ] crbug.com/450493 http/tests/devtools/sources/debugger-ui/script-formatter-breakpoints-2.js [ Crash ] crbug.com/450493 http/tests/devtools/sources/debugger-ui/script-formatter-breakpoints-3.js [ Crash ] @@ -1624,10 +1624,10 @@ crbug.com/450493 http/tests/devtools/sources/debugger/mutation-observer-suspend-while-paused.js [ Crash Pass ] crbug.com/450493 http/tests/devtools/sources/debugger/rethrow-error-from-bindings-crash.js [ Crash Pass ] crbug.com/450493 http/tests/devtools/sources/debugger/source-frame-breakpoint-decorations.js [ Crash ] -crbug.com/450493 http/tests/devtools/sources/debugger/source-frame-inline-breakpoint-decorations.js [ Crash ] +crbug.com/450493 http/tests/devtools/sources/debugger/source-frame-inline-breakpoint-decorations.js [ Crash Pass ] crbug.com/450493 http/tests/devtools/sources/inline-script-with-source-map.js [ Crash ] crbug.com/450493 http/tests/devtools/sources/source-frame-toolbar-items.js [ Crash Pass ] -crbug.com/450493 http/tests/devtools/sources/sources-pretty-print.js [ Crash ] +crbug.com/450493 http/tests/devtools/sources/sources-pretty-print.js [ Crash Pass ] crbug.com/450493 http/tests/devtools/startup/sources/debugger/script-formatter-breakpoints-1.js [ Crash ] crbug.com/450493 http/tests/devtools/startup/sources/debugger/script-formatter-breakpoints-4.js [ Crash ] crbug.com/450493 http/tests/devtools/startup/sources/debugger/script-formatter-console.js [ Crash ] @@ -1637,7 +1637,7 @@ crbug.com/851363 http/tests/devtools/sxg/sxg-prefetch.js [ Pass ] crbug.com/420008 http/tests/devtools/tracing/hit-test.js [ Failure ] crbug.com/420008 crbug.com/916975 http/tests/devtools/tracing/timeline-misc/timeline-event-causes.js [ Crash Failure Pass Timeout ] -crbug.com/982194 http/tests/devtools/unit/source-frame-pretty-print.js [ Crash ] +crbug.com/982194 http/tests/devtools/unit/source-frame-pretty-print.js [ Crash Pass ] crbug.com/982194 http/tests/download/default-encoding.html [ Timeout ] crbug.com/982194 http/tests/download/inherited-encoding.html [ Timeout ] crbug.com/982194 http/tests/filesystem/input-display.html [ Timeout ] @@ -2278,7 +2278,8 @@ crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-writing-mode-014.html [ Pass ] crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-writing-mode-015.html [ Pass ] crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01.html [ Failure Pass ] -crbug.com/982194 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ] +crbug.com/982194 external/wpt/forced-colors-mode/forced-colors-mode-19.html [ Pass ] +crbug.com/982194 external/wpt/geolocation-API/PositionOptions.https.html [ Failure Pass ] crbug.com/982194 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3q.html [ Pass ] crbug.com/982194 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html [ Pass ] crbug.com/982194 external/wpt/html/semantics/forms/form-submission-0/implicit-submission.optional.html [ Failure ] @@ -2286,6 +2287,7 @@ crbug.com/982194 external/wpt/largest-contentful-paint/element-only-when-fully-active.html [ Timeout ] crbug.com/982194 external/wpt/largest-contentful-paint/first-paint-equals-lcp-text.html [ Timeout ] crbug.com/982194 external/wpt/largest-contentful-paint/toJSON.html [ Timeout ] +crbug.com/982194 external/wpt/mathml/relations/html5-tree/href-click-3.html [ Pass ] crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemBaseHandle-postMessage-BroadcastChannel.tentative.https.window.html [ Crash ] crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemBaseHandle-postMessage-MessagePort.tentative.https.window.html [ Crash ] crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemBaseHandle-postMessage.tentative.https.window.html [ Crash ] @@ -2298,6 +2300,7 @@ crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemWriter.tentative.https.any.html [ Crash Pass ] crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemWriter.tentative.https.any.worker.html [ Crash ] crbug.com/982194 external/wpt/speech-api/SpeechSynthesis-speak-events.html [ Failure ] +crbug.com/982194 external/wpt/uievents/click/click_events_on_input.html [ Timeout ] crbug.com/982194 fast/block/basic/020.html [ Failure ] crbug.com/982194 fast/block/basic/adding-near-anonymous-block.html [ Failure ] crbug.com/982194 fast/block/float/001.html [ Failure ] @@ -2432,6 +2435,7 @@ crbug.com/982194 http/tests/devtools/service-workers/user-agent-override.js [ Pass ] crbug.com/982194 http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await1.js [ Crash Pass ] crbug.com/982194 http/tests/devtools/sources/debugger-async/async-callstack-events.js [ Crash Pass ] +crbug.com/982194 http/tests/devtools/sources/debugger-breakpoints/event-listener-breakpoints-webaudio.js [ Crash Pass ] crbug.com/982194 http/tests/devtools/sources/debugger-step/debugger-step-in.js [ Crash Pass ] crbug.com/982194 http/tests/devtools/tracing/timeline-paint/paint-profiler-update.js [ Pass ] crbug.com/982194 http/tests/devtools/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.js [ Pass Timeout ] @@ -2558,7 +2562,7 @@ crbug.com/982194 virtual/controls-refresh/color-scheme/time/time-appearance-basic.html [ Failure ] crbug.com/982194 virtual/controls-refresh/color-scheme/week/week-appearance-basic.html [ Failure ] crbug.com/982194 virtual/controls-refresh/datetimelocal-picker/datetimelocal-select-value.html [ Failure ] -crbug.com/982194 virtual/disable-deferred-rendering/fast/canvas/OffscreenCanvas-copyImage.html [ Pass ] +crbug.com/982194 virtual/disable-deferred-rendering/fast/canvas/OffscreenCanvas-copyImage.html [ Failure Pass ] crbug.com/982194 virtual/disable-deferred-rendering/fast/canvas/webgl/draw-webgl-to-canvas-2d-after-to-data-url-without-context.html [ Crash ] crbug.com/982194 virtual/disable-deferred-rendering/fast/canvas/webgl/draw-webgl-to-canvas-2d.html [ Crash ] crbug.com/982194 virtual/exotic-color-space/images/55.html [ Failure ] @@ -2882,7 +2886,7 @@ crbug.com/982194 virtual/mouseevent_fractional/fast/events/drag-remove-iframe-crash.html [ Timeout ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/drag-svg-image-crash.html [ Crash ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/drag_and_drop_into_removed_on_focus.html [ Crash ] -crbug.com/982194 virtual/mouseevent_fractional/fast/events/event-hit-testing-fallback-to-iframe.html [ Failure ] +crbug.com/982194 virtual/mouseevent_fractional/fast/events/event-hit-testing-fallback-to-iframe.html [ Crash Failure ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/event-on-culled-inline-with-pseudo.html [ Failure ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/event-on-culled_inline.html [ Failure ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/event-trusted.html [ Failure ] @@ -2896,7 +2900,7 @@ crbug.com/982194 virtual/mouseevent_fractional/fast/events/input-image-scrolled-x-y.html [ Timeout ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/inputevents/beforeinput-remove-iframe-crash.html [ Failure ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/keydown-1.html [ Failure ] -crbug.com/982194 virtual/mouseevent_fractional/fast/events/menu-key-context-menu-document-pinch-zoom.html [ Failure ] +crbug.com/982194 virtual/mouseevent_fractional/fast/events/menu-key-context-menu-document-pinch-zoom.html [ Failure Pass ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/menu-key-context-menu-position.html [ Failure ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/menu-key-context-menu.html [ Crash Failure ] crbug.com/982194 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-drag-scrollable-iframe-div.html [ Crash ] @@ -3087,8 +3091,8 @@ crbug.com/982194 virtual/scroll_customization/fast/scrolling/scrollable-area-frame-scrolling-yes.html [ Failure ] crbug.com/982194 virtual/scroll_customization/fast/scrolling/scrollable-area-frame-visibility-hidden-child.html [ Failure ] crbug.com/982194 virtual/scroll_customization/fast/scrolling/scrollable-area-frame.html [ Failure ] -crbug.com/982194 virtual/scroll_customization/fast/scrolling/scrollbar-tickmarks-styled-after-onload.html [ Failure ] -crbug.com/982194 virtual/scroll_customization/fast/scrolling/scrollbar-tickmarks-styled.html [ Failure ] +crbug.com/982194 virtual/scroll_customization/fast/scrolling/scrollbar-tickmarks-styled-after-onload.html [ Failure Pass ] +crbug.com/982194 virtual/scroll_customization/fast/scrolling/scrollbar-tickmarks-styled.html [ Failure Pass ] crbug.com/982194 virtual/speech-with-unified-autoplay/external/wpt/speech-api/SpeechSynthesis-speak-events.html [ Failure ] crbug.com/982194 virtual/speech-with-unified-autoplay/external/wpt/speech-api/SpeechSynthesis-speak-ownership.html [ Timeout ] crbug.com/982194 virtual/speech-with-unified-autoplay/external/wpt/speech-api/SpeechSynthesis-speak-without-activation-fails.tentative.html [ Pass ] @@ -3188,8 +3192,9 @@ crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollable-area-frame-scrolling-yes.html [ Failure ] crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollable-area-frame-visibility-hidden-child.html [ Failure ] crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollable-area-frame.html [ Failure ] -crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollbar-tickmarks-styled-after-onload.html [ Failure ] -crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollbar-tickmarks-styled.html [ Failure ] +crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollbar-tickmarks-styled-after-onload.html [ Failure Pass ] +crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollbar-tickmarks-styled.html [ Failure Pass ] +crbug.com/982194 virtual/threaded/external/wpt/css/css-animations/CSSAnimation-canceling.tentative.html [ Failure Pass ] crbug.com/982194 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html [ Pass ] crbug.com/982194 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html [ Pass ] crbug.com/982194 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-disabled-frame-no-scroll-manual.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations index 27a7b4ec..7900c0d6 100644 --- a/third_party/blink/web_tests/LeakExpectations +++ b/third_party/blink/web_tests/LeakExpectations
@@ -105,8 +105,6 @@ # Only times out on the leak bots. crbug.com/998399 [ Linux ] virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-interception.https.html [ Pass Timeout ] -crbug.com/1023242 [ Linux ] editing/input/edit-context.html [ Pass Failure ] - ########################################################################### # WARNING: Memory leaks must be fixed asap. Sheriff is expected to revert # # culprit CLs instead of suppressing the leaks. If you have any question, #
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 7c52b4a8..1dda27d 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -69,7 +69,6 @@ crbug.com/678491 http/tests/misc/webtiming-no-origin.html [ Crash Pass ] crbug.com/765779 http/tests/loading/bad-server-subframe.html [ Failure ] crbug.com/801992 http/tests/misc/iframe-script-modify-attr.html [ Pass Crash ] -crbug.com/819800 external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html [ Failure ] crbug.com/872952 http/tests/media/autoplay/document-user-activation-feature-policy-iframe-no-gesture.html [ Failure Pass Timeout ] crbug.com/872952 virtual/audio-service/http/tests/media/autoplay/document-user-activation-feature-policy-iframe-no-gesture.html [ Failure Pass Timeout ] crbug.com/895001 external/wpt/html/user-activation/message-event-activation-api-iframe-cross-origin.sub.tentative.html [ Timeout Pass ] @@ -1480,12 +1479,7 @@ # ====== MathMLCore-only tests from here ====== crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction-006.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction-007.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction-008.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction-009.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction-010.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction-overall.html [ Failure ] -crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction-token.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/direction/direction.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/fractions/frac-1.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/fractions/frac-bar-001.html [ Failure ] @@ -1566,7 +1560,6 @@ crbug.com/6606 external/wpt/mathml/presentation-markup/tables/table-001.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/tables/table-002.html [ Failure ] crbug.com/6606 external/wpt/mathml/presentation-markup/tables/table-axis-height.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/attribute-mapping-001.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/attribute-mapping-002.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/color-002.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/color-003.html [ Failure ] @@ -1579,21 +1572,11 @@ crbug.com/6606 external/wpt/mathml/relations/css-styling/displaystyle-015.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/displaystyle-1.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/displaystyle-2.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/dynamic-dir-1.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/ignored-properties-001.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/lengths-1.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/lengths-2.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathbackground-001.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathbackground-002.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathbackground-003.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/mathbackground-004.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathcolor-001.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathcolor-002.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathcolor-003.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/mathcolor-004.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathsize-attribute-css-keywords.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathsize-attribute-legacy-values.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/css-styling/mathsize-attribute.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-auto.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-bold-fraktur.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/mathvariant-bold-italic.html [ Failure ] @@ -1627,7 +1610,6 @@ crbug.com/6606 external/wpt/mathml/relations/css-styling/width-height-001.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/writing-mode/writing-mode-001.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/css-styling/writing-mode/writing-mode-002.html [ Failure ] -crbug.com/6606 external/wpt/mathml/relations/html5-tree/color-attributes-1.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/html5-tree/display-1.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/html5-tree/display-2.html [ Failure ] crbug.com/6606 external/wpt/mathml/relations/html5-tree/href-click-1.html [ Failure ]
diff --git a/third_party/blink/web_tests/editing/input/edit-context.html b/third_party/blink/web_tests/editing/input/edit-context.html index a7747dab..511eeef 100644 --- a/third_party/blink/web_tests/editing/input/edit-context.html +++ b/third_party/blink/web_tests/editing/input/edit-context.html
@@ -457,13 +457,12 @@ const textarea = childDocument.createElement('textarea'); childDocument.body.appendChild(textarea); textarea.addEventListener("focusin", e => { - childDocument.childEditContext = new EditContext() - childDocument.childEditContext.focus(); - childDocument.childEditContext.addEventListener("textupdate", e => { - console.log("iframe textupdate event fired"); + const childEditContext = new EditContext() + childEditContext.focus(); + childEditContext.addEventListener("textupdate", e => { child.remove(); }); - childDocument.childEditContext.addEventListener("textformatupdate", e => { + childEditContext.addEventListener("textformatupdate", e => { }); }); textarea.focus(); @@ -472,26 +471,14 @@ }, 'Testing EditContext Iframe Document Delete'); test(function() { - // SetComposition should not crash when event handler removes document - const child = document.createElement("iframe"); - document.body.appendChild(child); - const childDocument = child.contentDocument; - const textarea = childDocument.createElement('textarea'); - childDocument.body.appendChild(textarea); - textarea.addEventListener("focusin", e => { - childDocument.childEditContext = new EditContext() - childDocument.childEditContext.focus() - childDocument.childEditContext.addEventListener("textupdate", e => { - console.log("textupdate event fired"); - textarea.remove(); - }); - childDocument.childEditContext.addEventListener("textformatupdate", e => { - }); + const editContext1 = new EditContext(); + editContext1.addEventListener("textupdate", e => { }); - child.contentWindow.focus(); - textarea.focus(); + editContext1.focus(); + gc() textInputController.setComposition("bar"); -}, 'Testing EditContext Iframe Element Delete'); + +}, 'Testing EditContext GC'); </script> </body>
diff --git a/third_party/blink/web_tests/editing/selection/move-selection-detached-frame-crash-expected.txt b/third_party/blink/web_tests/editing/selection/move-selection-detached-frame-crash-expected.txt new file mode 100644 index 0000000..880026b --- /dev/null +++ b/third_party/blink/web_tests/editing/selection/move-selection-detached-frame-crash-expected.txt
@@ -0,0 +1,9 @@ +Should not crash if iframe's document element's focusout event handler removes the iframe in the parent document and the selection is moved. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + +PASS Did not crash. +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/blink/web_tests/editing/selection/move-selection-detached-frame-crash.html b/third_party/blink/web_tests/editing/selection/move-selection-detached-frame-crash.html new file mode 100644 index 0000000..238adc5 --- /dev/null +++ b/third_party/blink/web_tests/editing/selection/move-selection-detached-frame-crash.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> + <script src="../../resources/js-test.js"></script> +</head> +<body> + <iframe></iframe> + <script> + description('Should not crash if iframe\'s document element\'s focusout event handler removes the iframe in the parent document and the selection is moved.'); + + function run() { + var iframe = document.getElementsByTagName('iframe')[0]; + iframe.contentDocument.documentElement.contentEditable = true; + iframe.contentDocument.documentElement.addEventListener('focusout', function () { + iframe.parentNode.removeChild(iframe); + }, false); + iframe.contentDocument.documentElement.focus(); + + if (window.eventSender) + eventSender.keyDown('ArrowDown'); + + testPassed('Did not crash.'); + window.finishJSTest(); + } + + document.addEventListener('DOMContentLoaded', run); + </script> +</body> +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index d9623a8..2e84db1 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -61799,6 +61799,18 @@ {} ] ], + "css/css-position/position-absolute-dynamic-relayout-002.html": [ + [ + "css/css-position/position-absolute-dynamic-relayout-002.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-position/position-absolute-dynamic-static-position-floats-001.html": [ [ "css/css-position/position-absolute-dynamic-static-position-floats-001.html", @@ -165379,6 +165391,9 @@ "mathml/presentation-markup/spaces/space-2-ref.html": [ [] ], + "mathml/relations/css-styling/attribute-mapping-001-expected.txt": [ + [] + ], "mathml/relations/css-styling/color-001-ref.html": [ [] ], @@ -167239,9 +167254,6 @@ "payment-request/allowpaymentrequest/echo-PaymentRequest.html": [ [] ], - "payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt": [ - [] - ], "payment-request/blank.html": [ [] ], @@ -172129,9 +172141,6 @@ "service-workers/service-worker/resources/xslt-pass.xsl": [ [] ], - "service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https-expected.txt": [ - [] - ], "service-workers/service-worker/unregister-then-register-new-script.https-expected.txt": [ [] ], @@ -173608,6 +173617,9 @@ "tools/manifest/sourcefile.py": [ [] ], + "tools/manifest/testpaths.py": [ + [] + ], "tools/manifest/update.py": [ [] ], @@ -179221,9 +179233,6 @@ "webrtc/RTCPeerConnection-helper.js": [ [] ], - "webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt": [ - [] - ], "webrtc/RTCPeerConnection-iceGatheringState-expected.txt": [ [] ], @@ -213634,6 +213643,12 @@ {} ] ], + "css/css-position/position-absolute-crash-chrome-013.html": [ + [ + "css/css-position/position-absolute-crash-chrome-013.html", + {} + ] + ], "css/css-position/position-absolute-dynamic-containing-block.html": [ [ "css/css-position/position-absolute-dynamic-containing-block.html", @@ -340351,7 +340366,7 @@ "support" ], "README.md": [ - "e3ee8551ff48a77652e2a4dc4fbc677e0812c5c5", + "8f755f2ac2fc88e012b32803fc65a68baa538596", "support" ], "WebCryptoAPI/META.yml": [ @@ -393670,6 +393685,10 @@ "f012ff572691d9c42fb8f642a2fa47e524a4cacf", "testharness" ], + "css/css-position/position-absolute-crash-chrome-013.html": [ + "8f0daf4bfe4aef4916e3cfb037181cf8124fb938", + "testharness" + ], "css/css-position/position-absolute-dynamic-containing-block.html": [ "3968f685849663574ca213fcb90dc5fb3eaffaa3", "testharness" @@ -393690,6 +393709,10 @@ "1bde15551e7952cce210463d156217a51d3f30f3", "reftest" ], + "css/css-position/position-absolute-dynamic-relayout-002.html": [ + "4dc2dc0f803dd657c90e62529f7f37f6a1efc108", + "reftest" + ], "css/css-position/position-absolute-dynamic-static-position-floats-001.html": [ "a63df41089e7e75d33ee1f46d458e97c8ebf0fb0", "reftest" @@ -406831,7 +406854,7 @@ "support" ], "css/css-text/word-break/reference/word-break-break-all-inline-006-ref.html": [ - "0232ecb6f011358493059518be22e98697d45d76", + "268536c98e066b3b6cf9db6fbf67e944c86dbe44", "support" ], "css/css-text/word-break/reference/word-break-break-all-inline-007-ref.html": [ @@ -407099,7 +407122,7 @@ "reftest" ], "css/css-text/word-break/word-break-break-all-inline-006.html": [ - "af2f6fb90b23db36f7e0db531f89475dfa632cd3", + "9f9a618ebfed4e1b747199d36741f5e567b3ceb0", "reftest" ], "css/css-text/word-break/word-break-break-all-inline-007.html": [ @@ -469526,8 +469549,12 @@ "f9354266a7c6c42a75519e9771eb2c61536ad8e5", "testharness" ], + "mathml/relations/css-styling/attribute-mapping-001-expected.txt": [ + "5c64785af046109797f9980ec7da6db6f4b3acb1", + "support" + ], "mathml/relations/css-styling/attribute-mapping-001.html": [ - "e7c6391ebad2aad8b8d31db056a209ad1d7ebba5", + "3424e8c1a8cbb775a91839db6b3951dfe869af95", "testharness" ], "mathml/relations/css-styling/attribute-mapping-002.html": [ @@ -482014,10 +482041,6 @@ "b0e0cbacbf2e611139cd30747acaaf1186ae21f6", "testharness" ], - "payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt": [ - "2103791bb0a8ef4c9d6314c4e217a2121955922a", - "support" - ], "payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html": [ "45661de7e0dedd19cda4a7a2f0a76aaa72e91ccc", "testharness" @@ -497119,7 +497142,7 @@ "support" ], "resources/testdriver-actions.js": [ - "292fe8889f5e21bd011ade89edf540cc615e35b2", + "d3dc00b4d0f002670258e56d59d33061f4fc5775", "support" ], "resources/testdriver-vendor.js.headers": [ @@ -497351,11 +497374,11 @@ "testharness" ], "scroll-to-text-fragment/scroll-to-text-fragment-target.html": [ - "1ef9dbba519697c61529fba0e81dc64979257e70", + "1595d8bff9ebeefe0d22052cfe4dea59a8c5b750", "support" ], "scroll-to-text-fragment/scroll-to-text-fragment.html": [ - "b3a35f489aca424b24c57b40796a179c5ee5b4c7", + "c0018eda03fc40f99f61468fea01945b73979f2f", "testharness" ], "secure-contexts/META.yml": [ @@ -500970,12 +500993,8 @@ "e08b71645325cd8fe94f1001bc778ed325571a98", "testharness" ], - "service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https-expected.txt": [ - "01dcfe66bfabba0b491786e3b1c3b753feaeaa4f", - "support" - ], "service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https.html": [ - "a58525f422203b087a2c88ef24cfadfa567fade2", + "70be6ef9b0a956707384030b1be17b702663976f", "testharness" ], "service-workers/service-worker/service-worker-csp-connect.https.html": [ @@ -506395,7 +506414,7 @@ "support" ], "tools/manifest/commands.json": [ - "074d248bf27a417933195ad4f8d232468bb1b6dd", + "769675e0ee42c6efc36fc1150778682f933a6465", "support" ], "tools/manifest/download.py": [ @@ -506403,7 +506422,7 @@ "support" ], "tools/manifest/item.py": [ - "a38709193a9bed82e6bff5849c07679abb6abafd", + "217f6cac262fba020c044d963d42ca55a2361e53", "support" ], "tools/manifest/log.py": [ @@ -506411,13 +506430,17 @@ "support" ], "tools/manifest/manifest.py": [ - "8aace771cba32acca56c9c37887d4a900cafbeb0", + "6fb591b9c314b0dd01d93ff12f3820bf26d4fe79", "support" ], "tools/manifest/sourcefile.py": [ "4788fc9bdb640447eb9997808c5b7110661a3960", "support" ], + "tools/manifest/testpaths.py": [ + "3c1f09d437304a0ce7bbcbc542dede672f01a17e", + "support" + ], "tools/manifest/update.py": [ "bfbaaf897126d8eeca69dcef94bb31308897fde2", "support" @@ -520174,12 +520197,8 @@ "dbfc41e0c375dea0711a8cf312846cbdb27c570b", "testharness" ], - "webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt": [ - "1b3bb5465db7e3f971107832f97d33b4f93e4130", - "support" - ], "webrtc/RTCPeerConnection-iceConnectionState.https.html": [ - "32f2eb9b4607121ad9aa0db99a05e3ab78750f7e", + "a2b2827b8494af7e33e5c81b765b92041064fe6f", "testharness" ], "webrtc/RTCPeerConnection-iceGatheringState-expected.txt": [
diff --git a/third_party/blink/web_tests/external/wpt/README.md b/third_party/blink/web_tests/external/wpt/README.md index e3ee855..8f755f2a 100644 --- a/third_party/blink/web_tests/external/wpt/README.md +++ b/third_party/blink/web_tests/external/wpt/README.md
@@ -48,128 +48,9 @@ Running the Tests ================= -The tests are designed to be run from your local computer. The test -environment requires [Python 2.7+](http://www.python.org/downloads) (but not Python 3.x). - -On Windows, be sure to add the Python directory (`c:\python2x`, by default) to -your `%Path%` [Environment Variable](http://www.computerhope.com/issues/ch000549.htm), -and read the [Windows Notes](#windows-notes) section below. - -To get the tests running, you need to set up the test domains in your -[`hosts` file](http://en.wikipedia.org/wiki/Hosts_%28file%29%23Location_in_the_file_system). - -The necessary content can be generated with `./wpt make-hosts-file`; on -Windows, you will need to precede the prior command with `python` or -the path to the Python binary (`python wpt make-hosts-file`). - -For example, on most UNIX-like systems, you can setup the hosts file with: - -```bash -./wpt make-hosts-file | sudo tee -a /etc/hosts -``` - -And on Windows (this must be run in a PowerShell session with Administrator privileges): - -```powershell -python wpt make-hosts-file | Out-File $env:systemroot\System32\drivers\etc\hosts -Encoding ascii -Append -``` - -If you are behind a proxy, you also need to make sure the domains above are -excluded from your proxy lookups. - - -Running Tests Manually -====================== - -The test server can be started using -``` -./wpt serve -``` - -**On Windows**: You will need to precede the prior command with -`python` or the path to the python binary. -```bash -python wpt serve -``` - -This will start HTTP servers on two ports and a websockets server on -one port. By default the web servers start on ports 8000 and 8443 and -the other ports are randomly-chosen free ports. Tests must be loaded -from the *first* HTTP server in the output. To change the ports, -create a `config.json` file in the wpt root directory, and add -port definitions of your choice e.g.: - -``` -{ - "ports": { - "http": [1234, "auto"], - "https":[5678] - } -} -``` - -After your `hosts` file is configured, the servers will be locally accessible at: - -http://web-platform.test:8000/<br> -https://web-platform.test:8443/ * - -To use the web-based runner point your browser to: - -http://web-platform.test:8000/tools/runner/index.html <br> -https://web-platform.test:8443/tools/runner/index.html * - -\**See [Trusting Root CA](./tools/certs/README.md)* - -Running Tests Automatically ---------------------------- - -Tests can be run automatically in a browser using the `run` command of -the `wpt` script in the root of the checkout. This requires the hosts -file setup documented above, but you must *not* have the -test server already running when calling `wpt run`. The basic command -line syntax is: - -```bash -./wpt run product [tests] -``` - -**On Windows**: You will need to precede the prior command with -`python` or the path to the python binary. -```bash -python wpt run product [tests] -``` - -where `product` is currently `firefox` or `chrome` and `[tests]` is a -list of paths to tests. This will attempt to automatically locate a -browser instance and install required dependencies. The command is -very configurable; for example to specify a particular binary use -`wpt run --binary=path product`. The full range of options can be see -with `wpt run --help` and `wpt run --wptrunner-help`. - -Not all dependencies can be automatically installed; in particular the -`certutil` tool required to run https tests with Firefox must be -installed using a system package manager or similar. - -On Debian/Ubuntu certutil may be installed using: - -``` -sudo apt install libnss3-tools -``` - -And on macOS with homebrew using: - -``` -brew install nss -``` - -On other platforms, download the firefox archive and common.tests.tar.gz -archive for your platform from -[Mozilla CI](https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/). - -Then extract `certutil[.exe]` from the tests.tar.gz package and -`libnss3[.so|.dll|.dynlib]` and put the former on your path and the latter on -your library path. - +See the [documentation website](https://web-platform-tests.org/running-tests/) +and in particular the +[system setup for running tests locally](https://web-platform-tests.org/running-tests/from-local-system.html#system-setup). Command Line Tools ==================
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/CSSPseudoElement-getAnimations.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/CSSPseudoElement-getAnimations.tentative-expected.txt deleted file mode 100644 index 08e57b14..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/CSSPseudoElement-getAnimations.tentative-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -PASS getAnimations returns CSSAnimation objects -FAIL getAnimations returns CSS transitions/animations, and script-generated animations in the expected order assert_equals: 1st animation is the 1st transition sorted by name expected (string) "height" but got (undefined) undefined -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/CSSPseudoElement-getAnimations.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/CSSPseudoElement-getAnimations.tentative.html deleted file mode 100644 index 8fcdf38..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/CSSPseudoElement-getAnimations.tentative.html +++ /dev/null
@@ -1,75 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<title>CSSPseudoElement.getAnimations() for CSS animations</title> -<!-- TODO: Add a more specific link for this once it is specified. --> -<link rel="help" href="https://drafts.csswg.org/css-animations-2/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="support/testcommon.js"></script> -<style> -@keyframes anim1 { } -@keyframes anim2 { } -.before::before { - animation: anim1 10s; - content: ''; -} -.after-with-mix-anims-trans::after { - content: ''; - animation: anim1 10s, anim2 10s; - width: 0px; - height: 0px; - transition: all 100s; -} -.after-change::after { - width: 100px; - height: 100px; - content: ''; -} -</style> -<div id="log"></div> -<script> -'use strict'; - -test(t => { - const div = addDiv(t, { class: 'before' }); - const pseudoTarget = document.getAnimations()[0].effect.target; - assert_equals(pseudoTarget.getAnimations().length, 1, - 'Expected number of animations are returned'); - assert_equals(pseudoTarget.getAnimations()[0].animationName, 'anim1', - 'CSS animation name matches'); -}, 'getAnimations returns CSSAnimation objects'); - -test(t => { - const div = addDiv(t, { class: 'after-with-mix-anims-trans' }); - // Trigger transitions - flushComputedStyle(div); - div.classList.add('after-change'); - - // Create additional animation on the pseudo-element from script - const pseudoTarget = document.getAnimations()[0].effect.target; - const effect = new KeyframeEffect(pseudoTarget, - { background: ["blue", "red"] }, - 3 * MS_PER_SEC); - const newAnimation = new Animation(effect, document.timeline); - newAnimation.id = 'scripted-anim'; - newAnimation.play(); - - // Check order - the script-generated animation should appear later - const anims = pseudoTarget.getAnimations(); - assert_equals(anims.length, 5, - 'Got expected number of animations/trnasitions running on ' + - '::after pseudo element'); - assert_equals(anims[0].transitionProperty, 'height', - '1st animation is the 1st transition sorted by name'); - assert_equals(anims[1].transitionProperty, 'width', - '2nd animation is the 2nd transition sorted by name '); - assert_equals(anims[2].animationName, 'anim1', - '3rd animation is the 1st animation in animation-name list'); - assert_equals(anims[3].animationName, 'anim2', - '4rd animation is the 2nd animation in animation-name list'); - assert_equals(anims[4].id, 'scripted-anim', - 'Animation added by script appears last'); -}, 'getAnimations returns CSS transitions/animations, and script-generated ' + - 'animations in the expected order'); - -</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/Document-getAnimations.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/Document-getAnimations.tentative-expected.txt index 7bd0e24..e65479c4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/Document-getAnimations.tentative-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/Document-getAnimations.tentative-expected.txt
@@ -12,6 +12,6 @@ PASS Yet-to-start CSS Animations are returned PASS CSS Animations canceled via the API are not returned PASS CSS Animations canceled and restarted via the API are returned -FAIL CSS Animations targetting (pseudo-)elements should have correct order after sorting assert_equals: Animation #2 has expected target expected (object) Element node <div id="parent" style="animation: animBottom 100s"><div ... but got (undefined) undefined +FAIL CSS Animations targetting (pseudo-)elements should have correct order after sorting assert_equals: Animation #1 has null pseudo type expected (object) null but got (undefined) undefined Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/Document-getAnimations.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/Document-getAnimations.tentative.html index 175acf84..ba8c6d91 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/Document-getAnimations.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/Document-getAnimations.tentative.html
@@ -298,12 +298,12 @@ if (pseudo) { assert_equals( - actual.effect.target.element, + actual.effect.target, element, `Animation #${index + 1} has expected target` ); assert_equals( - actual.effect.target.type, + actual.effect.pseudoElement, pseudo, `Animation #${index + 1} has expected pseudo type` ); @@ -313,6 +313,11 @@ element, `Animation #${index + 1} has expected target` ); + assert_equals( + actual.effect.pseudoElement, + null, + `Animation #${index + 1} has null pseudo type` + ); } } }, 'CSS Animations targetting (pseudo-)elements should have correct order '
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative-expected.txt index f8481b4..544ec617 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative-expected.txt
@@ -17,9 +17,9 @@ PASS getAnimations for CSS Animations that are canceled FAIL getAnimations for CSS Animations follows animation-name order assert_equals: animation order after prepending to list expected "anim1" but got "anim2" PASS { subtree: false } on a leaf element returns the element's animations and ignore pseudo-elements -FAIL { subtree: true } on a leaf element returns the element's animations and its pseudo-elements' animations assert_equals: The animation targeting the ::before pseudo-element should be returned second expected (string) "::before" but got (undefined) undefined +FAIL { subtree: true } on a leaf element returns the element's animations and its pseudo-elements' animations assert_equals: The animation targeting the parent element should be returned first expected (object) null but got (undefined) undefined PASS { subtree: false } on an element with a child returns only the element's animations -FAIL { subtree: true } on an element with a child returns animations from the element, its pseudo-elements, its child and its child pseudo-elements assert_equals: The animation targeting the ::before pseudo-element should be returned second expected (string) "::before" but got (undefined) undefined +FAIL { subtree: true } on an element with a child returns animations from the element, its pseudo-elements, its child and its child pseudo-elements assert_equals: The animation targeting the parent element should be returned first expected (object) null but got (undefined) undefined PASS { subtree: true } on an element with many descendants returns animations from all the descendants Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative.html index 5690a7d..5419e11e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative.html
@@ -325,10 +325,13 @@ assert_equals(animations[0].effect.target, target, 'The animation targeting the parent element ' + 'should be returned first'); - assert_equals(animations[1].effect.target.type, '::before', + assert_equals(animations[0].effect.pseudoElement, null, + 'The animation targeting the parent element ' + + 'should be returned first') + assert_equals(animations[1].effect.pseudoElement, '::before', 'The animation targeting the ::before pseudo-element ' + 'should be returned second'); - assert_equals(animations[2].effect.target.type, '::after', + assert_equals(animations[2].effect.pseudoElement, '::after', 'The animation targeting the ::after pesudo-element ' + 'should be returned last'); }, '{ subtree: true } on a leaf element returns the element\'s animations' @@ -366,34 +369,37 @@ const animations = parent.getAnimations({ subtree: true }); assert_equals(animations.length, 6, - 'Should find all elements, pesudo-elements that parent has'); + 'Should find all elements, pseudo-elements that parent has'); assert_equals(animations[0].effect.target, parent, 'The animation targeting the parent element ' + 'should be returned first'); - assert_equals(animations[1].effect.target.type, '::before', + assert_equals(animations[0].effect.pseudoElement, null, + 'The animation targeting the parent element ' + + 'should be returned first'); + assert_equals(animations[1].effect.pseudoElement, '::before', 'The animation targeting the ::before pseudo-element ' + 'should be returned second'); - assert_equals(animations[1].effect.target.element, parent, + assert_equals(animations[1].effect.target, parent, 'This ::before element should be child of parent element'); - assert_equals(animations[2].effect.target.type, '::after', + assert_equals(animations[2].effect.pseudoElement, '::after', 'The animation targeting the ::after pesudo-element ' + 'should be returned third'); - assert_equals(animations[2].effect.target.element, parent, + assert_equals(animations[2].effect.target, parent, 'This ::after element should be child of parent element'); assert_equals(animations[3].effect.target, child, 'The animation targeting the child element ' + 'should be returned fourth'); - assert_equals(animations[4].effect.target.type, '::before', + assert_equals(animations[4].effect.pseudoElement, '::before', 'The animation targeting the ::before pseudo-element ' + 'should be returned fifth'); - assert_equals(animations[4].effect.target.element, child, + assert_equals(animations[4].effect.target, child, 'This ::before element should be child of child element'); - assert_equals(animations[5].effect.target.type, '::after', + assert_equals(animations[5].effect.pseudoElement, '::after', 'The animation targeting the ::after pesudo-element ' + 'should be returned last'); - assert_equals(animations[5].effect.target.element, child, + assert_equals(animations[5].effect.target, child, 'This ::after element should be child of child element'); }, '{ subtree: true } on an element with a child returns animations from the' + ' element, its pseudo-elements, its child and its child pseudo-elements');
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/widows-orphans-005.html b/third_party/blink/web_tests/external/wpt/css/css-break/widows-orphans-005.html new file mode 100644 index 0000000..7138497 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/widows-orphans-005.html
@@ -0,0 +1,45 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-break/#widows-orphans"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1022348"> +<meta name="assert" content="Here's a multicol container with four lines, and a widows requirement of 2. We cannot honor that requirement, because the third line alone is too tall to fit in a column."> +<style> + .multicol { + position: relative; + columns: 3; + column-fill: auto; + column-gap: 10px; + width: 320px; + height: 200px; + orphans: 1; + widows: 2; + column-rule: 1px dotted; + line-height: 20px; + } + .ibk { + display: inline-block; + width: 70px; + } +</style> +<p> + There should be three columns below. In the first column there should be a + black rectangle and a yellow rectangle. In the second column there should be a + cyan rectangle. In the third column there should be a hotpink rectangle.</p> +<div class="multicol"> + <div class="ibk" style="height:50px; background:black;" data-offset-x="0"></div><br> + <div class="ibk" style="height:50px; background:yellow;" data-offset-x="0"></div><br> + <div class="ibk" style="height:285px;" data-offset-x="110"> + <!-- The implementations differ here. Gecko lets the inline-block overflow + the column, while Blink slices the inline-block and puts what doesn't + fit in the second column into the third. Blink has a bug, but that's + not the bug we want to test here. --> + <div style="height:100px; background:cyan;"></div> + </div><br> + <div class="ibk" style="height:10px; background:hotpink;" data-offset-x="220"></div><br> +</div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<script> + checkLayout("[data-offset-x]"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-crash-chrome-013.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-crash-chrome-013.html new file mode 100644 index 0000000..8f0daf4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-crash-chrome-013.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<link rel="help" href="https://crbug.com/1021676"> +<div id="tfoot" style="display: table-footer-group; transform: scale(2);"> + <div id="oof" style="position: absolute;">text</div> +</div> +<script> +test(() => { + document.body.offsetTop; + + // Make the ICB the containing-block. + document.getElementById('tfoot').style.transform = ''; + document.body.offsetTop; + + document.getElementById('oof').innerText = ''; + document.body.offsetTop; +}, 'test passes if it does not crash'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSPseudoElement-getAnimations.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSPseudoElement-getAnimations.tentative-expected.txt deleted file mode 100644 index 63466c3f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSPseudoElement-getAnimations.tentative-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL getAnimations sorts simultaneous transitions by name assert_class_string: Got pseudo-element target expected "[object CSSPseudoElement]" but got "[object Element]" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSPseudoElement-getAnimations.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSPseudoElement-getAnimations.tentative.html deleted file mode 100644 index 5229881e..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSPseudoElement-getAnimations.tentative.html +++ /dev/null
@@ -1,47 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<title>CSSPseudoElement.getAnimations() for CSS transitions</title> -<link rel="help" href="https://drafts.csswg.org/css-transitions-2/#animation-composite-order"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="support/helper.js"></script> -<style> -.init::before { - content: ''; - height: 0px; - width: 0px; - opacity: 0; - transition: all 100s; -} -.change::before { - height: 100px; - width: 100px; - opacity: 1; -} -</style> -<div id="log"></div> -<script> -'use strict'; - -test(t => { - const div = addDiv(t, { class: 'init' }); - getComputedStyle(div).width; - div.classList.add('change'); - - // Sanity checks - assert_equals(document.getAnimations().length, 3, - 'Got expected number of animations on document'); - const pseudoTarget = document.getAnimations()[0].effect.target; - assert_class_string(pseudoTarget, 'CSSPseudoElement', - 'Got pseudo-element target'); - - // Check animations returned from the pseudo element are in correct order - const anims = pseudoTarget.getAnimations(); - assert_equals(anims.length, 3, - 'Got expected number of animations on pseudo-element'); - assert_equals(anims[0].transitionProperty, 'height'); - assert_equals(anims[1].transitionProperty, 'opacity'); - assert_equals(anims[2].transitionProperty, 'width'); -}, 'getAnimations sorts simultaneous transitions by name'); - -</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/Document-getAnimations.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transitions/Document-getAnimations.tentative-expected.txt index d859a1c..477dcaf 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/Document-getAnimations.tentative-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/Document-getAnimations.tentative-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. PASS getAnimations for non-animated content PASS getAnimations for CSS Transitions -FAIL CSS Transitions targetting (pseudo-)elements should have correct order after sorting assert_equals: Transition #2 has expected target expected (object) Element node <div style="display: list-item; left: 100px; transition: ... but got (undefined) undefined +FAIL CSS Transitions targetting (pseudo-)elements should have correct order after sorting assert_equals: Transition #1 has null pseudo type expected (object) null but got (undefined) undefined PASS Transitions are not returned after they have finished Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/Document-getAnimations.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/Document-getAnimations.tentative.html index 98b91e0..cecddfaa 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/Document-getAnimations.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/Document-getAnimations.tentative.html
@@ -99,12 +99,12 @@ if (pseudo) { assert_equals( - actual.effect.target.element, + actual.effect.target, element, `Transition #${index + 1} has expected target` ); assert_equals( - actual.effect.target.type, + actual.effect.pseudoElement, pseudo, `Transition #${index + 1} has expected pseudo type` ); @@ -114,6 +114,11 @@ element, `Transition #${index + 1} has expected target` ); + assert_equals( + actual.effect.pseudoElement, + null, + `Transition #${index + 1} has null pseudo type` + ); } } }, 'CSS Transitions targetting (pseudo-)elements should have correct order '
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001-expected.txt b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001-expected.txt new file mode 100644 index 0000000..5c64785a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001-expected.txt
@@ -0,0 +1,164 @@ +This is a testharness.js-based test. +Found 160 tests; 158 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS dir on the math element is mapped to CSS direction +PASS mathcolor on the math element is mapped to CSS color +PASS mathbackground on the math element is mapped to CSS background-color +PASS mathsize on the math element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the math element are not mapped to CSS +PASS dir on the annotation element is mapped to CSS direction +PASS mathcolor on the annotation element is mapped to CSS color +PASS mathbackground on the annotation element is mapped to CSS background-color +PASS mathsize on the annotation element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the annotation element are not mapped to CSS +PASS dir on the annotation-xml element is mapped to CSS direction +PASS mathcolor on the annotation-xml element is mapped to CSS color +PASS mathbackground on the annotation-xml element is mapped to CSS background-color +PASS mathsize on the annotation-xml element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the annotation-xml element are not mapped to CSS +PASS dir on the maction element is mapped to CSS direction +PASS mathcolor on the maction element is mapped to CSS color +PASS mathbackground on the maction element is mapped to CSS background-color +PASS mathsize on the maction element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the maction element are not mapped to CSS +PASS dir on the menclose element is mapped to CSS direction +PASS mathcolor on the menclose element is mapped to CSS color +PASS mathbackground on the menclose element is mapped to CSS background-color +PASS mathsize on the menclose element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the menclose element are not mapped to CSS +PASS dir on the merror element is mapped to CSS direction +FAIL mathcolor on the merror element is mapped to CSS color assert_equals: no attribute expected "rgb(255, 0, 0)" but got "rgb(0, 0, 255)" +FAIL mathbackground on the merror element is mapped to CSS background-color assert_equals: no attribute expected "rgb(255, 255, 224)" but got "rgba(0, 0, 0, 0)" +PASS mathsize on the merror element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the merror element are not mapped to CSS +PASS dir on the mfrac element is mapped to CSS direction +PASS mathcolor on the mfrac element is mapped to CSS color +PASS mathbackground on the mfrac element is mapped to CSS background-color +PASS mathsize on the mfrac element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mfrac element are not mapped to CSS +PASS dir on the mi element is mapped to CSS direction +PASS mathcolor on the mi element is mapped to CSS color +PASS mathbackground on the mi element is mapped to CSS background-color +PASS mathsize on the mi element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mi element are not mapped to CSS +PASS dir on the mmultiscripts element is mapped to CSS direction +PASS mathcolor on the mmultiscripts element is mapped to CSS color +PASS mathbackground on the mmultiscripts element is mapped to CSS background-color +PASS mathsize on the mmultiscripts element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mmultiscripts element are not mapped to CSS +PASS dir on the mn element is mapped to CSS direction +PASS mathcolor on the mn element is mapped to CSS color +PASS mathbackground on the mn element is mapped to CSS background-color +PASS mathsize on the mn element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mn element are not mapped to CSS +PASS dir on the mo element is mapped to CSS direction +PASS mathcolor on the mo element is mapped to CSS color +PASS mathbackground on the mo element is mapped to CSS background-color +PASS mathsize on the mo element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mo element are not mapped to CSS +PASS dir on the mover element is mapped to CSS direction +PASS mathcolor on the mover element is mapped to CSS color +PASS mathbackground on the mover element is mapped to CSS background-color +PASS mathsize on the mover element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mover element are not mapped to CSS +PASS dir on the mpadded element is mapped to CSS direction +PASS mathcolor on the mpadded element is mapped to CSS color +PASS mathbackground on the mpadded element is mapped to CSS background-color +PASS mathsize on the mpadded element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mpadded element are not mapped to CSS +PASS dir on the mphantom element is mapped to CSS direction +PASS mathcolor on the mphantom element is mapped to CSS color +PASS mathbackground on the mphantom element is mapped to CSS background-color +PASS mathsize on the mphantom element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mphantom element are not mapped to CSS +PASS dir on the mprescripts element is mapped to CSS direction +PASS mathcolor on the mprescripts element is mapped to CSS color +PASS mathbackground on the mprescripts element is mapped to CSS background-color +PASS mathsize on the mprescripts element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mprescripts element are not mapped to CSS +PASS dir on the mroot element is mapped to CSS direction +PASS mathcolor on the mroot element is mapped to CSS color +PASS mathbackground on the mroot element is mapped to CSS background-color +PASS mathsize on the mroot element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mroot element are not mapped to CSS +PASS dir on the mrow element is mapped to CSS direction +PASS mathcolor on the mrow element is mapped to CSS color +PASS mathbackground on the mrow element is mapped to CSS background-color +PASS mathsize on the mrow element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mrow element are not mapped to CSS +PASS dir on the ms element is mapped to CSS direction +PASS mathcolor on the ms element is mapped to CSS color +PASS mathbackground on the ms element is mapped to CSS background-color +PASS mathsize on the ms element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the ms element are not mapped to CSS +PASS dir on the mspace element is mapped to CSS direction +PASS mathcolor on the mspace element is mapped to CSS color +PASS mathbackground on the mspace element is mapped to CSS background-color +PASS mathsize on the mspace element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mspace element are not mapped to CSS +PASS dir on the msqrt element is mapped to CSS direction +PASS mathcolor on the msqrt element is mapped to CSS color +PASS mathbackground on the msqrt element is mapped to CSS background-color +PASS mathsize on the msqrt element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the msqrt element are not mapped to CSS +PASS dir on the mstyle element is mapped to CSS direction +PASS mathcolor on the mstyle element is mapped to CSS color +PASS mathbackground on the mstyle element is mapped to CSS background-color +PASS mathsize on the mstyle element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mstyle element are not mapped to CSS +PASS dir on the msub element is mapped to CSS direction +PASS mathcolor on the msub element is mapped to CSS color +PASS mathbackground on the msub element is mapped to CSS background-color +PASS mathsize on the msub element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the msub element are not mapped to CSS +PASS dir on the msubsup element is mapped to CSS direction +PASS mathcolor on the msubsup element is mapped to CSS color +PASS mathbackground on the msubsup element is mapped to CSS background-color +PASS mathsize on the msubsup element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the msubsup element are not mapped to CSS +PASS dir on the msup element is mapped to CSS direction +PASS mathcolor on the msup element is mapped to CSS color +PASS mathbackground on the msup element is mapped to CSS background-color +PASS mathsize on the msup element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the msup element are not mapped to CSS +PASS dir on the mtable element is mapped to CSS direction +PASS mathcolor on the mtable element is mapped to CSS color +PASS mathbackground on the mtable element is mapped to CSS background-color +PASS mathsize on the mtable element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mtable element are not mapped to CSS +PASS dir on the mtd element is mapped to CSS direction +PASS mathcolor on the mtd element is mapped to CSS color +PASS mathbackground on the mtd element is mapped to CSS background-color +PASS mathsize on the mtd element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mtd element are not mapped to CSS +PASS dir on the mtext element is mapped to CSS direction +PASS mathcolor on the mtext element is mapped to CSS color +PASS mathbackground on the mtext element is mapped to CSS background-color +PASS mathsize on the mtext element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mtext element are not mapped to CSS +PASS dir on the mtr element is mapped to CSS direction +PASS mathcolor on the mtr element is mapped to CSS color +PASS mathbackground on the mtr element is mapped to CSS background-color +PASS mathsize on the mtr element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the mtr element are not mapped to CSS +PASS dir on the munder element is mapped to CSS direction +PASS mathcolor on the munder element is mapped to CSS color +PASS mathbackground on the munder element is mapped to CSS background-color +PASS mathsize on the munder element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the munder element are not mapped to CSS +PASS dir on the munderover element is mapped to CSS direction +PASS mathcolor on the munderover element is mapped to CSS color +PASS mathbackground on the munderover element is mapped to CSS background-color +PASS mathsize on the munderover element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the munderover element are not mapped to CSS +PASS dir on the none element is mapped to CSS direction +PASS mathcolor on the none element is mapped to CSS color +PASS mathbackground on the none element is mapped to CSS background-color +PASS mathsize on the none element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the none element are not mapped to CSS +PASS dir on the semantics element is mapped to CSS direction +PASS mathcolor on the semantics element is mapped to CSS color +PASS mathbackground on the semantics element is mapped to CSS background-color +PASS mathsize on the semantics element is mapped to CSS font-size +PASS deprecated MathML3 attributes on the semantics element are not mapped to CSS +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001.html index e7c6391e..3424e8c 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001.html
@@ -34,6 +34,10 @@ assert_equals(style.getPropertyValue("direction"), "rtl", "attribute specified"); element.setAttribute("dir", "RtL"); assert_equals(style.getPropertyValue("direction"), "rtl", "case insensitive"); + element.setAttribute("dir", "auto"); + assert_equals(style.getPropertyValue("direction"), "ltr", "auto"); + element.setAttribute("dir", "foo"); + assert_equals(style.getPropertyValue("direction"), "ltr", "random value"); }, `dir on the ${tag} element is mapped to CSS direction`) test(function() {
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt deleted file mode 100644 index 2103791b..0000000 --- a/third_party/blink/web_tests/external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL PaymentRequest setting allowpaymentrequest after document creation, before response assert_equals: expected "Exception" but got "Success" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https-expected.txt deleted file mode 100644 index 01dcfe66..0000000 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -PASS Accessing navigator.serviceWorker in normal iframe should not throw. -PASS Accessing navigator.serviceWorker in sandboxed iframe should throw. -PASS Accessing navigator.serviceWorker in sandboxed iframe with allow-same-origin flag should not throw. -FAIL Switching iframe sandbox attribute while loading the iframe assert_equals: expected "navigator.serviceWorker failed: SecurityError" but got "getRegistration() failed: InvalidStateError" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https.html index a58525f4..70be6ef9 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https.html +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https.html
@@ -8,10 +8,12 @@ var lastCallbackId = 0; var callbacks = {}; function postMessageAndWaitResult(frame) { - return new Promise(function(resolve) { + return new Promise(function(resolve, reject) { var id = ++lastCallbackId; callbacks[id] = resolve; frame.contentWindow.postMessage({id:id}, '*'); + const timeout = 1000; + step_timeout(() => reject("no msg back after " + timeout + "ms"), timeout); }); } @@ -105,10 +107,13 @@ // It's not clear whether navigation subsequently creates a new // Document, but I'm assuming it wouldn't. // https://html.spec.whatwg.org/multipage/embedded-content.html#attr-iframe-sandbox - assert_equals( - result, - 'navigator.serviceWorker failed: SecurityError'); - }); + assert_true( + false, + 'should NOT get message back from a sandboxed frame where scripts are not allowed to execute'); + }) + .catch(msg => { + assert_true(msg.startsWith('no msg back'), 'expecting error message "no msg back"'); + }); }, 'Switching iframe sandbox attribute while loading the iframe'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/tools/manifest/commands.json b/third_party/blink/web_tests/external/wpt/tools/manifest/commands.json index 074d248..769675e 100644 --- a/third_party/blink/web_tests/external/wpt/tools/manifest/commands.json +++ b/third_party/blink/web_tests/external/wpt/tools/manifest/commands.json
@@ -1,5 +1,23 @@ -{"manifest": - {"path": "update.py", "script": "run", "parser": "create_parser", "help": "Update the MANIFEST.json file", - "virtualenv": false}, - "manifest-download": - {"path": "download.py", "script": "run", "parser": "create_parser", "help": "Download recent pregenerated MANIFEST.json file", "virtualenv": false}} +{ + "manifest": { + "path": "update.py", + "script": "run", + "parser": "create_parser", + "help": "Update the MANIFEST.json file", + "virtualenv": false + }, + "manifest-download": { + "path": "download.py", + "script": "run", + "parser": "create_parser", + "help": "Download recent pregenerated MANIFEST.json file", + "virtualenv": false + }, + "test-paths": { + "path": "testpaths.py", + "script": "run", + "parser": "create_parser", + "help": "Print test paths given a set of test ids", + "virtualenv": false + } +}
diff --git a/third_party/blink/web_tests/external/wpt/tools/manifest/item.py b/third_party/blink/web_tests/external/wpt/tools/manifest/item.py index a387091..217f6cac2 100644 --- a/third_party/blink/web_tests/external/wpt/tools/manifest/item.py +++ b/third_party/blink/web_tests/external/wpt/tools/manifest/item.py
@@ -51,7 +51,7 @@ @abstractproperty def id(self): - # type: () -> Hashable + # type: () -> Text """The test's id (usually its url)""" pass
diff --git a/third_party/blink/web_tests/external/wpt/tools/manifest/manifest.py b/third_party/blink/web_tests/external/wpt/tools/manifest/manifest.py index 8aace771..6fb591b 100644 --- a/third_party/blink/web_tests/external/wpt/tools/manifest/manifest.py +++ b/third_party/blink/web_tests/external/wpt/tools/manifest/manifest.py
@@ -251,18 +251,18 @@ self.url_base = url_base # type: Text def __iter__(self): - # type: () -> Iterable[Tuple[str, Text, Set[ManifestItem]]] + # type: () -> Iterator[Tuple[str, Text, Set[ManifestItem]]] return self.itertypes() def itertypes(self, *types): - # type: (*str) -> Iterable[Tuple[str, Text, Set[ManifestItem]]] + # type: (*str) -> Iterator[Tuple[str, Text, Set[ManifestItem]]] for item_type in (types or sorted(self._data.keys())): for path in sorted(self._data[item_type]): tests = self._data[item_type][path] yield item_type, path, tests def iterpath(self, path): - # type: (Text) -> Iterable[ManifestItem] + # type: (Text) -> Iterator[ManifestItem] for type_tests in self._data.values(): i = type_tests.get(path, set()) assert i is not None @@ -270,7 +270,7 @@ yield test def iterdir(self, dir_name): - # type: (Text) -> Iterable[ManifestItem] + # type: (Text) -> Iterator[ManifestItem] if not dir_name.endswith(os.path.sep): dir_name = dir_name + os.path.sep for type_tests in self._data.values():
diff --git a/third_party/blink/web_tests/external/wpt/tools/manifest/testpaths.py b/third_party/blink/web_tests/external/wpt/tools/manifest/testpaths.py new file mode 100644 index 0000000..3c1f09d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/tools/manifest/testpaths.py
@@ -0,0 +1,92 @@ +import argparse +import json +import os +from collections import defaultdict + +from six import iteritems + +from .manifest import load_and_update, Manifest +from .log import get_logger + +MYPY = False +if MYPY: + # MYPY is set to True when run under Mypy. + from typing import Any + from typing import Dict + from typing import Iterable + from typing import List + from typing import Text + +wpt_root = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) + +logger = get_logger() + + +def abs_path(path): + # type: (str) -> str + return os.path.abspath(os.path.expanduser(path)) + + +def create_parser(): + # type: () -> argparse.ArgumentParser + parser = argparse.ArgumentParser() + parser.add_argument( + "-p", "--path", type=abs_path, help="Path to manifest file.") + parser.add_argument( + "--tests-root", type=abs_path, default=wpt_root, help="Path to root of tests.") + parser.add_argument( + "--no-update", dest="update", action="store_false", default=True, + help="Don't update manifest before continuing") + parser.add_argument( + "-r", "--rebuild", action="store_true", default=False, + help="Force a full rebuild of the manifest.") + parser.add_argument( + "--url-base", action="store", default="/", + help="Base url to use as the mount point for tests in this manifest.") + parser.add_argument( + "--cache-root", action="store", default=os.path.join(wpt_root, ".wptcache"), + help="Path in which to store any caches (default <tests_root>/.wptcache/)") + parser.add_argument( + "--json", action="store_true", default=False, + help="Output as JSON") + parser.add_argument( + "test_ids", action="store", nargs="+", + help="Test ids for which to get paths") + return parser + + +def get_path_id_map(manifest_file, test_ids): + # type: (Manifest, Iterable[Text]) -> Dict[Text, List[Text]] + test_ids = set(test_ids) + path_id_map = defaultdict(list) # type: Dict[Text, List[Text]] + + for item_type, path, tests in manifest_file: + for test in tests: + if test.id in test_ids: + path_id_map[path].append(test.id) + return path_id_map + + +def run(**kwargs): + # type: (**Any) -> None + tests_root = kwargs["tests_root"] + assert tests_root is not None + path = kwargs["path"] + if path is None: + path = os.path.join(kwargs["tests_root"], "MANIFEST.json") + + manifest_file = load_and_update(tests_root, + path, + kwargs["url_base"], + update=kwargs["update"], + rebuild=kwargs["rebuild"], + cache_root=kwargs["cache_root"]) + + path_id_map = get_path_id_map(manifest_file, kwargs["test_ids"]) + if kwargs["json"]: + print(json.dumps(path_id_map)) + else: + for path, test_ids in sorted(iteritems(path_id_map)): + print(path) + for test_id in sorted(test_ids): + print(" " + test_id)
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt index f12ce9d..b079e4e 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt +++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 563 tests; 544 PASS, 19 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 560 tests; 541 PASS, 19 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Setup PASS align-content (type: discrete) has testAccumulation function PASS align-content: "flex-end" onto "flex-start" @@ -176,9 +176,6 @@ PASS column-width (type: discrete) has testAccumulation function PASS column-width: "1px" onto "auto" PASS column-width: "auto" onto "1px" -PASS content (type: discrete) has testAccumulation function -PASS content: ""b"" onto ""a"" -PASS content: ""a"" onto ""b"" PASS counter-increment (type: discrete) has testAccumulation function PASS counter-increment: "ident-2 2" onto "ident-1 1" PASS counter-increment: "ident-1 1" onto "ident-2 2"
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt index 5cd14a5..21a7dd2f 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt +++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 559 tests; 541 PASS, 18 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 556 tests; 538 PASS, 18 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Setup PASS align-content (type: discrete) has testAddition function PASS align-content: "flex-end" onto "flex-start" @@ -176,9 +176,6 @@ PASS column-width (type: discrete) has testAddition function PASS column-width: "1px" onto "auto" PASS column-width: "auto" onto "1px" -PASS content (type: discrete) has testAddition function -PASS content: ""b"" onto ""a"" -PASS content: ""a"" onto ""b"" PASS counter-increment (type: discrete) has testAddition function PASS counter-increment: "ident-2 2" onto "ident-1 1" PASS counter-increment: "ident-1 1" onto "ident-2 2"
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt index 48cfbb4..93ad9fe 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt +++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 690 tests; 657 PASS, 33 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 686 tests; 653 PASS, 33 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Setup PASS align-content (type: discrete) has testInterpolation function PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing @@ -212,10 +212,6 @@ PASS column-width uses discrete animation when animating between "auto" and "1px" with linear easing PASS column-width uses discrete animation when animating between "auto" and "1px" with effect easing PASS column-width uses discrete animation when animating between "auto" and "1px" with keyframe easing -PASS content (type: discrete) has testInterpolation function -PASS content uses discrete animation when animating between ""a"" and ""b"" with linear easing -PASS content uses discrete animation when animating between ""a"" and ""b"" with effect easing -PASS content uses discrete animation when animating between ""a"" and ""b"" with keyframe easing PASS counter-increment (type: discrete) has testInterpolation function PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with linear easing PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with effect easing
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-list.js b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-list.js index 11bbf1a..2f91ebc 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-list.js +++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-list.js
@@ -410,15 +410,6 @@ { type: 'discrete', options: [ [ 'auto', '1px' ] ] } ] }, - 'content': { - // https://drafts.csswg.org/css-content-3/#propdef-content - types: [ - { type: 'discrete', options: [ [ '"a"', '"b"' ] ] } - ], - setup: t => { - return getPseudoElement(t, 'before'); - } - }, 'counter-increment': { // https://drafts.csswg.org/css-lists-3/#propdef-counter-increment types: [ @@ -1432,13 +1423,11 @@ }; function testAnimationSamples(animation, idlName, testSamples) { - const type = animation.effect.target.type; - const target = animation.effect.target.constructor.name === 'CSSPseudoElement' - ? animation.effect.target.element - : animation.effect.target; + const pseudoType = animation.effect.pseudoElement; + const target = animation.effect.target; for (const testSample of testSamples) { animation.currentTime = testSample.time; - assert_equals(getComputedStyle(target, type)[idlName], + assert_equals(getComputedStyle(target, pseudoType)[idlName], testSample.expected, `The value should be ${testSample.expected}` + ` at ${testSample.time}ms`); @@ -1453,10 +1442,8 @@ // don't specify an order for serializing computed values. // This test is for such the property. function testAnimationSamplesWithAnyOrder(animation, idlName, testSamples) { - const type = animation.effect.target.type; - const target = animation.effect.target.constructor.name === 'CSSPseudoElement' - ? animation.effect.target.element - : animation.effect.target; + const type = animation.effect.pseudoElement; + const target = animation.effect.target; for (const testSample of testSamples) { animation.currentTime = testSample.time;
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animatable/animate-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animatable/animate-expected.txt index a694484..081ee31 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animatable/animate-expected.txt +++ b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animatable/animate-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 138 tests; 136 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 140 tests; 137 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Element.animate() creates an Animation object PASS Element.animate() creates an Animation object in the relevant realm of the target element PASS Element.animate() creates an Animation object with a KeyframeEffect @@ -134,9 +134,11 @@ PASS Element.animate() correctly sets the Animation's timeline when triggered on an element in a different document PASS Element.animate() calls play on the Animation PASS Element.animate() does NOT trigger a style change event -PASS CSSPseudoElement.animate() creates an Animation object -FAIL CSSPseudoElement.animate() creates an Animation object for ::marker assert_true: expected true got false -PASS CSSPseudoElement.animate() creates an Animation object targeting to the correct CSSPseudoElement object -FAIL CSSPseudoElement.animate() creates an Animation object targeting to the correct CSSPseudoElement object for ::marker assert_true: expected true got false +PASS animate() with pseudoElement parameter creates an Animation object +PASS animate() with pseudoElement parameter creates an Animation object for ::marker +PASS animate() with pseudoElement parameter creates an Animation object for ::first-line +FAIL animate() with pseudoElement an Animation object targeting to the correct pseudo-element assert_equals: The returned Animation targets to the correct selector expected (string) "::before" but got (undefined) undefined +FAIL animate() with pseudoElement an Animation object targeting to the correct pseudo-element for ::marker assert_equals: The returned Animation targets to the correct selector expected (string) "::marker" but got (undefined) undefined +FAIL animate() with pseudoElement an Animation object targeting to the correct pseudo-element for ::first-line assert_equals: The returned Animation targets to the correct selector expected (string) "::first-line" but got (undefined) undefined Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animatable/animate.html b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animatable/animate.html index fcf753b..2d09cdf 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animatable/animate.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animatable/animate.html
@@ -10,6 +10,11 @@ <script src="../../resources/keyframe-tests.js"></script> <script src="../../resources/timing-utils.js"></script> <script src="../../resources/timing-tests.js"></script> +<style> +.pseudo::before {content: '';} +.pseudo::after {content: '';} +.pseudo::marker {content: '';} +</style> <body> <div id="log"></div> <iframe width="10" height="10" id="iframe"></iframe> @@ -235,34 +240,59 @@ assert_false(gotTransition, 'A transition should NOT have been triggered'); }, 'Element.animate() does NOT trigger a style change event'); -// Tests on CSSPseudoElement +// Tests on pseudo-elements test(t => { - const pseudoTarget = getPseudoElement(t, 'before'); - const anim = pseudoTarget.animate(null); + const div = createDiv(t); + div.classList.add('pseudo'); + const anim = div.animate(null, {pseudoElement: '::before'}); assert_class_string(anim, 'Animation', 'The returned object is an Animation'); -}, 'CSSPseudoElement.animate() creates an Animation object'); +}, 'animate() with pseudoElement parameter creates an Animation object'); test(t => { - const pseudoTarget = getPseudoElement(t, 'marker'); - const anim = pseudoTarget.animate(null); + const div = createDiv(t); + div.classList.add('pseudo'); + div.style.display = 'list-item'; + const anim = div.animate(null, {pseudoElement: '::marker'}); assert_class_string(anim, 'Animation', 'The returned object is an Animation for ::marker'); -}, 'CSSPseudoElement.animate() creates an Animation object for ::marker'); +}, 'animate() with pseudoElement parameter creates an Animation object for ::marker'); test(t => { - const pseudoTarget = getPseudoElement(t, 'before'); - const anim = pseudoTarget.animate(null); - assert_equals(anim.effect.target, pseudoTarget, - 'The returned Animation targets to the correct object'); -}, 'CSSPseudoElement.animate() creates an Animation object targeting ' + - 'to the correct CSSPseudoElement object'); + const div = createDiv(t); + div.classList.add('pseudo'); + div.textContent = 'foo'; + const anim = div.animate(null, {pseudoElement: '::first-line'}); + assert_class_string(anim, 'Animation', 'The returned object is an Animation for ::first-line'); +}, 'animate() with pseudoElement parameter creates an Animation object for ::first-line'); test(t => { - const pseudoTarget = getPseudoElement(t, 'marker'); - const anim = pseudoTarget.animate(null); - assert_equals(anim.effect.target, pseudoTarget, - 'The returned Animation targets to the correct object for ::marker'); -}, 'CSSPseudoElement.animate() creates an Animation object targeting ' + - 'to the correct CSSPseudoElement object for ::marker'); + const div = createDiv(t); + div.classList.add('pseudo'); + const anim = div.animate(null, {pseudoElement: '::before'}); + assert_equals(anim.effect.pseudoElement, '::before', + 'The returned Animation targets to the correct selector'); +}, 'animate() with pseudoElement an Animation object targeting ' + + 'to the correct pseudo-element'); + +test(t => { + const div = createDiv(t); + div.classList.add('pseudo'); + div.style.display = 'list-item'; + const anim = div.animate(null, {pseudoElement: '::marker'}); + assert_equals(anim.effect.pseudoElement, '::marker', + 'The returned Animation targets to the correct selector'); +}, 'animate() with pseudoElement an Animation object targeting ' + + 'to the correct pseudo-element for ::marker'); + +test(t => { + const div = createDiv(t); + div.classList.add('pseudo'); + div.textContent = 'foo'; + const anim = div.animate(null, {pseudoElement: '::first-line'}); + assert_equals(anim.effect.pseudoElement, '::first-line', + 'The returned Animation targets to the correct selector'); +}, 'animate() with pseudoElement an Animation object targeting ' + + 'to the correct pseudo-element for ::first-line'); + </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/commitStyles-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/commitStyles-expected.txt index 4daa0bc..1281fd0 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/commitStyles-expected.txt +++ b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/commitStyles-expected.txt
@@ -28,6 +28,8 @@ FAIL Throws if the target effect is disconnected assert_throws: function "() => { animation.commitStyles(); }" threw object "TypeError: animation.commitStyles is not a function" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11 -FAIL Checks the pseudo element condition before the not rendered condition Cannot read property 'remove' of undefined +FAIL Checks the pseudo element condition before the not rendered condition assert_throws: function "() => { + animation.commitStyles(); + }" threw object "TypeError: animation.commitStyles is not a function" that is not a DOMException NoModificationAllowedError: property "code" is equal to undefined, expected 7 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/commitStyles.html b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/commitStyles.html index 9005db9e..d3a95e0 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/commitStyles.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/commitStyles.html
@@ -5,6 +5,11 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="../../testcommon.js"></script> +<style> +.pseudo::before {content: '';} +.pseudo::after {content: '';} +.pseudo::marker {content: '';} +</style> <body> <div id="log"></div> <script> @@ -263,10 +268,12 @@ }, 'Does NOT trigger mutation observers when the change to style is redundant'); test(t => { - const pseudo = getPseudoElement(t, 'before'); - const animation = pseudo.animate( + + const div = createDiv(t); + div.classList.add('pseudo'); + const animation = div.animate( { opacity: 0 }, - { duration: 1, fill: 'forwards' } + { duration: 1, fill: 'forwards', pseudoElement: '::before' } ); assert_throws('NoModificationAllowedError', () => { @@ -372,13 +379,14 @@ }, 'Throws if the target effect is disconnected'); test(t => { - const pseudo = getPseudoElement(t, 'before'); - const animation = pseudo.animate( + const div = createDiv(t); + div.classList.add('pseudo'); + const animation = div.animate( { opacity: 0 }, - { duration: 1, fill: 'forwards' } + { duration: 1, fill: 'forwards', pseudoElement: '::before' } ); - pseudo.element.remove(); + div.remove(); assert_throws('NoModificationAllowedError', () => { animation.commitStyles();
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js b/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js index 82b7053..f89cbbaf 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js +++ b/third_party/blink/web_tests/external/wpt/web-animations/testcommon.js
@@ -87,23 +87,6 @@ }); } -// Create a pseudo element -function getPseudoElement(test, type) { - createStyle(test, { '@keyframes anim': '', - [`.pseudo::${type}`]: 'animation: anim 10s; ' + - 'content: \'\';' }); - const div = createDiv(test); - if (type == 'marker') { - div.style.display = 'list-item'; - } - div.classList.add('pseudo'); - const anims = document.getAnimations(); - assert_true(anims.length >= 1); - const anim = anims[anims.length - 1]; - anim.cancel(); - return anim.effect.target; -} - // Cubic bezier with control points (0, 0), (x1, y1), (x2, y2), and (1, 1). function cubicBezier(x1, y1, x2, y2) { const xForT = t => {
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html index 32f2eb9..a2b2827 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html
@@ -393,8 +393,8 @@ pc2.oniceconnectionstatechange = t.unreached_func(); pc2.close(); - await Promise.resolve(); assert_true(pc2.iceConnectionState === 'closed'); + await new Promise(r => t.step_timeout(r, 100)); }, 'Closing a PeerConnection should not fire iceconnectionstatechange event'); </script>
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/calendar-picker-mouse-operations-expected.txt b/third_party/blink/web_tests/fast/forms/calendar-picker/calendar-picker-mouse-operations-expected.txt index 24e15349..2571542 100644 --- a/third_party/blink/web_tests/fast/forms/calendar-picker/calendar-picker-mouse-operations-expected.txt +++ b/third_party/blink/web_tests/fast/forms/calendar-picker/calendar-picker-mouse-operations-expected.txt
@@ -39,7 +39,7 @@ PASS checkYearListViewScrollOffset() < 0 is true Check that clicking an year list cell opens it. PASS checkYearListViewScrollOffset() > 0 is true -PASS highlightedMonthButton() is "1999-10" +PASS highlightedMonthButton() is "1999-01" Check that clicking the month popup sets the month. PASS popupWindow.global.picker.monthPopupView.isVisible is false PASS currentMonth() is "1999-06"
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/calendar-picker-mouse-operations.html b/third_party/blink/web_tests/fast/forms/calendar-picker/calendar-picker-mouse-operations.html index 83e25498..54b21a8 100644 --- a/third_party/blink/web_tests/fast/forms/calendar-picker/calendar-picker-mouse-operations.html +++ b/third_party/blink/web_tests/fast/forms/calendar-picker/calendar-picker-mouse-operations.html
@@ -83,7 +83,7 @@ eventSender.mouseScrollBy(0, 10); shouldBeTrue('checkYearListViewScrollOffset() > 0'); clickYearListCell(1999); - shouldBeEqualToString('highlightedMonthButton()', '1999-10'); + shouldBeEqualToString('highlightedMonthButton()', '1999-01'); debug('Check that clicking the month popup sets the month.');
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-mouse-operations-expected.txt b/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-mouse-operations-expected.txt index 74295eb..34c84d4b 100644 --- a/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-mouse-operations-expected.txt +++ b/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-mouse-operations-expected.txt
@@ -55,7 +55,7 @@ PASS checkYearListViewScrollOffset() < 0 is true Check that clicking an year list cell opens it. PASS checkYearListViewScrollOffset() > 0 is true -PASS highlightedMonthButton() is "1999-10" +PASS highlightedMonthButton() is "1999-01" Check that clicking the month popup sets the month. PASS popupWindow.global.picker.monthPopupView.isVisible is false PASS currentMonth() is "1999-06"
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-mouse-operations.html b/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-mouse-operations.html index f482a33..410b117 100644 --- a/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-mouse-operations.html +++ b/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-mouse-operations.html
@@ -107,7 +107,7 @@ eventSender.mouseScrollBy(0, 10); shouldBeTrue('checkYearListViewScrollOffset() > 0'); clickYearListCell(1999); - shouldBeEqualToString('highlightedMonthButton()', '1999-10'); + shouldBeEqualToString('highlightedMonthButton()', '1999-01'); debug('Check that clicking the month popup sets the month.');
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-mouse-operations-expected.txt b/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-mouse-operations-expected.txt index 5b6d0e7a..e4aa4b39 100644 --- a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-mouse-operations-expected.txt +++ b/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-mouse-operations-expected.txt
@@ -60,7 +60,7 @@ PASS checkYearListViewScrollOffset() < 0 is true Check that clicking an year list cell opens it. PASS checkYearListViewScrollOffset() > 0 is true -PASS highlightedMonthButton() is "1999-10" +PASS highlightedMonthButton() is "1999-01" Check that clicking the month popup sets the month. PASS popupWindow.global.picker.monthPopupView.isVisible is false PASS currentMonth() is "1999-06"
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-mouse-operations.html b/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-mouse-operations.html index 4328b1d..464b133 100644 --- a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-mouse-operations.html +++ b/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-mouse-operations.html
@@ -115,7 +115,7 @@ eventSender.mouseScrollBy(0, 10); shouldBeTrue('checkYearListViewScrollOffset() > 0'); clickYearListCell(1999); - shouldBeEqualToString('highlightedMonthButton()', '1999-10'); + shouldBeEqualToString('highlightedMonthButton()', '1999-01'); debug('Check that clicking the month popup sets the month.');
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt deleted file mode 100644 index c960d0d..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt +++ /dev/null
@@ -1,13 +0,0 @@ -This is a testharness.js-based test. -PASS page-created Error (worker) -PASS page-created Error (cross-site iframe) -PASS page-created DOMException (worker) -PASS page-created DOMException (cross-site iframe) -PASS JS-engine-created TypeError (worker) -PASS JS-engine-created TypeError (cross-site iframe) -PASS web API-created TypeError (worker) -PASS web API-created TypeError (cross-site iframe) -FAIL web API-created DOMException (worker) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:41:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1917:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:40:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined -FAIL web API-created DOMException (cross-site iframe) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:60:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1917:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:57:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-request/payment-is-showing.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-request/payment-is-showing.https-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-request/payment-is-showing.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt deleted file mode 100644 index 42e1de3..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/speech-api/historical-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/speech-api/historical-expected.txt deleted file mode 100644 index 07d8219..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/speech-api/historical-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -This is a testharness.js-based test. -PASS SpeechRecognitionError interface should not exist -FAIL webkitSpeechGrammar interface should not exist assert_false: expected false got true -FAIL webkitSpeechGrammarList interface should not exist assert_false: expected false got true -FAIL webkitSpeechRecognition interface should not exist assert_false: expected false got true -FAIL webkitSpeechRecognitionError interface should not exist assert_false: expected false got true -FAIL webkitSpeechRecognitionEvent interface should not exist assert_false: expected false got true -PASS SpeechRecognition's serviceURI attribute should not exist -PASS SpeechRecognitionEvent's interpretation attribute should not exist -PASS SpeechRecognitionEvent's emma attribute should not exist -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-highlighted-month-after-year-change.html b/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-highlighted-month-after-year-change.html new file mode 100644 index 0000000..07a9db2 --- /dev/null +++ b/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-highlighted-month-after-year-change.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<script> +testRunner.waitUntilDone(); +</script> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../../fast/forms/resources/common.js"></script> +<script src="../../../fast/forms/resources/picker-common.js"></script> +<script src="../../../fast/forms/calendar-picker/resources/calendar-picker-common.js"></script> +<input type=date id=date value="2017-07-31"> +<script> + +let t = async_test('Test highlighted month in year view.'); + +function test1() { + clickMonthPopupButton(); + clickYearListCell(2018); + assert_equals(highlightedMonthButton(), "2018-01"); +} + +t.step(() => { + openPicker(document.getElementById('date'), t.step_func_done(test1)); +}); +</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index e7483eaf..bb3dca5 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -11074,19 +11074,12 @@ attribute @@toStringTag getter hitMatrix method constructor -interface XRHitTestOptions - attribute @@toStringTag - getter offsetRay - getter space - method constructor interface XRHitTestResult attribute @@toStringTag - getter hitTestOptions method constructor method getPose interface XRHitTestSource attribute @@toStringTag - getter hitTestOptions method constructor interface XRInputSource attribute @@toStringTag
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/cts.html b/third_party/blink/web_tests/wpt_internal/webgpu/cts.html index c67c0c8..9c78e72a 100644 --- a/third_party/blink/web_tests/wpt_internal/webgpu/cts.html +++ b/third_party/blink/web_tests/wpt_internal/webgpu/cts.html
@@ -19,6 +19,17 @@ width: 100%; height: 15em; } + +/* Test Name column */ +#results > tbody > tr > td:nth-child(2) { + word-break: break-word; +} + +/* Message column */ +#results > tbody > tr > td:nth-child(3) { + white-space: pre-wrap; + word-break: break-word; +} </style> <textarea id=results></textarea> @@ -93,6 +104,8 @@ <meta name=variant content='?q=cts:validation/createPipelineLayout:'> +<meta name=variant content='?q=cts:validation/createRenderPipeline:'> + <meta name=variant content='?q=cts:validation/createTexture:validation_of_sampleCount={"sampleCount":0}'> <meta name=variant content='?q=cts:validation/createTexture:validation_of_sampleCount={"sampleCount":1}'> <meta name=variant content='?q=cts:validation/createTexture:validation_of_sampleCount={"sampleCount":2}'> @@ -215,7 +228,9 @@ <meta name=variant content='?q=cts:validation/setBlendColor:'> <meta name=variant content='?q=cts:validation/setScissorRect:'> <meta name=variant content='?q=cts:validation/setStencilReference:'> +<meta name=variant content='?q=cts:validation/setVertexBuffer:'> <meta name=variant content='?q=cts:validation/setViewport:'> +<meta name=variant content='?q=cts:validation/vertex_state:'> <!-- Workers --> @@ -288,6 +303,8 @@ <meta name=variant content='?worker=1&q=cts:validation/createPipelineLayout:'> +<meta name=variant content='?worker=1&q=cts:validation/createRenderPipeline:'> + <meta name=variant content='?worker=1&q=cts:validation/createTexture:validation_of_sampleCount={"sampleCount":0}'> <meta name=variant content='?worker=1&q=cts:validation/createTexture:validation_of_sampleCount={"sampleCount":1}'> <meta name=variant content='?worker=1&q=cts:validation/createTexture:validation_of_sampleCount={"sampleCount":2}'> @@ -410,4 +427,6 @@ <meta name=variant content='?worker=1&q=cts:validation/setBlendColor:'> <meta name=variant content='?worker=1&q=cts:validation/setScissorRect:'> <meta name=variant content='?worker=1&q=cts:validation/setStencilReference:'> +<meta name=variant content='?worker=1&q=cts:validation/setVertexBuffer:'> <meta name=variant content='?worker=1&q=cts:validation/setViewport:'> +<meta name=variant content='?worker=1&q=cts:validation/vertex_state:'>
diff --git a/tools/android/roll/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy b/tools/android/roll/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy index 8ae5c28..e92c4e6 100644 --- a/tools/android/roll/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy +++ b/tools/android/roll/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
@@ -121,7 +121,12 @@ new File("${absoluteDepDir}/LICENSE").write( new File("${normalisedRepoPath}/${dependency.licensePath}").text) } else if (!dependency.licenseUrl?.trim()?.isEmpty()) { - downloadFile(dependency.licenseUrl, new File("${absoluteDepDir}/LICENSE")) + File destFile = new File("${absoluteDepDir}/LICENSE") + downloadFile(dependency.id, dependency.licenseUrl, destFile) + if (destFile.text.contains("<html")) { + throw new RuntimeException("Found HTML in LICENSE file. Please add an " + + "override to ChromiumDepGraph.groovy for ${dependency.name}.") + } } } } @@ -478,9 +483,37 @@ getLogger().warn(jsonDump(obj)) } - static void downloadFile(String sourceUrl, File destinationFile) { + static HttpURLConnection connectAndFollowRedirects(String id, String sourceUrl) { + URL urlObj = new URL(sourceUrl) + HttpURLConnection connection + for (int i = 0; i < 10; ++i) { + // Several deps use this URL for their license, but it just points to license + // *template*. Generally the actual license can be found in the source code. + if (sourceUrl.contains("://opensource.org/licenses")) { + throw new RuntimeException("Found templated license URL for dependency " + + id + ": " + sourceUrl + + ". You will need to edit FALLBACK_PROPERTIES for this dep.") + } + connection = urlObj.openConnection() + switch (connection.getResponseCode()) { + case HttpURLConnection.HTTP_MOVED_PERM: + case HttpURLConnection.HTTP_MOVED_TEMP: + String location = connection.getHeaderField("Location"); + urlObj = new URL(urlObj, location); + continue + case HttpURLConnection.HTTP_OK: + return connection + default: + throw new RuntimeException( + "Url had statusCode=" + connection.getResponseCode() + ": " + sourceUrl) + } + } + throw new RuntimeException("Url in redirect loop: " + sourceUrl) + } + + static void downloadFile(String id, String sourceUrl, File destinationFile) { destinationFile.withOutputStream { out -> - out << new URL(sourceUrl).openStream() + out << connectAndFollowRedirects(id, sourceUrl).getInputStream() } }
diff --git a/tools/binary_size/libsupersize/caspian/BUILD.gn b/tools/binary_size/libsupersize/caspian/BUILD.gn index e31449f8..f889004b 100644 --- a/tools/binary_size/libsupersize/caspian/BUILD.gn +++ b/tools/binary_size/libsupersize/caspian/BUILD.gn
@@ -72,7 +72,7 @@ "-s", "ALLOW_MEMORY_GROWTH=1", "-s", - "EXPORTED_FUNCTIONS=['_LoadSizeFile','_BuildTree','_Open','_malloc','_free']", + "EXPORTED_FUNCTIONS=['_LoadSizeFile','_LoadBeforeSizeFile','_BuildTree','_Open','_malloc','_free']", "-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap','UTF8ToString']", ]
diff --git a/tools/binary_size/libsupersize/caspian/caspian_web.cc b/tools/binary_size/libsupersize/caspian/caspian_web.cc index fef68f5f..f7c570c 100644 --- a/tools/binary_size/libsupersize/caspian/caspian_web.cc +++ b/tools/binary_size/libsupersize/caspian/caspian_web.cc
@@ -21,7 +21,9 @@ namespace caspian { namespace { -SizeInfo info; +std::unique_ptr<SizeInfo> info; +std::unique_ptr<SizeInfo> before_info; +std::unique_ptr<DiffSizeInfo> diff_info; std::unique_ptr<TreeBuilder> builder; std::unique_ptr<Json::StreamWriter> writer; @@ -38,7 +40,15 @@ extern "C" { void LoadSizeFile(const char* compressed, size_t size) { - ParseSizeInfo(compressed, size, &info); + diff_info.reset(nullptr); + info = std::make_unique<SizeInfo>(); + ParseSizeInfo(compressed, size, info.get()); +} + +void LoadBeforeSizeFile(const char* compressed, size_t size) { + diff_info.reset(nullptr); + before_info = std::make_unique<SizeInfo>(); + ParseSizeInfo(compressed, size, before_info.get()); } void BuildTree(bool group_by_component, @@ -49,14 +59,22 @@ int match_flag) { std::vector<std::function<bool(const Symbol&)>> filters; + const bool diff_mode = info && before_info; + if (minimum_size_bytes > 0) { - filters.push_back([minimum_size_bytes](const Symbol& sym) -> bool { - return sym.pss() >= minimum_size_bytes; - }); + if (!diff_mode) { + filters.push_back([minimum_size_bytes](const Symbol& sym) -> bool { + return sym.pss >= minimum_size_bytes; + }); + } else { + filters.push_back([minimum_size_bytes](const Symbol& sym) -> bool { + return abs(sym.pss) >= minimum_size_bytes; + }); + } } - // It's currently not useful to filter on more than one flag, so |match_flag| - // can be assumed to be a power of two. + // It's currently not useful to filter on more than one flag, so + // |match_flag| can be assumed to be a power of two. if (match_flag) { std::cout << "Filtering on flag matching " << match_flag << std::endl; filters.push_back([match_flag](const Symbol& sym) -> bool { @@ -71,8 +89,7 @@ include_sections_map[static_cast<uint8_t>(*c)] = true; } filters.push_back([&include_sections_map](const Symbol& sym) -> bool { - return include_sections_map[static_cast<uint8_t>( - info.ShortSectionName(sym.section_name))]; + return include_sections_map[static_cast<uint8_t>(sym.sectionId)]; }); } @@ -98,7 +115,18 @@ } } - builder.reset(new TreeBuilder(&info, group_by_component, filters)); + // BuildTree() is called every time a new filter is applied in the HTML + // viewer, but if we already have a DiffSizeInfo we can skip regenerating it + // and let the TreeBuilder filter the symbols we care about. + if (diff_mode && !diff_info) { + diff_info.reset(new DiffSizeInfo(before_info.get(), info.get())); + } + + BaseSizeInfo* rendered_info = info.get(); + if (diff_mode) { + rendered_info = diff_info.get(); + } + builder.reset(new TreeBuilder(rendered_info, group_by_component, filters)); builder->Build(); }
diff --git a/tools/binary_size/libsupersize/caspian/cli.cc b/tools/binary_size/libsupersize/caspian/cli.cc index b07f9cd..b9c9761 100644 --- a/tools/binary_size/libsupersize/caspian/cli.cc +++ b/tools/binary_size/libsupersize/caspian/cli.cc
@@ -14,20 +14,30 @@ #include "tools/binary_size/libsupersize/caspian/file_format.h" #include "tools/binary_size/libsupersize/caspian/model.h" -int main(int argc, char* argv[]) { - if (argc < 2) { - std::cerr << "Usage: cli (path to .size file)" << std::endl; - exit(1); - } - std::ifstream ifs(argv[1], std::ifstream::in); +void ParseSizeInfoFromFile(const char* filename, caspian::SizeInfo* info) { + std::ifstream ifs(filename, std::ifstream::in); if (!ifs.good()) { - std::cerr << "Unable to open file: " << argv[1] << std::endl; + std::cerr << "Unable to open file: " << filename << std::endl; exit(1); } std::string compressed((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); + caspian::ParseSizeInfo(compressed.data(), compressed.size(), info); +} + +void Diff(const char* before_filename, const char* after_filename) { + caspian::SizeInfo before; + ParseSizeInfoFromFile(before_filename, &before); + + caspian::SizeInfo after; + ParseSizeInfoFromFile(after_filename, &after); + + caspian::DiffSizeInfo diff(&before, &after); +} + +void Validate(const char* filename) { caspian::SizeInfo info; - caspian::ParseSizeInfo(compressed.data(), compressed.size(), &info); + ParseSizeInfoFromFile(filename, &info); size_t max_aliases = 0; for (auto& s : info.raw_symbols) { @@ -44,5 +54,23 @@ } } std::cout << "Largest number of aliases: " << max_aliases << std::endl; +} + +int main(int argc, char* argv[]) { + if (argc < 2) { + std::cerr << "Must have exactly one of:" << std::endl; + std::cerr << " validate, diff" << std::endl; + std::cerr << "Usage: " << std::endl; + std::cerr << " cli validate <size file>" << std::endl; + std::cerr << " cli diff <before_file> <after_file>" << std::endl; + exit(1); + } + if (std::string_view(argv[1]) == "diff") { + Diff(argv[2], argv[3]); + } else if (std::string_view(argv[1]) == "validate") { + Validate(argv[1]); + } else { + exit(1); + } return 0; }
diff --git a/tools/binary_size/libsupersize/caspian/file_format.cc b/tools/binary_size/libsupersize/caspian/file_format.cc index d11a192..40e7669 100644 --- a/tools/binary_size/libsupersize/caspian/file_format.cc +++ b/tools/binary_size/libsupersize/caspian/file_format.cc
@@ -15,6 +15,7 @@ #include <iostream> #include <memory> #include <numeric> +#include <set> #include <sstream> #include <string> #include <vector> @@ -155,6 +156,56 @@ namespace caspian { +void CalculatePadding(std::vector<Symbol>* raw_symbols) { + std::set<const char*> seen_sections; + for (size_t i = 1; i < raw_symbols->size(); i++) { + const Symbol& prev_symbol = (*raw_symbols)[i - 1]; + Symbol& symbol = (*raw_symbols)[i]; + + if (symbol.IsOverhead()) { + symbol.padding = symbol.size; + } + if (prev_symbol.section_name != symbol.section_name) { + if (seen_sections.count(symbol.section_name)) { + std::cerr << "Input symbols must be sorted by section, then address: " + << prev_symbol << ", " << symbol << std::endl; + exit(1); + } + seen_sections.insert(symbol.section_name); + continue; + } + + if (symbol.address <= 0 || prev_symbol.address <= 0 || !symbol.IsNative() || + !prev_symbol.IsNative()) { + continue; + } + + if (symbol.address == prev_symbol.address) { + if (symbol.aliases && symbol.aliases == prev_symbol.aliases) { + symbol.padding = prev_symbol.padding; + symbol.size = prev_symbol.size; + continue; + } + if (prev_symbol.SizeWithoutPadding() != 0) { + // Padding-only symbols happen for ** symbol gaps. + std::cerr << "Found duplicate symbols: " << prev_symbol << ", " + << symbol << std::endl; + exit(1); + } + } + + int32_t padding = symbol.address - prev_symbol.EndAddress(); + symbol.padding = padding; + symbol.size += padding; + if (symbol.size < 0) { + std::cerr << "Symbol has negative size (likely not sorted properly):" + << symbol << std::endl; + std::cerr << "prev symbol: " << prev_symbol << std::endl; + exit(1); + } + } +} + void ParseSizeInfo(const char* gzipped, unsigned long len, ::caspian::SizeInfo* info) { @@ -257,6 +308,8 @@ // Construct raw symbols for (int section_idx = 0; section_idx < n_sections; section_idx++) { const char* cur_section_name = info->section_names[section_idx]; + caspian::SectionId cur_section_id = + info->ShortSectionName(cur_section_name); const int cur_section_count = section_counts[section_idx]; const std::vector<int64_t>& cur_addresses = addresses[section_idx]; const std::vector<int32_t>& cur_sizes = sizes[section_idx]; @@ -295,9 +348,10 @@ } } } - new_sym.section_name = cur_section_name; + new_sym.sectionId = cur_section_id; new_sym.address = cur_addresses[i]; new_sym.size = cur_sizes[i]; + new_sym.section_name = cur_section_name; new_sym.object_path = info->object_paths[cur_path_indices[i]]; new_sym.source_path = info->source_paths[cur_path_indices[i]]; if (has_components) { @@ -320,6 +374,13 @@ } } + CalculatePadding(&info->raw_symbols); + + for (caspian::Symbol& sym : info->raw_symbols) { + size_t alias_count = sym.aliases ? sym.aliases->size() : 1; + sym.pss = static_cast<float>(sym.size) / alias_count; + } + // If there are unparsed non-empty lines, something's gone wrong. CheckNoNonEmptyLinesRemain(rest);
diff --git a/tools/binary_size/libsupersize/caspian/model.cc b/tools/binary_size/libsupersize/caspian/model.cc index 19f390c..fe654c7 100644 --- a/tools/binary_size/libsupersize/caspian/model.cc +++ b/tools/binary_size/libsupersize/caspian/model.cc
@@ -5,15 +5,82 @@ #include "tools/binary_size/libsupersize/caspian/model.h" #include <algorithm> +#include <functional> #include <iostream> +#include <list> #include <string> +#include <unordered_map> #include "tools/binary_size/libsupersize/caspian/file_format.h" +namespace { +struct SymbolMatchIndex { + SymbolMatchIndex() {} + SymbolMatchIndex(caspian::SectionId id, + std::string_view name, + std::string_view path, + int size_without_padding) + : nonempty(true), + id(id), + name(name), + path(path), + size_without_padding(size_without_padding) { + this->name = name; + } + + operator bool() const { return nonempty; } + + bool operator==(const SymbolMatchIndex& other) const { + return id == other.id && name == other.name && path == other.path && + size_without_padding == other.size_without_padding; + } + + bool nonempty = false; + caspian::SectionId id; + std::string_view name; + std::string_view path; + int size_without_padding; +}; +} // namespace + +namespace std { +template <> +struct hash<SymbolMatchIndex> { + static constexpr size_t kPrime1 = 105929; + static constexpr size_t kPrime2 = 8543; + size_t operator()(const SymbolMatchIndex& k) const { + return ((kPrime1 * static_cast<size_t>(k.id)) ^ + hash<string_view>()(k.name) ^ hash<string_view>()(k.path) ^ + (kPrime2 * k.size_without_padding)); + } +}; +} // namespace std + namespace caspian { Symbol::Symbol() = default; Symbol::Symbol(const Symbol& other) = default; +Symbol& Symbol::operator=(const Symbol& other) = default; + +Symbol Symbol::DiffSymbolFrom(const Symbol* before_sym, + const Symbol* after_sym) { + Symbol ret; + if (after_sym) { + ret = *after_sym; + } else if (before_sym) { + ret = *before_sym; + } + + if (before_sym && after_sym) { + ret.size = after_sym->size - before_sym->size; + ret.pss = after_sym->pss - before_sym->pss; + } else if (before_sym) { + ret.size = -before_sym->size; + ret.pss = -before_sym->pss; + } + + return ret; +} TreeNode::TreeNode() = default; TreeNode::~TreeNode() { @@ -23,6 +90,16 @@ } } +std::ostream& operator<<(std::ostream& os, const Symbol& sym) { + return os << "Symbol(full_name=" << sym.full_name + << ", section=" << static_cast<char>(sym.sectionId) + << ", address=" << sym.address << ", size=" << sym.size + << ", flags=" << sym.flags << ", padding=" << sym.padding << ")"; +} + +BaseSizeInfo::BaseSizeInfo() = default; +BaseSizeInfo::~BaseSizeInfo() = default; + SizeInfo::SizeInfo() = default; SizeInfo::~SizeInfo() = default; @@ -61,10 +138,100 @@ return ret; } +namespace { +// Copied from /base/stl_util.h +template <class T, class Allocator, class Value> +void Erase(std::vector<T, Allocator>& container, const Value& value) { + container.erase(std::remove(container.begin(), container.end(), value), + container.end()); +} + +std::string_view GetIdPath(const Symbol& sym) { + return (sym.source_path && *sym.source_path) ? sym.source_path + : sym.object_path; +} + +SymbolMatchIndex PerfectMatch(const Symbol& sym) { + return SymbolMatchIndex(sym.sectionId, sym.full_name, GetIdPath(sym), + sym.pss); +} + +SymbolMatchIndex PerfectMatchExceptSize(const Symbol& sym) { + return SymbolMatchIndex(sym.sectionId, sym.full_name, GetIdPath(sym), 0.0f); +} + +void MatchSymbols(std::function<SymbolMatchIndex(const Symbol&)> key_func, + std::vector<caspian::Symbol>* delta_symbols, + std::vector<const caspian::Symbol*>* unmatched_before, + std::vector<const caspian::Symbol*>* unmatched_after) { + // TODO(jaspercb): Accumulate added/dropped padding by section name. + std::unordered_map<SymbolMatchIndex, + std::list<std::reference_wrapper<const caspian::Symbol*>>> + before_symbols_by_key; + for (const caspian::Symbol*& before_sym : *unmatched_before) { + SymbolMatchIndex key = key_func(*before_sym); + if (key) { + before_symbols_by_key[key].emplace_back(before_sym); + } + } + + for (const caspian::Symbol*& after_sym : *unmatched_after) { + SymbolMatchIndex key = key_func(*after_sym); + if (key) { + const auto& found = before_symbols_by_key.find(key); + if (found != before_symbols_by_key.end() && found->second.size()) { + const caspian::Symbol*& before_sym = found->second.front().get(); + found->second.pop_front(); + delta_symbols->push_back(Symbol::DiffSymbolFrom(before_sym, after_sym)); + before_sym = nullptr; + after_sym = nullptr; + } + } + } + + Erase(*unmatched_before, nullptr); + Erase(*unmatched_after, nullptr); +} +} // namespace + +DiffSizeInfo::DiffSizeInfo(SizeInfo* before, SizeInfo* after) + : before(before), after(after) { + // TODO(jaspercb): It's okay to do a first pass where we match on the raw + // name (from the .size file), but anything left over after that first step + // (hopefully <2k objects) needs to consider the derived full_name. Should + // do this lazily for efficiency - name derivation is costly. + + std::vector<const caspian::Symbol*> unmatched_before; + for (const caspian::Symbol& sym : before->raw_symbols) { + unmatched_before.push_back(&sym); + } + + std::vector<const caspian::Symbol*> unmatched_after; + for (const caspian::Symbol& sym : after->raw_symbols) { + unmatched_after.push_back(&sym); + } + + // Attempt several rounds to use increasingly loose matching on unmatched + // symbols. Any symbols still unmatched are tried in the next round. + for (const auto& key_function : {PerfectMatch, PerfectMatchExceptSize}) { + MatchSymbols(key_function, &raw_symbols, &unmatched_before, + &unmatched_after); + } + + // Add removals or deletions for any unmatched symbols. + for (const caspian::Symbol* after_sym : unmatched_after) { + raw_symbols.push_back(Symbol::DiffSymbolFrom(nullptr, after_sym)); + } + for (const caspian::Symbol* before_sym : unmatched_before) { + raw_symbols.push_back(Symbol::DiffSymbolFrom(before_sym, nullptr)); + } +} + +DiffSizeInfo::~DiffSizeInfo() {} + void TreeNode::WriteIntoJson(Json::Value* out, int depth) { (*out)["idPath"] = std::string(this->id_path); (*out)["shortNameIndex"] = this->short_name_index; - // TODO: Put correct information. std::string type; if (container_type != ContainerType::kSymbol) { type += static_cast<char>(container_type); @@ -84,7 +251,7 @@ // TODO: Support additional compare functions. auto compare_func = [](const TreeNode* const& l, const TreeNode* const& r) -> bool { - return l->size > r->size; + return abs(l->size) > abs(r->size); }; std::sort(this->children.begin(), this->children.end(), compare_func); for (unsigned int i = 0; i < this->children.size(); i++) { @@ -124,9 +291,9 @@ SectionId ret = SectionId::kNone; float max = 0.0f; for (auto& pair : child_stats) { - if (pair.second.size > max) { + if (abs(pair.second.size) > max) { ret = pair.first; - max = pair.second.size; + max = abs(pair.second.size); } } return ret;
diff --git a/tools/binary_size/libsupersize/caspian/model.h b/tools/binary_size/libsupersize/caspian/model.h index f5dc71a9..a43b0b5e4 100644 --- a/tools/binary_size/libsupersize/caspian/model.h +++ b/tools/binary_size/libsupersize/caspian/model.h
@@ -44,35 +44,65 @@ struct Symbol { Symbol(); Symbol(const Symbol& other); + Symbol& operator=(const Symbol& other); + static Symbol DiffSymbolFrom(const Symbol* before, const Symbol* after); - float pss() const { - int alias_count = aliases ? aliases->size() : 1; - return static_cast<float>(size) / alias_count; + bool IsOverhead() const { return full_name.substr(0, 10) == "Overhead: "; } + + bool IsBss() const { return sectionId == SectionId::kBss; } + + bool IsDex() const { + return sectionId == SectionId::kDex || sectionId == SectionId::kDexMethod; } + bool IsOther() const { return sectionId == SectionId::kOther; } + + bool IsPak() const { + return sectionId == SectionId::kPakNontranslated || + sectionId == SectionId::kPakTranslations; + } + + bool IsNative() const { + return (sectionId == SectionId::kBss || sectionId == SectionId::kData || + sectionId == SectionId::kDataRelRo || + sectionId == SectionId::kText || sectionId == SectionId::kRoData); + } + + int32_t SizeWithoutPadding() const { return size - padding; } + + int32_t EndAddress() const { return address + SizeWithoutPadding(); } + int32_t address = 0; int32_t size = 0; int32_t flags = 0; int32_t padding = 0; + float pss = 0.0f; + SectionId sectionId = SectionId::kNone; + std::string_view full_name; // Pointers into SizeInfo->raw_decompressed; const char* section_name = nullptr; - std::string_view full_name; const char* object_path = nullptr; const char* source_path = nullptr; const char* component = nullptr; std::vector<Symbol*>* aliases = nullptr; }; -struct SizeInfo { +std::ostream& operator<<(std::ostream& os, const Symbol& sym); + +struct BaseSizeInfo { + BaseSizeInfo(); + ~BaseSizeInfo(); + std::vector<caspian::Symbol> raw_symbols; + Json::Value metadata; +}; + +struct SizeInfo : BaseSizeInfo { SizeInfo(); ~SizeInfo(); SizeInfo(const SizeInfo& other) = delete; SizeInfo& operator=(const SizeInfo& other) = delete; SectionId ShortSectionName(const char* section_name); - std::vector<caspian::Symbol> raw_symbols; - Json::Value metadata; - // Entries in |raw_symbols| hold pointers to this data. std::vector<const char*> object_paths; std::vector<const char*> source_paths; @@ -84,6 +114,16 @@ std::deque<std::vector<Symbol*>> alias_groups; }; +struct DiffSizeInfo : BaseSizeInfo { + DiffSizeInfo(SizeInfo* before, SizeInfo* after); + ~DiffSizeInfo(); + DiffSizeInfo(const DiffSizeInfo&) = delete; + DiffSizeInfo& operator=(const DiffSizeInfo&) = delete; + + SizeInfo* before = nullptr; + SizeInfo* after = nullptr; +}; + struct Stat { int32_t count = 0; float size = 0.0f;
diff --git a/tools/binary_size/libsupersize/caspian/tree_builder.cc b/tools/binary_size/libsupersize/caspian/tree_builder.cc index a2613fb6..a7e7430a 100644 --- a/tools/binary_size/libsupersize/caspian/tree_builder.cc +++ b/tools/binary_size/libsupersize/caspian/tree_builder.cc
@@ -41,7 +41,7 @@ } // namespace TreeBuilder::TreeBuilder( - SizeInfo* size_info, + BaseSizeInfo* size_info, bool group_by_component, std::vector<std::function<bool(const Symbol&)>> filters) : size_info_(size_info), @@ -123,9 +123,8 @@ TreeNode* symbol_node = new TreeNode(); symbol_node->container_type = ContainerType::kSymbol; symbol_node->id_path = sym->full_name; - symbol_node->size = sym->pss(); - symbol_node->node_stats = NodeStats( - size_info_->ShortSectionName(sym->section_name), 1, symbol_node->size); + symbol_node->size = sym->pss; + symbol_node->node_stats = NodeStats(sym->sectionId, 1, symbol_node->size); AttachToParent(symbol_node, file_node); }
diff --git a/tools/binary_size/libsupersize/caspian/tree_builder.h b/tools/binary_size/libsupersize/caspian/tree_builder.h index a69fc12a..afd4270 100644 --- a/tools/binary_size/libsupersize/caspian/tree_builder.h +++ b/tools/binary_size/libsupersize/caspian/tree_builder.h
@@ -17,7 +17,7 @@ namespace caspian { class TreeBuilder { public: - TreeBuilder(SizeInfo* size_info, + TreeBuilder(BaseSizeInfo* size_info, bool group_by_component, std::vector<std::function<bool(const Symbol&)>> filters); ~TreeBuilder(); @@ -45,7 +45,7 @@ // node. std::unordered_map<std::string_view, TreeNode*> _parents; - SizeInfo* size_info_ = nullptr; + BaseSizeInfo* size_info_ = nullptr; // Contained TreeNode hold lightweight string_views to fields in SizeInfo. // If grouping by component, this isn't possible: TreeNode id_paths are not // substrings of SizeInfo-owned strings. In that case, the strings are stored
diff --git a/tools/binary_size/libsupersize/start_server.py b/tools/binary_size/libsupersize/start_server.py index 88ffefa9..82a66b7 100644 --- a/tools/binary_size/libsupersize/start_server.py +++ b/tools/binary_size/libsupersize/start_server.py
@@ -16,6 +16,7 @@ serve_from = None # Path to data file data_file_path = None + before_file_path = None #override def translate_path(self, path): @@ -23,6 +24,8 @@ relative_path = os.path.relpath(f, os.getcwd()) if relative_path == 'data.ndjson': return SupersizeHTTPRequestHandler.data_file_path + if relative_path == 'before.size': + return SupersizeHTTPRequestHandler.before_file_path else: return os.path.join(SupersizeHTTPRequestHandler.serve_from, relative_path) @@ -30,6 +33,13 @@ def AddArguments(parser): parser.add_argument('report_file', help='Path to a custom html_report data file to load.') + parser.add_argument( + '-b', + '--before_file', + type=str, + default='', + help=('Path to a "before" .size file to diff against. If present, ' + 'report_file should also be a .size file.')) parser.add_argument('-p', '--port', type=int, default=8000, help='Port for the HTTP server') parser.add_argument('-a', '--address', default='localhost', @@ -44,11 +54,13 @@ SupersizeHTTPRequestHandler.serve_from = static_files SupersizeHTTPRequestHandler.data_file_path = args.report_file + SupersizeHTTPRequestHandler.before_file_path = args.before_file SupersizeHTTPRequestHandler.extensions_map['.wasm'] = 'application/wasm' httpd = BaseHTTPServer.HTTPServer(server_addr, SupersizeHTTPRequestHandler) sa = httpd.socket.getsockname() + before_suffix = '&before_url=before.size&wasm=1' if args.before_file else '' logging.warning( - 'Server ready at http://%s:%d/viewer.html?load_url=data.ndjson', - sa[0], sa[1]) + 'Server ready at http://%s:%d/viewer.html?load_url=data.ndjson' + + before_suffix, sa[0], sa[1]) httpd.serve_forever()
diff --git a/tools/binary_size/libsupersize/static/tree-worker-wasm.js b/tools/binary_size/libsupersize/static/tree-worker-wasm.js index 8458b1b..f4cfff3 100644 --- a/tools/binary_size/libsupersize/static/tree-worker-wasm.js +++ b/tools/binary_size/libsupersize/static/tree-worker-wasm.js
@@ -7,6 +7,13 @@ importScripts('./shared.js'); importScripts('./caspian_web.js'); +const LoadWasm = new Promise(function(resolve, reject) { + Module['onRuntimeInitialized'] = function() { + console.log('Loaded WebAssembly runtime'); + resolve(); + } +}); + const _PATH_SEP = '/'; const _NAMES_TO_FLAGS = Object.freeze({ hot: _FLAGS.HOT, @@ -127,84 +134,66 @@ return dataHeap; } -var _Open = null; -function Open(name) { - if (_Open === null) { +async function Open(name) { + return LoadWasm.then(() => { _Open = Module.cwrap('Open', 'number', ['string']); - } - let stringPtr = _Open(name); - // Something has gone wrong if we get back a string longer than 67MB. - let ret = JSON.parse(Module.UTF8ToString(stringPtr, 2 ** 26)); - console.log(ret); - return ret; + const stringPtr = _Open(name); + // Something has gone wrong if we get back a string longer than 67MB. + const ret = JSON.parse(Module.UTF8ToString(stringPtr, 2 ** 26)); + return ret; + }); } // Placeholder input name until supplied via setInput() -const fetcher = new DataFetcher('data.size'); +const fetcher = new DataFetcher('data.ndjson'); +let beforeFetcher = null; let sizeFileLoaded = false; +async function loadSizeFile(isBefore, fetcher) { + const sizeBuffer = await fetcher.loadSizeBuffer(); + const heapBuffer = mallocBuffer(sizeBuffer); + const LoadSizeFile = Module.cwrap( + isBefore ? 'LoadBeforeSizeFile' : 'LoadSizeFile', 'bool', + ['number', 'number']); + const start_time = Date.now(); + LoadSizeFile(heapBuffer.byteOffset, sizeBuffer.byteLength); + console.log( + 'Loaded size file in ' + (Date.now() - start_time) / 1000.0 + ' seconds'); + Module._free(heapBuffer.byteOffset); +} + async function buildTree( groupBy, includeRegex, excludeRegex, includeSections, minSymbolSize, flagToFilter, methodCountMode, onProgress) { - if (!sizeFileLoaded) { - let sizeBuffer = await fetcher.loadSizeBuffer(); - let heapBuffer = mallocBuffer(sizeBuffer); - console.log('Passing ' + sizeBuffer.byteLength + ' bytes to WebAssembly'); - let LoadSizeFile = - Module.cwrap('LoadSizeFile', 'bool', ['number', 'number']); - let start_time = Date.now(); - LoadSizeFile(heapBuffer.byteOffset, sizeBuffer.byteLength); + return await LoadWasm.then(async () => { + if (!sizeFileLoaded) { + const current = loadSizeFile(false, fetcher); + const before = + beforeFetcher !== null ? loadSizeFile(true, beforeFetcher) : null; + await current; + await before; + sizeFileLoaded = true; + } + + const BuildTree = Module.cwrap( + 'BuildTree', 'void', + ['bool', 'string', 'string', 'string', 'number', 'number']); + const start_time = Date.now(); + const groupByComponent = groupBy === 'component'; + BuildTree( + groupByComponent, includeRegex, excludeRegex, includeSections, + minSymbolSize, flagToFilter); console.log( - 'Loaded size file in ' + (Date.now() - start_time) / 1000.0 + + 'Constructed tree in ' + (Date.now() - start_time) / 1000.0 + ' seconds'); - Module._free(heapBuffer.byteOffset); - sizeFileLoaded = true; - } - - /** - * Creates data to post to the UI thread. Defaults will be used for the root - * and percent values if not specified. - * @param {{root?:TreeNode,percent?:number,error?:Error}} data Default data - * values to post. - */ - function createProgressMessage(data = {}) { - let {percent} = data; - if (percent == null) { - if (meta == null) { - percent = 0; - } else { - percent = Math.max(builder.rootNode.size / meta.total, 0.1); - } - } - - const message = { - root: builder.formatNode(data.root || builder.rootNode), - percent, - diffMode: meta && meta.diff_mode, + const root = await Open(''); + return { + root: root, + percent: 1.0, + diffMode: beforeFetcher !== null, // diff mode }; - if (data.error) { - message.error = data.error.message; - } - return message; - } - - let BuildTree = Module.cwrap( - 'BuildTree', 'void', - ['bool', 'string', 'string', 'string', 'number', 'number']); - let start_time = Date.now(); - const groupByComponent = groupBy === 'component'; - BuildTree( - groupByComponent, includeRegex, excludeRegex, includeSections, - minSymbolSize, flagToFilter); - console.log('Constructed tree in ' + - (Date.now() - start_time)/1000.0 + ' seconds'); - - return { - root: Open(''), - percent: 1.0, - diffMode: 0, // diff mode - }; + }); } /** @@ -215,15 +204,8 @@ function parseOptions(options) { const params = new URLSearchParams(options); - const url = params.get('load_url'); const groupBy = params.get('group_by') || 'source_path'; const methodCountMode = params.has('method_count'); - const flagToFilter = _NAMES_TO_FLAGS[params.get('flag_filter')] || 0; - - let minSymbolSize = Number(params.get('min_size')); - if (Number.isNaN(minSymbolSize)) { - minSymbolSize = 0; - } const includeRegex = params.get('include'); const excludeRegex = params.get('exclude'); @@ -238,6 +220,15 @@ includeSections = Array.from(includeSectionsSet.values()).join(''); } + const minSymbolSize = Number(params.get('min_size')); + if (Number.isNaN(minSymbolSize)) { + minSymbolSize = 0; + } + + const flagToFilter = _NAMES_TO_FLAGS[params.get('flag_filter')] || 0; + const url = params.get('load_url'); + const beforeUrl = params.get('before_url'); + return { groupBy, includeRegex, @@ -246,6 +237,7 @@ minSymbolSize, flagToFilter, url, + beforeUrl, }; } @@ -260,6 +252,7 @@ minSymbolSize, flagToFilter, url, + beforeUrl, } = parseOptions(options); if (input === 'from-url://' && url) { // Display the data from the `load_url` query parameter @@ -270,6 +263,10 @@ fetcher.setInput(input); } + if (beforeUrl) { + beforeFetcher = new DataFetcher(beforeUrl); + } + return buildTree( groupBy, includeRegex, excludeRegex, includeSections, minSymbolSize, flagToFilter, progress => {
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 040c482..c2eccf54 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -749,6 +749,14 @@ </description> </action> +<action name="Accel_Minimize_Top_Window_On_Back"> + <owner>minch@chromium.org</owner> + <description> + Metric recorded when the user press back key in the keyboard to minimize the + top window at bottom page while in tablet mode. + </description> +</action> + <action name="Accel_Move_Active_Window_Between_Displays"> <owner>warx@chromium.org</owner> <description> @@ -15142,12 +15150,12 @@ <action name="Options_AccessibilitySwitchAccess_Disable"> <owner>dmazzoni@chromium.org</owner> - <description>Settings: Accessibility: Disable switch access</description> + <description>Settings: Accessibility: Disable Switch Access</description> </action> <action name="Options_AccessibilitySwitchAccess_Enable"> <owner>dmazzoni@chromium.org</owner> - <description>Settings: Accessibility: Enable switch access</description> + <description>Settings: Accessibility: Enable Switch Access</description> </action> <action name="Options_AccessibilitySystemMenu_Disable"> @@ -21377,7 +21385,7 @@ <owner>anastasi@google.com</owner> <owner>dtseng@chromium.org</owner> <description> - Ash system menu: Accessibility: Disable switch access + Ash system menu: Accessibility: Disable Switch Access </description> </action> @@ -21385,7 +21393,7 @@ <owner>anastasi@google.com</owner> <owner>dtseng@chromium.org</owner> <description> - Ash system menu: Accessibility: Enable switch access + Ash system menu: Accessibility: Enable Switch Access </description> </action>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index f71ec25..8513098d 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -4858,9 +4858,12 @@ <int value="-684843031" label="SafeBrowsingTriggeredPopupBlocker"/> <int value="-438850149" label="PermissionRequestManager"/> <int value="72716222" label="WebBluetooth"/> + <int value="88001126" label="MixedContentSettingsTabHelper"/> <int value="671363579" label="banners::AppBannerManager"/> <int value="990438262" label="MediaWebContentsObserver::OnMediaPlaying"/> <int value="1683256665" label="NativeFileSystem"/> + <int value="1774599341" label="WebAuthenticationAPI"/> + <int value="1985234179" label="PermissionServiceContext"/> <int value="2013040510" label="RenderFrameDevToolsAgentHost"/> <int value="2024383223" label="ChromePasswordManagerClient::BindCredentialManager"/> @@ -38223,6 +38226,7 @@ <int value="1258043820" label="AudioFocusEnforcement:enabled"/> <int value="1258747457" label="SyncPseudoUSSHistoryDeleteDirectives:disabled"/> + <int value="1259798038" label="AllowAmbientEQ:disabled"/> <int value="1260186484" label="spurious-power-button-screen-accel"/> <int value="1261379424" label="DecodeLossyWebPImagesToYUV:disabled"/> <int value="1261713150" label="ChromeHomeOptOutSnackbar:disabled"/> @@ -38531,6 +38535,7 @@ <int value="1658644418" label="disable-app-list-voice-search"/> <int value="1659082220" label="EnableManualSaving:disabled"/> <int value="1659372520" label="WebXrRenderPath:disabled"/> + <int value="1660491118" label="AllowAmbientEQ:enabled"/> <int value="1661925474" label="silent-debugger-extension-api"/> <int value="1664401033" label="ColorCorrectRendering:enabled"/> <int value="1665349789" label="spurious-power-button-window"/> @@ -40878,6 +40883,7 @@ <int value="1" label="Overflow Menu"/> <int value="2" label="Contextual Menu"/> <int value="3" label="Page"/> + <int value="4" label="App Menu"/> </enum> <enum name="MediaRouterDialParseMessageResult">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index abf6645..46683336 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -14486,6 +14486,11 @@ <histogram name="Blink.Animate.UpdateTime" units="microseconds" expires_after="2020-05-03"> +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> + +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> + + <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <summary> Time spent processing main frame animations during a main frame update. @@ -16088,6 +16093,10 @@ <histogram name="Blink.MainFrame.UpdateTime" units="microseconds" expires_after="2020-05-03"> +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> + +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> + <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <summary> @@ -16275,6 +16284,11 @@ <histogram name="Blink.Paint.UpdateTime" units="microseconds" expires_after="2020-05-03"> +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> + +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> + + <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <summary> Time spent updating paint in the Blink document lifecycle. @@ -16299,6 +16313,11 @@ <histogram name="Blink.PrePaint.UpdateTime" units="microseconds" expires_after="2020-05-03"> +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> + +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> + + <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <summary> Time spent updating paint properties and paint invalidation in the Blink @@ -16312,6 +16331,11 @@ <histogram name="Blink.ProxyCommit.UpdateTime" units="microseconds" expires_after="2020-05-03"> +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> + +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> + + <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <summary> Time spent commiting the layer tree to the impl thread in a main frame @@ -16603,7 +16627,12 @@ <histogram name="Blink.ScrollingCoordinator.UpdateTime" units="microseconds" expires_after="2020-05-03"> +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> + +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> + <owner>pdr@chromium.org</owner> + <owner>paint-dev@chromium.org</owner> <summary> The time it took to update scrolling coordinator data (scroll gesture regions, touch event rects, and main thread scrolling reasons). These values @@ -16769,6 +16798,10 @@ <histogram name="Blink.Style.UpdateTime" units="microseconds" expires_after="2020-05-03"> +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> + +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> + <owner>schenney@chromium.org</owner> <owner>layout-dev@chromium.org</owner> <summary> @@ -16781,6 +16814,11 @@ <histogram name="Blink.StyleAndLayout.UpdateTime" units="microseconds" expires_after="2020-04-19"> +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> + +<!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> + + <owner>schenney@chromium.org</owner> <owner>layout-dev@chromium.org</owner> <summary> Time spent updating style and layout in the Blink document lifecycle. @@ -44639,8 +44677,7 @@ </summary> </histogram> -<histogram name="ExploreSites.NavBackTime" units="ms" expires_after="M80"> - <owner>angelii@google.com</owner> +<histogram name="ExploreSites.NavBackTime" units="ms" expires_after="M85"> <owner>chili@chromium.org</owner> <owner>dewittj@chromium.org</owner> <summary> @@ -52509,6 +52546,18 @@ </summary> </histogram> +<histogram name="GCM.SendWebPushMessageStatusCode" + enum="CombinedHttpResponseAndNetErrorCode" expires_after="2020-04-05"> + <owner>alexchau@chromium.org</owner> + <owner>peter@chromium.org</owner> + <summary> + Result code from sending web push messages. Logs net::Error if it's not + net::OK. Logs net::OK if response header is not present. Otherwise, logs + HTTP status code returned. Recorded when received response after message has + been sent. + </summary> +</histogram> + <histogram name="GCM.StoreDestroySucceeded" enum="BooleanSuccess"> <owner>zea@chromium.org</owner> <summary> @@ -99509,7 +99558,22 @@ <summary> Records when hints fetching is enabled whether the HTTPS host being navigated to was included in a hints fetch request and any hints returned - have not since expired. + have not since expired. Captured at navigation start so it will not include + hints fetched based on the current navigation. + </summary> +</histogram> + +<histogram + name="OptimizationGuide.HintsFetcher.NavigationHostCoveredByFetch.AtCommit" + enum="BooleanCovered" expires_after="M85"> + <owner>mcrouse@chromium.org</owner> + <owner>dougarnett@chromium.org</owner> + <summary> + Records when hints fetching is enabled whether the HTTPS host being + navigated to was included in a hints fetch request and any hints returned + have not since expired. Captured after a navigation navigation is committed + in order to determine if the fetch attempt made at navigation start + succeeded or not. </summary> </histogram> @@ -170119,6 +170183,40 @@ <affected-histogram name="Blink.MainFrame.UpdateLayersRatio"/> </histogram_suffixes> +<histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" separator="."> + <suffix name="PostFCP" label="Update occurred after First Contentful Paint."/> + <affected-histogram name="Blink.Animate.UpdateTime"/> + <affected-histogram name="Blink.Compositing.UpdateTime"/> + <affected-histogram name="Blink.CompositingCommit.UpdateTime"/> + <affected-histogram name="Blink.ForcedStyleAndLayout.UpdateTime"/> + <affected-histogram name="Blink.HandleInputEvents.UpdateTime"/> + <affected-histogram name="Blink.IntersectionObservation.UpdateTime"/> + <affected-histogram name="Blink.Layout.UpdateTime"/> + <affected-histogram name="Blink.Paint.UpdateTime"/> + <affected-histogram name="Blink.PrePaint.UpdateTime"/> + <affected-histogram name="Blink.ProxyCommit.UpdateTime"/> + <affected-histogram name="Blink.ScrollingCoordinator.UpdateTime"/> + <affected-histogram name="Blink.Style.UpdateTime"/> + <affected-histogram name="Blink.StyleAndLayout.UpdateTime"/> +</histogram_suffixes> + +<histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" separator="."> + <suffix name="PreFCP" label="Update occurred before First Contentful Paint."/> + <affected-histogram name="Blink.Animate.UpdateTime"/> + <affected-histogram name="Blink.Compositing.UpdateTime"/> + <affected-histogram name="Blink.CompositingCommit.UpdateTime"/> + <affected-histogram name="Blink.ForcedStyleAndLayout.UpdateTime"/> + <affected-histogram name="Blink.HandleInputEvents.UpdateTime"/> + <affected-histogram name="Blink.IntersectionObservation.UpdateTime"/> + <affected-histogram name="Blink.Layout.UpdateTime"/> + <affected-histogram name="Blink.Paint.UpdateTime"/> + <affected-histogram name="Blink.PrePaint.UpdateTime"/> + <affected-histogram name="Blink.ProxyCommit.UpdateTime"/> + <affected-histogram name="Blink.ScrollingCoordinator.UpdateTime"/> + <affected-histogram name="Blink.Style.UpdateTime"/> + <affected-histogram name="Blink.StyleAndLayout.UpdateTime"/> +</histogram_suffixes> + <histogram_suffixes name="BlinkVisibleLoadTimeSuffixes" separator="."> <suffix name="2G" label="2G effective connection type"/> <suffix name="3G" label="3G effective connection type"/>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 6210309..12e41f2 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -5332,6 +5332,19 @@ applied on the page load. </summary> </metric> + <metric name="PainfulPageLoadModelPredictionScore"> + <summary> + The score output after evaluating the painful page load model. If + populated, this is 100x the fractional value output by the model + evaluation. This will be a value between 0 and 100. + </summary> + </metric> + <metric name="PainfulPageLoadModelVersion"> + <summary> + The server-generated version of the painful page load model that was + evaluated for the page load. + </summary> + </metric> </event> <event name="PageDomainInfo"> @@ -6041,8 +6054,6 @@ <aggregation> <history> <index fields="profile.country"/> - <index fields="profile.is_dominant_version"/> - <index fields="profile.is_latest_version"/> <statistics> <quantiles type="std-percentiles"/> </statistics> @@ -7250,7 +7261,7 @@ </metric> <metric name="IsSwitchAccessEnabled"> <summary> - Boolean value to represent whether switch access is currently enabled. + Boolean value to represent whether Switch Access is currently enabled. </summary> </metric> <metric name="IsVideoPlaying">
diff --git a/tools/perf/core/results_processor/README.md b/tools/perf/core/results_processor/README.md new file mode 100644 index 0000000..5fac610a --- /dev/null +++ b/tools/perf/core/results_processor/README.md
@@ -0,0 +1,112 @@ +<!-- 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. +--> + +# Results Processor + +Results Processor is a tool to process intermediate results produced by +Telemetry or other test-running frameworks and extract performance measurements +from them. It expects its input in the form of a directory with the following +contents: +- A `_test_results.jsonl` file. +- Subdirectories with test artifacts (including traces) - one per test result. + +## Test results file + +The `_test_results.jsonl` file tries to follow the +[LUCI test results format](https://chromium.googlesource.com/infra/luci/luci-go/+/HEAD/resultdb/proto/sink/v1/test_result.proto). +Its every line is a json message of the `testResult` type. There are following +additional conventions: + +- The following keys are mandatory: + - status + - testPath +- For [json3 output](https://chromium.googlesource.com/chromium/src/+/master/docs/testing/json_test_results_format.md), the following are also mandatory: + - expected + - runDuration +- testPath is either in the form `{benchmark_name}/{story_name}` or in the form +`{test_suite_name}.{test_case_name}`. The format to use is specified by the +command-line flag `--test-path-format`. +- TBMv2 metrics, if necessary, are listed as tags with key `tbmv2`. +- Traces, if present, are listed as output artifacts with their names starting +with `trace/`. For details, see the [Traces subsection](#traces) below. +- Device and benchmark diagnostics (also optional) are stored in a special +artifact with the name `diagnostics.json` in the form of a json dict. +Diagnostic names must be listed in the +[reserved infos](https://cs.chromium.org/chromium/src/third_party/catapult/tracing/tracing/value/diagnostics/reserved_infos.py) +module. +- All artifacts files for a single test result are in a separate subdirectory. + +### Traces + +Traces should be output artifacts with their names starting with `trace/`. The +names should also have an extension. The extension of a trace name corresponds +to its format as follows: + +|extension | format +|--- | --- +|.json | Json trace +|.json.gz | Gzipped json trace +|.pb | Proto trace +|.pb.gz | Gzipped proto trace + +Note that this convention relates to the artifact name only, the actual file +stored in the host does not have to follow it. + +### Example + +Example of a single testResult message (formatted across multiple lines for ease +of reading): + + { + "testResult": { + "testPath": "benchmark/story1", + "status": "PASS", + "expected": true, + "startTime": "2019-10-23T09:43:32.046792Z", + "runDuration": "15.06s", + "outputArtifacts": { + "diagnostics.json": { + "contentType": "application/json", + "filePath": "/output/run_1/story1/diagnostics.json" + }, + "trace/cpu/1.json": { + "contentType": "application/json", + "filePath": "/output/run_1/story1/trace/cpu/1.json" + }, + "trace/chrome/1.json.gz": { + "contentType": "application/gzip", + "filePath": "/output/run_1/story1/trace/chrome/1.json.gz" + } + }, + "tags": [ + { + "key": "tbmv2", + "value": "consoleErrorMetric" + }, + { + "key": "tbmv2", + "value": "cpuTimeMetric" + } + ] + } + } + +## Two modes of operation + +Results Processor can be invoked as a standalone script +[tools/perf/results_processor](https://cs.chromium.org/chromium/src/tools/perf/results_processor?q=tools/perf/results_processor) +or as a python module (see e.g. +[benchmark_runner.py](https://cs.chromium.org/chromium/src/tools/perf/core/benchmark_runner.py) +). + +The standalone script has a mandatory argument `--intermediate-dir` that should +point to a directory with intermediate results as described above. If invoked +from another script, the `results_processor.ProcessOptions()` method provides +a reasonable default for the `--intermediate-dir` argument. + +In both modes final results are placed inside the output directory provided +by the `--output-dir` argument. By default it’s the base directory of the +running script. +
diff --git a/tools/perf/core/results_processor/command_line.py b/tools/perf/core/results_processor/command_line.py index 5ea5e73..97515ce7d 100644 --- a/tools/perf/core/results_processor/command_line.py +++ b/tools/perf/core/results_processor/command_line.py
@@ -139,7 +139,9 @@ if not options.output_formats: options.output_formats = ['html'] - elif 'none' in options.output_formats: + else: + options.output_formats = sorted(set(options.output_formats)) + if 'none' in options.output_formats: options.output_formats.remove('none')
diff --git a/tools/perf/core/results_processor/command_line_unittest.py b/tools/perf/core/results_processor/command_line_unittest.py index 147bc2a3..c929abb 100644 --- a/tools/perf/core/results_processor/command_line_unittest.py +++ b/tools/perf/core/results_processor/command_line_unittest.py
@@ -129,6 +129,12 @@ with self.assertRaises(SystemExit): self.ParseArgs(['--output-format', 'unknown']) + def testNoDuplicateOutputFormats(self): + options = self.ParseArgs( + ['--output-format', 'html', '--output-format', 'csv', + '--output-format', 'html', '--output-format', 'csv']) + self.assertEqual(options.output_formats, ['csv', 'html']) + class StandaloneTestProcessOptions(ProcessOptionsTestCase): def setUp(self):
diff --git a/tools/perf/core/results_processor/processor.py b/tools/perf/core/results_processor/processor.py index 853e55d..586b5d6 100644 --- a/tools/perf/core/results_processor/processor.py +++ b/tools/perf/core/results_processor/processor.py
@@ -205,9 +205,7 @@ """ artifacts = test_result.get('outputArtifacts', {}) json_traces = [name for name in artifacts if _IsJsonTrace(name)] - # TODO(crbug.com/981349): Stop checking for HTML_TRACE_NAME after - # Telemetry does not aggregate traces anymore. - if json_traces and compute_metrics.HTML_TRACE_NAME not in artifacts: + if json_traces: trace_files = [artifacts[name]['filePath'] for name in json_traces] html_path = _BuildOutputPath(trace_files, compute_metrics.HTML_TRACE_NAME) logging.info('%s: Aggregating json traces %s.', @@ -246,7 +244,7 @@ continue # TODO(crbug.com/981349): Think of a more general way to # specify which artifacts deserve uploading. - if name == MEASUREMENTS_NAME: + if name in [DIAGNOSTICS_NAME, MEASUREMENTS_NAME]: continue remote_name = '/'.join([run_identifier, test_result['testPath'], name]) urlsafe_remote_name = re.sub(r'[^A-Za-z0-9/.-]+', '_', remote_name)
diff --git a/tools/perf/core/results_processor/processor_test.py b/tools/perf/core/results_processor/processor_test.py index d3962a85..0a161fd 100644 --- a/tools/perf/core/results_processor/processor_test.py +++ b/tools/perf/core/results_processor/processor_test.py
@@ -123,9 +123,8 @@ 'benchmark/story', output_artifacts={ 'logs': testing.Artifact('/logs.txt', 'gs://logs.txt'), - 'trace/telemetry.json': testing.Artifact('/telemetry.json'), - 'trace.html': - testing.Artifact('/trace.html', 'gs://trace.html'), + 'screenshot': testing.Artifact( + os.path.join(self.output_dir, 'screenshot.png')), } ), ) @@ -146,7 +145,7 @@ self.assertEqual(len(artifacts), 2) self.assertEqual(artifacts['logs'], ['gs://logs.txt']) - self.assertEqual(artifacts['trace.html'], ['gs://trace.html']) + self.assertEqual(artifacts['screenshot'], ['screenshot.png']) def testMaxValuesPerTestCase(self): def SomeMeasurements(num):
diff --git a/tools/resources/svgo_presubmit.py b/tools/resources/svgo_presubmit.py index a32dfb33..4789106 100644 --- a/tools/resources/svgo_presubmit.py +++ b/tools/resources/svgo_presubmit.py
@@ -3,8 +3,15 @@ # found in the LICENSE file. +# Ignore the following files from SVG optimization checks. +BLOCKLIST = [ + # Ignore since it holds documentation comments. + "components/dom_distiller/core/images/dom_distiller_material_spinner.svg", +] + def CheckOptimized(input_api, output_api): - file_filter = lambda f: f.LocalPath().endswith('.svg') + file_filter = lambda f: f.LocalPath().endswith('.svg') and \ + f.LocalPath() not in BLOCKLIST svgs = input_api.AffectedFiles(file_filter=file_filter, include_deletes=False) if not svgs:
diff --git a/tools/translation/README.md b/tools/translation/README.md index 7d3cebf..54291b95 100644 --- a/tools/translation/README.md +++ b/tools/translation/README.md
@@ -24,3 +24,19 @@ For more information, see [https://g.co/chrome/translation](https://g.co/chrome/translation). +# Run the tests + +The presubmit automatically runs all files named `*_unittest.py `: +``` +git cl presubmit --force +``` + +python + +# Run sanity checks + +This will attempt to load all .grd and .grdp files in the Chrome repo. +Run once before uploading the CL to ensure everything works. +``` +python helper/sanity_check.py +```
diff --git a/tools/translation/helper/grd_helper.py b/tools/translation/helper/grd_helper.py new file mode 100644 index 0000000..b36aee03 --- /dev/null +++ b/tools/translation/helper/grd_helper.py
@@ -0,0 +1,75 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import sys +import tempfile + +here = os.path.dirname(os.path.realpath(__file__)) +repo_root = os.path.normpath(os.path.join(here, '..', '..', '..')) + +try: + old_sys_path = sys.path + sys.path = sys.path + [os.path.join(repo_root, 'tools', 'grit')] + import grit.grd_reader + import grit.node.message + import grit.util +finally: + sys.path = old_sys_path + +TAGS_TO_IGNORE = ( + # <include> tags mostly point to resource files that don't contain UI + # strings. + 'include', + # <structure> tags point to image files. + 'structure') + + +def GetGrdMessages(grd_path_or_string, dir_path): + """Load the grd file and return a dict of message ids to messages.""" + doc = grit.grd_reader.Parse( + grd_path_or_string, + dir_path, + stop_after=None, + first_ids_file=None, + debug=False, + defines={'_chromium': 1}, + tags_to_ignore=set(TAGS_TO_IGNORE)) + return { + msg.attrs['name']: msg + for msg in doc.GetChildrenOfType(grit.node.message.MessageNode) + } + + +def GetGrdpMessagesFromString(grdp_string): + """Parses the contents of the grdp file given in grdp_string. + + grd_reader can't parse grdp files directly. Instead, this replaces grd + specific tags in the input string with grdp specific tags, writes the output + string in a temporary file and loads the grd from the temporary file. + + This code previously created a temporary directory (using grit.util), wrote + a temporary grd file pointing to another temporary grdp file that contained + the input string. This was not testable since os.path.exists is overridden + in tests and grit.util uses mkdirs which in turn calls os.path.exists. This + new code works because it doesn't need to check the existence of a path. + + It's expected that a grdp file will not refer to another grdp file via a + <part> tag. Currently, none of the grdp files in the repository does that. + """ + replaced_string = grdp_string.replace( + '<grit-part>', + """<grit base_dir="." latest_public_release="1" current_release="1"> + <release seq="1" allow_pseudo="false"> + <messages fallback_to_english="true"> + """) + replaced_string = replaced_string.replace( + '</grit-part>', """</messages> + </release> + </grit>""") + with tempfile.NamedTemporaryFile() as f: + f.write(replaced_string.encode('utf-8')) + f.flush() + f.seek(0) + return GetGrdMessages(f.name, os.path.dirname(f.name))
diff --git a/tools/translation/helper/grd_helper_unittest.py b/tools/translation/helper/grd_helper_unittest.py new file mode 100644 index 0000000..cfa181d --- /dev/null +++ b/tools/translation/helper/grd_helper_unittest.py
@@ -0,0 +1,43 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Unit tests for grd_helper.py.""" + +import io +import os +import unittest +from .helper import grd_helper + +here = os.path.dirname(os.path.realpath(__file__)) +repo_root = os.path.normpath(os.path.join(here, '..', '..', '..')) + + +def read_file_as_text(path): + with io.open(path, mode='r', encoding='utf-8') as f: + return f.read() + + +class GrdHelperTest(unittest.TestCase): + + def testReadGrdMessages(self): + grd_dir = os.path.join(repo_root, 'tools', 'translation', 'testdata') + messages = grd_helper.GetGrdMessages( + os.path.join(grd_dir, 'test.grd'), grd_dir) + # Result should contain all messages from test.grd and part.grdp. + self.assertTrue('IDS_TEST_STRING1' in messages) + self.assertTrue('IDS_TEST_STRING2' in messages) + self.assertTrue('IDS_TEST_STRING_NON_TRANSLATEABLE' in messages) + self.assertTrue('IDS_PART_STRING_NON_TRANSLATEABLE' in messages) + + def testReadGrdpMessages(self): + messages = grd_helper.GetGrdpMessagesFromString( + read_file_as_text( + os.path.join(repo_root, 'tools', 'translation', 'testdata', + 'part.grdp'))) + self.assertTrue('IDS_PART_STRING1' in messages) + self.assertTrue('IDS_PART_STRING2' in messages) + print('DONE') + + +if __name__ == '__main__': + unittest.main()
diff --git a/tools/translation/helper/sanity_check.py b/tools/translation/helper/sanity_check.py new file mode 100644 index 0000000..cf2365de --- /dev/null +++ b/tools/translation/helper/sanity_check.py
@@ -0,0 +1,82 @@ +# 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. +"""Sanity checking for grd_helper.py. Run manually before uploading a CL.""" + +from .helper import grd_helper +from .helper import translation_helper +import io +import os +import subprocess +import sys + +if sys.platform.startswith('win'): + # Use the |git.bat| in the depot_tools/ on Windows. + GIT = 'git.bat' +else: + GIT = 'git' + +here = os.path.dirname(os.path.realpath(__file__)) +repo_root = os.path.normpath(os.path.join(here, '..', '..', '..')) + + +def list_files_in_repository(repo_path, pattern): + """Lists all files matching given pattern in the given git repository""" + # This works because git does its own glob expansion even though there is no + # shell to do it. + output = subprocess.check_output([GIT, 'ls-files', '--', pattern], + cwd=repo_path) + return output.strip().splitlines() + + +def read_file_as_text(path): + with io.open(path, mode='r', encoding='utf-8') as f: + return f.read() + + +# Sanity checks to ensure that we can parse all grd and grdp files in the repo. +# Must not fail. +def Run(): + grds = list_files_in_repository(repo_root, '*.grd') + grdps = list_files_in_repository(repo_root, '*.grdp') + + print('Found %d grds, %d grdps in the repo.' % (len(grds), len(grdps))) + # Make sure we can parse all .grd files in the source tree. Grd files are + # parsed via the file path. + for grd in grds: + # This file is intentionally missing an include, skip it. + if grd == os.path.join('tools', 'translation', 'testdata', 'internal.grd'): + continue + path = os.path.join(repo_root, grd) + grd_helper.GetGrdMessages(path, os.path.dirname(path)) + + # Make sure we can parse all .grdp files in the source tree. + # Grdp files are parsed using file contents instead of path. + for grdp in grdps: + path = os.path.join(repo_root, grdp) + # Parse grdp files using file contents. + contents = read_file_as_text(path) + grd_helper.GetGrdpMessagesFromString(contents) + + print('Successfully parsed all .grd and .grdp files in the repo.') + + # Additional check for translateable grds. Translateable grds are a subset + # of all grds so this checks some files twice, but it exercises the + # get_translatable_grds() path and also doesn't need to skip internal.grd. + TRANSLATION_EXPECTATIONS_PATH = os.path.join(repo_root, 'tools', + 'gritsettings', + 'translation_expectations.pyl') + translateable_grds = translation_helper.get_translatable_grds( + repo_root, grds, TRANSLATION_EXPECTATIONS_PATH) + print('Found %d translateable .grd files in translation expectations.' % + len(translateable_grds)) + for grd in translateable_grds: + path = os.path.join(repo_root, grd.path) + grd_helper.GetGrdMessages(path, os.path.dirname(path)) + print('Successfully parsed all translateable_grds .grd files in translation ' + 'expectations.') + print('DONE') + + +if __name__ == '__main__': + Run()
diff --git a/ui/accessibility/accessibility_switches.h b/ui/accessibility/accessibility_switches.h index e34013a..aacf314 100644 --- a/ui/accessibility/accessibility_switches.h +++ b/ui/accessibility/accessibility_switches.h
@@ -25,7 +25,7 @@ // Returns true if experimental accessibility language detection is enabled. AX_EXPORT bool IsExperimentalAccessibilityLanguageDetectionEnabled(); -// Returns true if experimental accessibility switch access text is enabled. +// Returns true if experimental accessibility Switch Access text is enabled. AX_EXPORT bool IsExperimentalAccessibilitySwitchAccessTextEnabled(); #if defined(OS_WIN)
diff --git a/ui/base/test/scoped_fake_nswindow_focus.mm b/ui/base/test/scoped_fake_nswindow_focus.mm index 91bd4b55..00b340af 100644 --- a/ui/base/test/scoped_fake_nswindow_focus.mm +++ b/ui/base/test/scoped_fake_nswindow_focus.mm
@@ -14,7 +14,7 @@ namespace { NSWindow* g_fake_focused_window = nil; -IMP g_order_out_impl_ = nullptr; +base::mac::ScopedObjCClassSwizzler* g_order_out_swizzler = nullptr; void SetFocus(NSWindow* window) { g_fake_focused_window = window; @@ -74,7 +74,7 @@ NSWindow* selfAsWindow = base::mac::ObjCCastStrict<NSWindow>(self); if (selfAsWindow == g_fake_focused_window) ClearFocus(); - g_order_out_impl_(self, _cmd, sender); + g_order_out_swizzler->InvokeOriginal<void, id>(self, _cmd, sender); } - (void)resignKeyWindow { @@ -117,10 +117,11 @@ new ScopedObjCClassSwizzler([NSWindow class], [FakeNSWindowFocusDonor class], @selector(orderOut:))) { - g_order_out_impl_ = order_out_swizzler_->GetOriginalImplementation(); + g_order_out_swizzler = order_out_swizzler_.get(); } ScopedFakeNSWindowFocus::~ScopedFakeNSWindowFocus() { + g_order_out_swizzler = nullptr; ClearFocus(); }
diff --git a/ui/base/test/scoped_fake_nswindow_fullscreen.mm b/ui/base/test/scoped_fake_nswindow_fullscreen.mm index 3ad4b694..f09aa141 100644 --- a/ui/base/test/scoped_fake_nswindow_fullscreen.mm +++ b/ui/base/test/scoped_fake_nswindow_fullscreen.mm
@@ -61,14 +61,14 @@ } } - IMP SetStyleMaskImplementation() { - return set_style_mask_swizzler_.GetOriginalImplementation(); + void OriginalSetStyleMask(id receiver, SEL selector, NSUInteger mask) { + return set_style_mask_swizzler_.InvokeOriginal<void, NSUInteger>( + receiver, selector, mask); } NSUInteger StyleMaskForWindow(NSWindow* window) { - NSUInteger actual_style_mask = reinterpret_cast<NSUInteger>( - style_mask_swizzler_.GetOriginalImplementation()(window, - @selector(styleMask))); + auto actual_style_mask = style_mask_swizzler_.InvokeOriginal<NSUInteger>( + window, @selector(styleMask)); if (window_ != window || !style_as_fullscreen_) return actual_style_mask; @@ -233,7 +233,7 @@ NOTREACHED() << "Can't set NSFullScreenWindowMask while faking fullscreen."; } newMask &= ~NSFullScreenWindowMask; - g_fake_fullscreen_impl->SetStyleMaskImplementation()(self, _cmd, newMask); + g_fake_fullscreen_impl->OriginalSetStyleMask(self, _cmd, newMask); } @end
diff --git a/ui/color/color_mixer.cc b/ui/color/color_mixer.cc index f0d038bd..2069d5b 100644 --- a/ui/color/color_mixer.cc +++ b/ui/color/color_mixer.cc
@@ -4,8 +4,6 @@ #include "ui/color/color_mixer.h" -#include "base/containers/adapters.h" -#include "base/stl_util.h" #include "ui/color/color_recipe.h" #include "ui/gfx/color_palette.h" @@ -20,17 +18,16 @@ ColorMixer::~ColorMixer() = default; +ColorRecipe& ColorMixer::operator[](ColorId id) { + DCHECK_COLOR_ID_VALID(id); + return recipes_[id]; +} + void ColorMixer::AddSet(ColorSet&& set) { DCHECK(FindSetWithId(set.id) == sets_.cend()); sets_.push_front(std::move(set)); } -ColorRecipe& ColorMixer::AddRecipe(ColorId id) { - DCHECK_COLOR_ID_VALID(id); - DCHECK(!base::Contains(recipes_, id)); - return recipes_[id]; -} - SkColor ColorMixer::GetInputColor(ColorId id) const { DCHECK_COLOR_ID_VALID(id); for (const auto& set : sets_) {
diff --git a/ui/color/color_mixer.h b/ui/color/color_mixer.h index d5879487..899f894f5 100644 --- a/ui/color/color_mixer.h +++ b/ui/color/color_mixer.h
@@ -39,16 +39,14 @@ ColorMixer& operator=(ColorMixer&&) noexcept; ~ColorMixer(); + // Adds a recipe for |id| if it does not exist. + ColorRecipe& operator[](ColorId id); + // Adds |set| to |sets_|. |set| must not have the same ID as any previously // added sets, though it may contain colors with the same IDs as colors in // those sets; in such cases, the last-added set takes priority. void AddSet(ColorSet&& set); - // Adds a recipe for |id|, which must not already have an existing recipe. - // Returns a non-const ref to allow chaining calls to - // ColorRecipe::AddTransform(). - ColorRecipe& AddRecipe(ColorId id); - // Returns the input color for |id|. First searches all |sets_| in reverse // order; if not found, asks the previous mixer for the result color. If // there is no previous mixer, returns gfx::kPlaceholderColor.
diff --git a/ui/color/color_mixer_unittest.cc b/ui/color/color_mixer_unittest.cc index f2ad20f1..4babf86 100644 --- a/ui/color/color_mixer_unittest.cc +++ b/ui/color/color_mixer_unittest.cc
@@ -27,10 +27,10 @@ EXPECT_EQ(SK_ColorGREEN, mixer.GetResultColor(kColorTest0)); } -// Tests that the recipe returned by AddRecipe() is respected by the mixer. -TEST(ColorMixerTest, AddRecipe) { +// Tests that the recipe returned by operator[] is respected by the mixer. +TEST(ColorMixerTest, AccessOperator) { ColorMixer mixer; - mixer.AddRecipe(kColorTest0).AddTransform(FromColor(SK_ColorGREEN)); + mixer[kColorTest0].AddTransform(FromColor(SK_ColorGREEN)); EXPECT_EQ(SK_ColorGREEN, mixer.GetResultColor(kColorTest0)); } @@ -86,8 +86,8 @@ TEST(ColorMixerTest, GetInputColorIgnoresRecipe) { ColorMixer mixer; mixer.AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); - mixer.AddRecipe(kColorTest0) - .AddTransform(GetColorWithMaxContrast(FromTransformInput())); + mixer[kColorTest0].AddTransform( + GetColorWithMaxContrast(FromTransformInput())); EXPECT_EQ(SK_ColorGREEN, mixer.GetInputColor(kColorTest0)); } @@ -97,8 +97,8 @@ TEST(ColorMixerTest, GetInputColorRespectsRecipePreviousMixer) { ColorMixer mixer0; mixer0.AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); - mixer0.AddRecipe(kColorTest0) - .AddTransform(GetColorWithMaxContrast(FromTransformInput())); + mixer0[kColorTest0].AddTransform( + GetColorWithMaxContrast(FromTransformInput())); ColorMixer mixer1(&mixer0); mixer1.AddSet({kColorSetTest1, {{kColorTest1, SK_ColorRED}}}); EXPECT_EQ(color_utils::GetColorWithMaxContrast(SK_ColorGREEN), @@ -169,8 +169,8 @@ TEST(ColorMixerTest, GetOriginalColorFromSetIgnoresRecipe) { ColorMixer mixer; mixer.AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); - mixer.AddRecipe(kColorTest0) - .AddTransform(GetColorWithMaxContrast(FromTransformInput())); + mixer[kColorTest0].AddTransform( + GetColorWithMaxContrast(FromTransformInput())); EXPECT_EQ(SK_ColorGREEN, mixer.GetOriginalColorFromSet(kColorTest0, kColorSetTest0)); } @@ -181,8 +181,8 @@ TEST(ColorMixerTest, GetOriginalColorFromSetIgnoresRecipePreviousMixer) { ColorMixer mixer0; mixer0.AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); - mixer0.AddRecipe(kColorTest0) - .AddTransform(GetColorWithMaxContrast(FromTransformInput())); + mixer0[kColorTest0].AddTransform( + GetColorWithMaxContrast(FromTransformInput())); ColorMixer mixer1(&mixer0); mixer1.AddSet({kColorSetTest1, {{kColorTest1, SK_ColorRED}}}); EXPECT_EQ(SK_ColorGREEN, @@ -207,9 +207,9 @@ // initial value for its requested color. TEST(ColorMixerTest, GetResultColorNoSet) { ColorMixer mixer; - mixer.AddRecipe(kColorTest0).AddTransform(FromColor(SK_ColorGREEN)); - mixer.AddRecipe(kColorTest1) - .AddTransform(GetColorWithMaxContrast(FromTransformInput())); + mixer[kColorTest0].AddTransform(FromColor(SK_ColorGREEN)); + mixer[kColorTest1].AddTransform( + GetColorWithMaxContrast(FromTransformInput())); EXPECT_EQ(SK_ColorGREEN, mixer.GetResultColor(kColorTest0)); EXPECT_NE(gfx::kPlaceholderColor, mixer.GetResultColor(kColorTest1)); } @@ -220,8 +220,8 @@ ColorMixer mixer; mixer.AddSet({kColorSetTest0, {{kColorTest0, SK_ColorWHITE}, {kColorTest1, SK_ColorBLACK}}}); - mixer.AddRecipe(kColorTest0).AddTransform(FromColor(SK_ColorGREEN)); - mixer.AddRecipe(kColorTest1).AddTransform(FromColor(SK_ColorGREEN)); + mixer[kColorTest0].AddTransform(FromColor(SK_ColorGREEN)); + mixer[kColorTest1].AddTransform(FromColor(SK_ColorGREEN)); EXPECT_EQ(SK_ColorGREEN, mixer.GetResultColor(kColorTest0)); EXPECT_EQ(SK_ColorGREEN, mixer.GetResultColor(kColorTest1)); } @@ -231,14 +231,12 @@ TEST(ColorMixerTest, GetResultColorChained) { ColorMixer mixer; mixer.AddSet({kColorSetTest0, {{kColorTest1, SK_ColorWHITE}}}); - mixer.AddRecipe(kColorTest0).AddTransform(FromColor(gfx::kGoogleBlue050)); - mixer.AddRecipe(kColorTest1) - .AddTransform(BlendTowardMaxContrast( - GetColorWithMaxContrast(FromTransformInput()), 0x29)); - mixer.AddRecipe(kColorTest2) - .AddTransform(BlendForMinContrast(FromColor(gfx::kGoogleBlue500), - FromResultColor(kColorTest1), - FromResultColor(kColorTest0))); + mixer[kColorTest0].AddTransform(FromColor(gfx::kGoogleBlue050)); + mixer[kColorTest1].AddTransform(BlendTowardMaxContrast( + GetColorWithMaxContrast(FromTransformInput()), 0x29)); + mixer[kColorTest2].AddTransform(BlendForMinContrast( + FromColor(gfx::kGoogleBlue500), FromResultColor(kColorTest1), + FromResultColor(kColorTest0))); EXPECT_EQ(SkColorSetRGB(0x89, 0xB3, 0xF8), mixer.GetResultColor(kColorTest2)); }
diff --git a/ui/color/color_provider.cc b/ui/color/color_provider.cc index d1d8d34..e9b34d4 100644 --- a/ui/color/color_provider.cc +++ b/ui/color/color_provider.cc
@@ -11,7 +11,7 @@ namespace ui { -ColorMixer* ColorProvider::AddMixer() { +ColorMixer& ColorProvider::AddMixer() { // Adding a mixer could change any of the result colors. cache_.clear(); @@ -20,7 +20,7 @@ // mixer for its result, and trust mixers to query each other back up the // chain as needed. mixers_.emplace_front(mixers_.empty() ? nullptr : &mixers_.front()); - return &mixers_.front(); + return mixers_.front(); } SkColor ColorProvider::GetColor(ColorId id, ColorVariant variant) const {
diff --git a/ui/color/color_provider.h b/ui/color/color_provider.h index b8a6a56..62347b8 100644 --- a/ui/color/color_provider.h +++ b/ui/color/color_provider.h
@@ -30,9 +30,9 @@ ColorProvider& operator=(const ColorProvider&) = delete; ~ColorProvider(); - // Adds a mixer to the end of the current color pipeline. Returns a pointer + // Adds a mixer to the end of the current color pipeline. Returns a reference // to the added mixer so callers can subsequently add sets and/or recipes. - ColorMixer* AddMixer(); + ColorMixer& AddMixer(); // Returns the result color for |id| by applying the effects of each mixer in // order. Returns gfx::kPlaceholderColor if no mixer knows how to construct
diff --git a/ui/color/color_provider_unittest.cc b/ui/color/color_provider_unittest.cc index c094c03..381faa3 100644 --- a/ui/color/color_provider_unittest.cc +++ b/ui/color/color_provider_unittest.cc
@@ -11,14 +11,6 @@ namespace ui { namespace { -// Tests that AddMixer() returns non-null pointers, implying addition was -// successful. (Other tests below will verify the mixers have an effect.) -TEST(ColorProviderTest, AddMixer) { - ColorProvider provider; - EXPECT_NE(nullptr, provider.AddMixer()); - EXPECT_NE(nullptr, provider.AddMixer()); -} - // Tests that when there are no mixers, GetColor() returns a placeholder value. TEST(ColorProviderTest, GetColorNoMixers) { EXPECT_EQ(gfx::kPlaceholderColor, ColorProvider().GetColor(kColorTest0)); @@ -28,7 +20,7 @@ // possible. TEST(ColorProviderTest, SingleMixer) { ColorProvider provider; - provider.AddMixer()->AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); + provider.AddMixer().AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); EXPECT_EQ(SK_ColorGREEN, provider.GetColor(kColorTest0)); EXPECT_EQ(gfx::kPlaceholderColor, provider.GetColor(kColorTest1)); } @@ -37,8 +29,8 @@ // use of both. TEST(ColorProviderTest, NonOverlappingMixers) { ColorProvider provider; - provider.AddMixer()->AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); - provider.AddMixer()->AddSet({kColorSetTest1, {{kColorTest1, SK_ColorRED}}}); + provider.AddMixer().AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); + provider.AddMixer().AddSet({kColorSetTest1, {{kColorTest1, SK_ColorRED}}}); EXPECT_EQ(SK_ColorGREEN, provider.GetColor(kColorTest0)); EXPECT_EQ(SK_ColorRED, provider.GetColor(kColorTest1)); } @@ -47,8 +39,8 @@ // added takes priority. TEST(ColorProviderTest, OverlappingMixers) { ColorProvider provider; - provider.AddMixer()->AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); - provider.AddMixer()->AddSet({kColorSetTest0, {{kColorTest0, SK_ColorRED}}}); + provider.AddMixer().AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); + provider.AddMixer().AddSet({kColorSetTest0, {{kColorTest0, SK_ColorRED}}}); EXPECT_EQ(SK_ColorRED, provider.GetColor(kColorTest0)); } @@ -56,10 +48,10 @@ // This attempts to verify that nothing is badly wrong with color caching. TEST(ColorProviderTest, Caching) { ColorProvider provider; - provider.AddMixer()->AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); + provider.AddMixer().AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}}}); EXPECT_EQ(SK_ColorGREEN, provider.GetColor(kColorTest0)); EXPECT_EQ(SK_ColorGREEN, provider.GetColor(kColorTest0)); - provider.AddMixer()->AddSet({kColorSetTest0, {{kColorTest0, SK_ColorRED}}}); + provider.AddMixer().AddSet({kColorSetTest0, {{kColorTest0, SK_ColorRED}}}); EXPECT_EQ(SK_ColorRED, provider.GetColor(kColorTest0)); }
diff --git a/ui/color/color_transform_unittest.cc b/ui/color/color_transform_unittest.cc index f8cc4a3..4a0b1db 100644 --- a/ui/color/color_transform_unittest.cc +++ b/ui/color/color_transform_unittest.cc
@@ -156,7 +156,7 @@ ColorMixer mixer; mixer.AddSet({kColorSetTest0, {{kColorTest0, SK_ColorGREEN}, {kColorTest1, kTest1Color}}}); - mixer.AddRecipe(kColorTest0).AddTransform(FromInputColor(kColorTest1)); + mixer[kColorTest0].AddTransform(FromInputColor(kColorTest1)); const auto verify_color = [&](SkColor input) { EXPECT_EQ(kTest1Color, transform.Run(input, mixer)); };
diff --git a/ui/color/win/native_color_mixer.cc b/ui/color/win/native_color_mixer.cc index 798c087..0c78d323 100644 --- a/ui/color/win/native_color_mixer.cc +++ b/ui/color/win/native_color_mixer.cc
@@ -21,7 +21,7 @@ // reverse-engineering current Windows behavior. Or maybe the union of all // these. #define MAP(chrome, native) {chrome, color_utils::GetSysSkColor(native)} - provider->AddMixer()->AddSet( + provider->AddMixer().AddSet( {kColorSetNative, { MAP(kColorNative3dDkShadow, COLOR_3DDKSHADOW),
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc index 4c8d4ee1..335aa2b 100644 --- a/ui/views/controls/label.cc +++ b/ui/views/controls/label.cc
@@ -460,7 +460,8 @@ if (!GetVisible() && collapse_when_hidden_) return gfx::Size(); - gfx::Size size(0, font_list().GetHeight()); + // Always reserve vertical space for at least one line. + gfx::Size size(0, std::max(font_list().GetHeight(), GetLineHeight())); if (elide_behavior_ == gfx::ELIDE_HEAD || elide_behavior_ == gfx::ELIDE_MIDDLE || elide_behavior_ == gfx::ELIDE_TAIL || @@ -479,6 +480,7 @@ size.SetToMin(GetTextSize()); } } + size.Enlarge(GetInsets().width(), GetInsets().height()); return size; }
diff --git a/ui/views/controls/label_unittest.cc b/ui/views/controls/label_unittest.cc index ff8e63d..518180f9 100644 --- a/ui/views/controls/label_unittest.cc +++ b/ui/views/controls/label_unittest.cc
@@ -326,6 +326,54 @@ EXPECT_EQ(was_rtl, base::i18n::IsRTL()); } +TEST_F(LabelTest, MinimumSizeRespectsLineHeight) { + base::string16 text(ASCIIToUTF16("This is example text.")); + label()->SetText(text); + + const gfx::Size minimum_size = label()->GetMinimumSize(); + const int expected_height = minimum_size.height() + 10; + label()->SetLineHeight(expected_height); + EXPECT_EQ(expected_height, label()->GetMinimumSize().height()); +} + +TEST_F(LabelTest, MinimumSizeRespectsLineHeightMultiline) { + base::string16 text(ASCIIToUTF16("This is example text.")); + label()->SetText(text); + label()->SetMultiLine(true); + + const gfx::Size minimum_size = label()->GetMinimumSize(); + const int expected_height = minimum_size.height() + 10; + label()->SetLineHeight(expected_height); + EXPECT_EQ(expected_height, label()->GetMinimumSize().height()); +} + +TEST_F(LabelTest, MinimumSizeRespectsLineHeightWithInsets) { + base::string16 text(ASCIIToUTF16("This is example text.")); + label()->SetText(text); + + const gfx::Size minimum_size = label()->GetMinimumSize(); + int expected_height = minimum_size.height() + 10; + label()->SetLineHeight(expected_height); + constexpr gfx::Insets kInsets{2, 3, 4, 5}; + expected_height += kInsets.height(); + label()->SetBorder(CreateEmptyBorder(kInsets)); + EXPECT_EQ(expected_height, label()->GetMinimumSize().height()); +} + +TEST_F(LabelTest, MinimumSizeRespectsLineHeightMultilineWithInsets) { + base::string16 text(ASCIIToUTF16("This is example text.")); + label()->SetText(text); + label()->SetMultiLine(true); + + const gfx::Size minimum_size = label()->GetMinimumSize(); + int expected_height = minimum_size.height() + 10; + label()->SetLineHeight(expected_height); + constexpr gfx::Insets kInsets{2, 3, 4, 5}; + expected_height += kInsets.height(); + label()->SetBorder(CreateEmptyBorder(kInsets)); + EXPECT_EQ(expected_height, label()->GetMinimumSize().height()); +} + TEST_F(LabelTest, ElideBehavior) { base::string16 text(ASCIIToUTF16("This is example text.")); label()->SetText(text);
diff --git a/ui/views/test/event_generator_delegate_mac.mm b/ui/views/test/event_generator_delegate_mac.mm index dec0b10..5788e69 100644 --- a/ui/views/test/event_generator_delegate_mac.mm +++ b/ui/views/test/event_generator_delegate_mac.mm
@@ -252,8 +252,8 @@ static EventGeneratorDelegateMac* instance() { return instance_; } - IMP CurrentEventMethod() { - return swizzle_current_event_->GetOriginalImplementation(); + NSEvent* OriginalCurrentEvent(id receiver, SEL selector) { + return swizzle_current_event_->InvokeOriginal<NSEvent*>(receiver, selector); } NSWindow* window() { return window_.get(); } @@ -634,8 +634,8 @@ return g_current_event; // Find the original implementation and invoke it. - IMP original = EventGeneratorDelegateMac::instance()->CurrentEventMethod(); - return original(self, _cmd); + return EventGeneratorDelegateMac::instance()->OriginalCurrentEvent(self, + _cmd); } @end
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 82df06d7..58e85500 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -1139,8 +1139,8 @@ ~ScopedSwizzleWaiter() { instance_ = nullptr; } - static IMP GetMethodAndMarkCalled() { - return instance_->GetMethodInternal(); + static void OriginalSetWindowStateForEnd(id receiver, SEL method) { + return instance_->CallMethodInternal(receiver, method); } void WaitForMethod() { @@ -1158,12 +1158,12 @@ bool method_called() const { return method_called_; } private: - IMP GetMethodInternal() { + void CallMethodInternal(id receiver, SEL selector) { DCHECK(!method_called_); method_called_ = true; if (run_loop_) run_loop_->Quit(); - return swizzler_.GetOriginalImplementation(); + swizzler_.InvokeOriginal<void>(receiver, selector); } static ScopedSwizzleWaiter* instance_; @@ -2475,7 +2475,7 @@ @implementation TestStopAnimationWaiter - (void)setWindowStateForEnd { - views::test::ScopedSwizzleWaiter::GetMethodAndMarkCalled()(self, _cmd); + views::test::ScopedSwizzleWaiter::OriginalSetWindowStateForEnd(self, _cmd); } @end
diff --git a/ui/webui/resources/css/tree.css b/ui/webui/resources/css/tree.css index 6454b96..d0f7939c 100644 --- a/ui/webui/resources/css/tree.css +++ b/ui/webui/resources/css/tree.css
@@ -171,3 +171,15 @@ margin: -2px -3px -2px -8px; padding: 1px 1px 1px 7px; } + +@media(forced-colors) { + .tree-row[selected], + .tree-row:hover, + .tree-row[selected]:hover, + tree:focus .tree-row[selected] { + background-color: Highlight; + background-image: none; + color: HighlightText; + forced-color-adjust: none; + } +}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/TabCallbackProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/TabCallbackProxy.java index 1ece19a..238cf84 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/TabCallbackProxy.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/TabCallbackProxy.java
@@ -36,6 +36,11 @@ mClient.visibleUrlChanged(string); } + @CalledByNative + private void onRenderProcessGone() throws RemoteException { + mClient.onRenderProcessGone(); + } + @NativeMethods interface Natives { long createTabCallbackProxy(TabCallbackProxy proxy, long tab);
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl index 793f48cd..70812c9b 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl +++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl
@@ -12,4 +12,6 @@ void visibleUrlChanged(in String url) = 0; void onNewTab(in int tabId, in int mode) = 1; + + void onRenderProcessGone() = 2; }
diff --git a/weblayer/browser/ssl_browsertest.cc b/weblayer/browser/ssl_browsertest.cc index 1550290..7627829 100644 --- a/weblayer/browser/ssl_browsertest.cc +++ b/weblayer/browser/ssl_browsertest.cc
@@ -51,13 +51,9 @@ EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); } - void NavigateToPageWithSslError() { - // Now do a navigation that should result in an SSL error. - GURL url_with_mismatched_cert = - https_server_mismatched_->GetURL("/simple_page.html"); - - NavigateAndWaitForFailure(url_with_mismatched_cert, shell()); - + void NavigateToPageWithSslErrorExpectBlocked() { + // Do a navigation that should result in an SSL error. + NavigateAndWaitForFailure(bad_ssl_url(), shell()); // First check that there *is* an interstitial. ASSERT_TRUE(IsShowingSecurityInterstitial(shell()->tab())); @@ -69,7 +65,37 @@ // ssl_browsertest.cc's CheckAuthenticationBrokenState() function. } + void NavigateToPageWithSslErrorExpectNotBlocked() { + NavigateAndWaitForCompletion(bad_ssl_url(), shell()); + EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); + + // TODO(blundell): Check the security state once security state is available + // via the public WebLayer API, following the example of //chrome's + // ssl_browsertest.cc's CheckAuthenticationBrokenState() function. + } + + void InteractWithBlockingPage(bool proceed) { + TestNavigationObserver navigation_observer( + proceed ? bad_ssl_url() : ok_url(), + TestNavigationObserver::NavigationEvent::Completion, shell()); + ExecuteScript(shell(), + "window.certificateErrorPageController." + + std::string(proceed ? "proceed" : "dontProceed") + "();", + false /*use_separate_isolate*/); + navigation_observer.Wait(); + EXPECT_FALSE(IsShowingSSLInterstitial(shell()->tab())); + } + + void NavigateToOtherOkPage() { + NavigateAndWaitForCompletion(https_server_->GetURL("/simple_page2.html"), + shell()); + EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); + } + GURL ok_url() { return https_server_->GetURL("/simple_page.html"); } + GURL bad_ssl_url() { + return https_server_mismatched_->GetURL("/simple_page.html"); + } protected: std::unique_ptr<net::EmbeddedTestServer> https_server_; @@ -82,30 +108,45 @@ // Tests clicking "take me back" on the interstitial page. IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBack) { NavigateToOkPage(); - NavigateToPageWithSslError(); + NavigateToPageWithSslErrorExpectBlocked(); // Click "Take me back". - TestNavigationObserver navigation_observer( - ok_url(), TestNavigationObserver::NavigationEvent::Completion, shell()); - ExecuteScript(shell(), "window.certificateErrorPageController.dontProceed();", - false /*use_separate_isolate*/); - navigation_observer.Wait(); - EXPECT_FALSE(IsShowingSSLInterstitial(shell()->tab())); + InteractWithBlockingPage(false /*proceed*/); // Check that it's possible to navigate to a new page. - NavigateAndWaitForCompletion(https_server_->GetURL("/simple_page2.html"), - shell()); - EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); + NavigateToOtherOkPage(); + + // Navigate to the bad SSL page again, an interstitial shows again (in + // contrast to what would happen had the user chosen to proceed). + NavigateToPageWithSslErrorExpectBlocked(); +} + +// Tests clicking proceed link on the interstitial page. This is a PRE_ test +// because it also acts as setup for the test below which verifies the behavior +// across restarts. +IN_PROC_BROWSER_TEST_F(SSLBrowserTest, PRE_Proceed) { + NavigateToOkPage(); + NavigateToPageWithSslErrorExpectBlocked(); + InteractWithBlockingPage(true /*proceed*/); + + // Go back to an OK page, then try to navigate again. The "Proceed" decision + // should be saved, so no interstitial is shown this time. + NavigateToOkPage(); + NavigateToPageWithSslErrorExpectNotBlocked(); +} + +// The proceed decision is not perpetuated across WebLayer sessions, i.e. +// WebLayer will block again when navigating to the same bad page that was +// previously proceeded through. +IN_PROC_BROWSER_TEST_F(SSLBrowserTest, Proceed) { + NavigateToPageWithSslErrorExpectBlocked(); } // Tests navigating away from the interstitial page. IN_PROC_BROWSER_TEST_F(SSLBrowserTest, NavigateAway) { NavigateToOkPage(); - NavigateToPageWithSslError(); - - NavigateAndWaitForCompletion(https_server_->GetURL("/simple_page2.html"), - shell()); - EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); + NavigateToPageWithSslErrorExpectBlocked(); + NavigateToOtherOkPage(); } } // namespace weblayer
diff --git a/weblayer/browser/tab_callback_proxy.cc b/weblayer/browser/tab_callback_proxy.cc index a9ce68e..e83eed5 100644 --- a/weblayer/browser/tab_callback_proxy.cc +++ b/weblayer/browser/tab_callback_proxy.cc
@@ -31,6 +31,11 @@ Java_TabCallbackProxy_visibleUrlChanged(env, java_observer_, jstring_url); } +void TabCallbackProxy::OnRenderProcessGone() { + Java_TabCallbackProxy_onRenderProcessGone(AttachCurrentThread(), + java_observer_); +} + static jlong JNI_TabCallbackProxy_CreateTabCallbackProxy( JNIEnv* env, const base::android::JavaParamRef<jobject>& proxy,
diff --git a/weblayer/browser/tab_callback_proxy.h b/weblayer/browser/tab_callback_proxy.h index b4a08e2..89bda15 100644 --- a/weblayer/browser/tab_callback_proxy.h +++ b/weblayer/browser/tab_callback_proxy.h
@@ -25,6 +25,8 @@ // BrowserObserver: void DisplayedUrlChanged(const GURL& url) override; + void OnRenderProcessGone() override; + private: Tab* tab_; base::android::ScopedJavaGlobalRef<jobject> java_observer_;
diff --git a/weblayer/browser/tab_impl.cc b/weblayer/browser/tab_impl.cc index b43c9b5..107dfe2 100644 --- a/weblayer/browser/tab_impl.cc +++ b/weblayer/browser/tab_impl.cc
@@ -362,6 +362,12 @@ #endif } +void TabImpl::RenderProcessGone(base::TerminationStatus status) { + for (auto& observer : observers_) { + observer.OnRenderProcessGone(); + } +} + void TabImpl::OnExitFullscreen() { // If |processing_enter_fullscreen_| is true, it means the callback is being // called while processing EnterFullscreenModeForTab(). WebContents doesn't
diff --git a/weblayer/browser/tab_impl.h b/weblayer/browser/tab_impl.h index ce7c4ae..bbbf74e 100644 --- a/weblayer/browser/tab_impl.h +++ b/weblayer/browser/tab_impl.h
@@ -125,6 +125,7 @@ // content::WebContentsObserver: void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; + void RenderProcessGone(base::TerminationStatus status) override; // Called from closure supplied to delegate to exit fullscreen. void OnExitFullscreen();
diff --git a/weblayer/public/java/org/chromium/weblayer/Tab.java b/weblayer/public/java/org/chromium/weblayer/Tab.java index f9f5a0c..0d4c4ef5 100644 --- a/weblayer/public/java/org/chromium/weblayer/Tab.java +++ b/weblayer/public/java/org/chromium/weblayer/Tab.java
@@ -224,6 +224,13 @@ assert tab.getBrowser() == getBrowser(); mNewTabCallback.onNewTab(tab, mode); } + + @Override + public void onRenderProcessGone() { + for (TabCallback callback : mCallbacks) { + callback.onRenderProcessGone(); + } + } } private static final class DownloadCallbackClientImpl extends IDownloadCallbackClient.Stub {
diff --git a/weblayer/public/java/org/chromium/weblayer/TabCallback.java b/weblayer/public/java/org/chromium/weblayer/TabCallback.java index 045b9e3..c48ba288 100644 --- a/weblayer/public/java/org/chromium/weblayer/TabCallback.java +++ b/weblayer/public/java/org/chromium/weblayer/TabCallback.java
@@ -18,4 +18,10 @@ * @param url The new user-visible url. */ public void onVisibleUrlChanged(@NonNull Uri url) {} + + /** + * Triggered when the render process dies, either due to crash or killed by the system to + * reclaim memory. + */ + public void onRenderProcessGone() {} }
diff --git a/weblayer/public/tab_observer.h b/weblayer/public/tab_observer.h index 2d0cd0b5..a9f5c4a 100644 --- a/weblayer/public/tab_observer.h +++ b/weblayer/public/tab_observer.h
@@ -14,6 +14,10 @@ // The URL bar should be updated to |url|. virtual void DisplayedUrlChanged(const GURL& url) {} + // Triggered when the render process dies, either due to crash or killed by the system to + // reclaim memory. + virtual void OnRenderProcessGone() {} + protected: virtual ~TabObserver() {} };
diff --git a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/TabCallbackTest.java b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/TabCallbackTest.java index 411e266d..0d9909b 100644 --- a/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/TabCallbackTest.java +++ b/weblayer/shell/android/javatests/src/org/chromium/weblayer/test/TabCallbackTest.java
@@ -12,15 +12,18 @@ import org.junit.runner.RunWith; import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.util.CallbackHelper; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.weblayer.Tab; import org.chromium.weblayer.TabCallback; import org.chromium.weblayer.shell.InstrumentationActivity; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.TimeoutException; /** * Tests that TabCallback methods are invoked as expected. @@ -71,14 +74,33 @@ String startupUrl = "about:blank"; InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(startupUrl); - Callback calllback = new Callback(); + Callback callback = new Callback(); TestThreadUtils.runOnUiThreadBlocking( - () -> { activity.getTab().registerTabCallback(calllback); }); + () -> { activity.getTab().registerTabCallback(callback); }); String url = "data:text,foo"; mActivityTestRule.navigateAndWait(url); /* Verify that the visible URL changes to the target. */ - calllback.visibleUrlChangedCallback.waitUntilValueObserved(url); + callback.visibleUrlChangedCallback.waitUntilValueObserved(url); + } + + @Test + @SmallTest + public void testOnRenderProcessGone() throws TimeoutException { + InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl("about:blank"); + CallbackHelper callbackHelper = new CallbackHelper(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + Tab tab = activity.getTab(); + TabCallback callback = new TabCallback() { + @Override + public void onRenderProcessGone() { + callbackHelper.notifyCalled(); + } + }; + tab.registerTabCallback(callback); + tab.getNavigationController().navigate(Uri.parse("chrome://crash")); + }); + callbackHelper.waitForFirst(); } }