diff --git a/.gitignore b/.gitignore index c75691e2..f6164b32 100644 --- a/.gitignore +++ b/.gitignore
@@ -295,6 +295,7 @@ /tools/metrics/actions/actions.old.xml /tools/metrics/histograms/histograms.before.pretty-print.xml /tools/metrics/histograms/histograms_xml/*.before.pretty-print.xml +/tools/metrics/histograms/histograms_xml/*/*.before.pretty-print.xml /tools/metrics/histograms/enums.before.pretty-print.xml /tools/page_cycler/acid3 /tools/reclient
diff --git a/DEPS b/DEPS index 7b9045e..334a5d8 100644 --- a/DEPS +++ b/DEPS
@@ -204,11 +204,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': 'c0c5106bd4d4f5c0142221109563eee45663eef5', + 'skia_revision': 'fa8d6915cbbf8cc7f6bc11c2c6bb7eaa36c2b5df', # 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': '04e154e4ca48094b482c0f1d77803987ec7b7cc6', + 'v8_revision': 'ab473c140fe5b583fe97ecb319840f23168f425a', # 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. @@ -279,7 +279,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '63989d27ead708330f28ebce558f547cee3e4300', + 'devtools_frontend_revision': 'b917ab64e84b7b91b925c1fc7c187e95b6602085', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -331,7 +331,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '10cb17e079e14f4f9a1bdaea9b46b343c82c4679', + 'dawn_revision': 'ab5821d0166feabf7690b7d2399ad36870501e72', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -370,7 +370,7 @@ 'ukey2_revision': '0275885d8e6038c39b8a8ca55e75d1d4d1727f47', # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'tint_revision': '76d12f0f5a330e613a068059a19915182144069b', + 'tint_revision': '00b77a80ab137229b2024fcf0e98c5e38ffc05fd', # TODO(crbug.com/941824): The values below need to be kept in sync # between //DEPS and //buildtools/DEPS, so if you're updating one, @@ -923,7 +923,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '968b1fe7d7cb848e250ffb62e27f547450f5b9e9', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '079a95bc72408f034a8ffbcb1ae70b54ef155aa0', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1545,7 +1545,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '3c2fe3888658d82b47ca831d59a2e07579619c2d', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '31d3b217d3b5c9e98559bb0ef9612659b36e88e5', + Var('webrtc_git') + '/src.git' + '@' + 'ad70609509a98138cd6391828e4adafeb2f35b3d', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1617,7 +1617,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d472d834dbda0e46609e789bd5336f1e245e37e9', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1df52ed5909b6872b8d7a76269c0e6247d4a101d', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index a81d5c4..4f3456c 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -5214,3 +5214,115 @@ 'in a way that is not backward-compatible.', long_text=error)] return [] + +def CheckDeprecationOfPreferences(input_api, output_api): + """Removing a preference should come with a deprecation.""" + + def FilterFile(affected_file): + """Accept only .cc files and the like.""" + file_inclusion_pattern = [r'.+%s' % _IMPLEMENTATION_EXTENSIONS] + files_to_skip = (_EXCLUDED_PATHS + + _TEST_CODE_EXCLUDED_PATHS + + input_api.DEFAULT_FILES_TO_SKIP) + return input_api.FilterSourceFile( + affected_file, + files_to_check=file_inclusion_pattern, + files_to_skip=files_to_skip) + + def ModifiedLines(affected_file): + """Returns a list of tuples (line number, line text) of added and removed + lines. + + Deleted lines share the same line number as the previous line. + + This relies on the scm diff output describing each changed code section + with a line of the form + + ^@@ <old line num>,<old size> <new line num>,<new size> @@$ + """ + line_num = 0 + modified_lines = [] + for line in affected_file.GenerateScmDiff().splitlines(): + # Extract <new line num> of the patch fragment (see format above). + m = input_api.re.match(r'^@@ [0-9\,\+\-]+ \+([0-9]+)\,[0-9]+ @@', line) + if m: + line_num = int(m.groups(1)[0]) + continue + if ((line.startswith('+') and not line.startswith('++')) or + (line.startswith('-') and not line.startswith('--'))): + modified_lines.append((line_num, line)) + + if not line.startswith('-'): + line_num += 1 + return modified_lines + + def FindLineWith(lines, needle): + """Returns the line number (i.e. index + 1) in `lines` containing `needle`. + + If 0 or >1 lines contain `needle`, -1 is returned. + """ + matching_line_numbers = [ + # + 1 for 1-based counting of line numbers. + i + 1 for i, line + in enumerate(lines) + if needle in line] + return matching_line_numbers[0] if len(matching_line_numbers) == 1 else -1 + + def ModifiedPrefMigration(affected_file): + """Returns whether the MigrateObsolete.*Pref functions were modified.""" + # Determine first and last lines of MigrateObsolete.*Pref functions. + new_contents = affected_file.NewContents(); + range_1 = ( + FindLineWith(new_contents, 'BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS'), + FindLineWith(new_contents, 'END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS')) + range_2 = ( + FindLineWith(new_contents, 'BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS'), + FindLineWith(new_contents, 'END_MIGRATE_OBSOLETE_PROFILE_PREFS')) + if (-1 in range_1 + range_2): + raise Exception( + 'Broken .*MIGRATE_OBSOLETE_.*_PREFS markers in browser_prefs.cc.') + + # Check whether any of the modified lines are part of the + # MigrateObsolete.*Pref functions. + for line_nr, line in ModifiedLines(affected_file): + if (range_1[0] <= line_nr <= range_1[1] or + range_2[0] <= line_nr <= range_2[1]): + return True + return False + + register_pref_pattern = input_api.re.compile(r'Register.+Pref') + browser_prefs_file_pattern = input_api.re.compile( + r'chrome/browser/prefs/browser_prefs.cc') + + changes = input_api.AffectedFiles(include_deletes=True, + file_filter=FilterFile) + potential_problems = [] + for f in changes: + for line in f.GenerateScmDiff().splitlines(): + # Check deleted lines for pref registrations. + if (line.startswith('-') and not line.startswith('--') and + register_pref_pattern.search(line)): + potential_problems.append('%s: %s' % (f.LocalPath(), line)) + + if browser_prefs_file_pattern.search(f.LocalPath()): + # If the developer modified the MigrateObsolete.*Prefs() functions, we + # assume that they knew that they have to deprecate preferences and don't + # warn. + try: + if ModifiedPrefMigration(f): + return [] + except Exception as e: + return [output_api.PresubmitError(str(e))] + + if potential_problems: + return [output_api.PresubmitPromptWarning( + 'Discovered possible removal of preference registrations.\n\n' + 'Please make sure to properly deprecate preferences by clearing their\n' + 'value for a couple of milestones before finally removing the code.\n' + 'Otherwise data may stay in the preferences files forever. See\n' + 'Migrate*Prefs() in chrome/browser/prefs/browser_prefs.cc for examples.\n' + 'This may be a false positive warning (e.g. if you move preference\n' + 'registrations to a different place).\n', + potential_problems + )] + return []
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index 2dfa78a..3dbbb77b 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -3658,5 +3658,156 @@ self.assertEqual([], errors) +class CheckDeprecationOfPreferencesTest(unittest.TestCase): + # Test that a warning is generated if a preference registration is removed + # from a random file. + def testWarning(self): + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockAffectedFile( + 'foo.cc', + ['A', 'B'], + ['A', 'prefs->RegisterStringPref("foo", "default");', 'B'], + scm_diff='\n'.join([ + '--- foo.cc.old 2020-12-02 20:40:54.430676385 +0100', + '+++ foo.cc.new 2020-12-02 20:41:02.086700197 +0100', + '@@ -1,3 +1,2 @@', + ' A', + '-prefs->RegisterStringPref("foo", "default");', + ' B']), + action='M') + ] + mock_output_api = MockOutputApi() + errors = PRESUBMIT.CheckDeprecationOfPreferences(mock_input_api, + mock_output_api) + self.assertEqual(1, len(errors)) + self.assertTrue( + 'Discovered possible removal of preference registrations' in + errors[0].message) + + # Test that a warning is inhibited if the preference registration was moved + # to the deprecation functions in browser prefs. + def testNoWarningForMigration(self): + mock_input_api = MockInputApi() + mock_input_api.files = [ + # RegisterStringPref was removed from foo.cc. + MockAffectedFile( + 'foo.cc', + ['A', 'B'], + ['A', 'prefs->RegisterStringPref("foo", "default");', 'B'], + scm_diff='\n'.join([ + '--- foo.cc.old 2020-12-02 20:40:54.430676385 +0100', + '+++ foo.cc.new 2020-12-02 20:41:02.086700197 +0100', + '@@ -1,3 +1,2 @@', + ' A', + '-prefs->RegisterStringPref("foo", "default");', + ' B']), + action='M'), + # But the preference was properly migrated. + MockAffectedFile( + 'chrome/browser/prefs/browser_prefs.cc', + [ + '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS', + 'prefs->RegisterStringPref("foo", "default");', + '// END_MIGRATE_OBSOLETE_PROFILE_PREFS', + ], + [ + '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS', + '// END_MIGRATE_OBSOLETE_PROFILE_PREFS', + ], + scm_diff='\n'.join([ + '--- browser_prefs.cc.old 2020-12-02 20:51:40.812686731 +0100', + '+++ browser_prefs.cc.new 2020-12-02 20:52:02.936755539 +0100', + '@@ -2,3 +2,4 @@', + ' // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + ' // BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS', + '+prefs->RegisterStringPref("foo", "default");', + ' // END_MIGRATE_OBSOLETE_PROFILE_PREFS']), + action='M'), + ] + mock_output_api = MockOutputApi() + errors = PRESUBMIT.CheckDeprecationOfPreferences(mock_input_api, + mock_output_api) + self.assertEqual(0, len(errors)) + + # Test that a warning is NOT inhibited if the preference registration was + # moved to a place outside of the migration functions in browser_prefs.cc + def testWarningForImproperMigration(self): + mock_input_api = MockInputApi() + mock_input_api.files = [ + # RegisterStringPref was removed from foo.cc. + MockAffectedFile( + 'foo.cc', + ['A', 'B'], + ['A', 'prefs->RegisterStringPref("foo", "default");', 'B'], + scm_diff='\n'.join([ + '--- foo.cc.old 2020-12-02 20:40:54.430676385 +0100', + '+++ foo.cc.new 2020-12-02 20:41:02.086700197 +0100', + '@@ -1,3 +1,2 @@', + ' A', + '-prefs->RegisterStringPref("foo", "default");', + ' B']), + action='M'), + # The registration call was moved to a place in browser_prefs.cc that + # is outside the migration functions. + MockAffectedFile( + 'chrome/browser/prefs/browser_prefs.cc', + [ + 'prefs->RegisterStringPref("foo", "default");', + '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS', + '// END_MIGRATE_OBSOLETE_PROFILE_PREFS', + ], + [ + '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS', + '// END_MIGRATE_OBSOLETE_PROFILE_PREFS', + ], + scm_diff='\n'.join([ + '--- browser_prefs.cc.old 2020-12-02 20:51:40.812686731 +0100', + '+++ browser_prefs.cc.new 2020-12-02 20:52:02.936755539 +0100', + '@@ -1,2 +1,3 @@', + '+prefs->RegisterStringPref("foo", "default");', + ' // BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + ' // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS']), + action='M'), + ] + mock_output_api = MockOutputApi() + errors = PRESUBMIT.CheckDeprecationOfPreferences(mock_input_api, + mock_output_api) + self.assertEqual(1, len(errors)) + self.assertTrue( + 'Discovered possible removal of preference registrations' in + errors[0].message) + + # Check that the presubmit fails if a marker line in brower_prefs.cc is + # deleted. + def testDeletedMarkerRaisesError(self): + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockAffectedFile('chrome/browser/prefs/browser_prefs.cc', + [ + '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS', + '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS', + # The following line is deleted for this test + # '// END_MIGRATE_OBSOLETE_PROFILE_PREFS', + ]) + ] + mock_output_api = MockOutputApi() + errors = PRESUBMIT.CheckDeprecationOfPreferences(mock_input_api, + mock_output_api) + self.assertEqual(1, len(errors)) + self.assertEqual( + 'Broken .*MIGRATE_OBSOLETE_.*_PREFS markers in browser_prefs.cc.', + errors[0].message) + + if __name__ == '__main__': unittest.main()
diff --git a/PRESUBMIT_test_mocks.py b/PRESUBMIT_test_mocks.py index 0a9e5a5..f8143ae 100644 --- a/PRESUBMIT_test_mocks.py +++ b/PRESUBMIT_test_mocks.py
@@ -179,16 +179,21 @@ MockInputApi for presubmit unittests. """ - def __init__(self, local_path, new_contents, old_contents=None, action='A'): + def __init__(self, local_path, new_contents, old_contents=None, action='A', + scm_diff=None): self._local_path = local_path self._new_contents = new_contents self._changed_contents = [(i + 1, l) for i, l in enumerate(new_contents)] self._action = action - self._scm_diff = "--- /dev/null\n+++ %s\n@@ -0,0 +1,%d @@\n" % (local_path, - len(new_contents)) + if scm_diff: + self._scm_diff = scm_diff + else: + self._scm_diff = ( + "--- /dev/null\n+++ %s\n@@ -0,0 +1,%d @@\n" % + (local_path, len(new_contents))) + for l in new_contents: + self._scm_diff += "+%s\n" % l self._old_contents = old_contents - for l in new_contents: - self._scm_diff += "+%s\n" % l def Action(self): return self._action
diff --git a/ash/ash_prefs.cc b/ash/ash_prefs.cc index 4ffdb57..720ed04 100644 --- a/ash/ash_prefs.cc +++ b/ash/ash_prefs.cc
@@ -88,6 +88,9 @@ registry->RegisterBooleanPref( chromeos::prefs::kSuggestedContentEnabled, true, user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); + registry->RegisterBooleanPref( + prefs::kLiveCaptionEnabled, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); } }
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 2f3e670..70df28a 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -1701,6 +1701,17 @@ Mic jack </message> + <!-- Status tray Live Caption strings. --> + <message name="IDS_ASH_STATUS_TRAY_LIVE_CAPTION_TOGGLE_TOOLTIP" desc="The tooltip text used for the button in the status tray to toggle the Live Caption feature on or off."> + Toggle Live Caption. <ph name="STATE_TEXT">$1<ex>Live Caption is on.</ex></ph> + </message> + <message name="IDS_ASH_STATUS_TRAY_LIVE_CAPTION_ENABLED_STATE_TOOLTIP" desc="The tooltip text indicating the Live Caption feature is on."> + Live Caption is on. + </message> + <message name="IDS_ASH_STATUS_TRAY_LIVE_CAPTION_DISABLED_STATE_TOOLTIP" desc="The tooltip text indicating the Live Caption feature is off."> + Live Caption is off. + </message> + <message name="IDS_AURA_SET_DESKTOP_WALLPAPER" desc="The label used for change wallpaper in context menu"> Set wallpaper </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_LIVE_CAPTION_DISABLED_STATE_TOOLTIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_LIVE_CAPTION_DISABLED_STATE_TOOLTIP.png.sha1 new file mode 100644 index 0000000..35f1f85 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_LIVE_CAPTION_DISABLED_STATE_TOOLTIP.png.sha1
@@ -0,0 +1 @@ +22cea29cf438b1550a0c70d262e23977fbc7c970 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_LIVE_CAPTION_ENABLED_STATE_TOOLTIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_LIVE_CAPTION_ENABLED_STATE_TOOLTIP.png.sha1 new file mode 100644 index 0000000..168a6ea --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_LIVE_CAPTION_ENABLED_STATE_TOOLTIP.png.sha1
@@ -0,0 +1 @@ +83265cf1191c34a9015b0ac7baf743a75a06fb56 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_LIVE_CAPTION_TOGGLE_TOOLTIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_LIVE_CAPTION_TOGGLE_TOOLTIP.png.sha1 new file mode 100644 index 0000000..168a6ea --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_LIVE_CAPTION_TOGGLE_TOOLTIP.png.sha1
@@ -0,0 +1 @@ +83265cf1191c34a9015b0ac7baf743a75a06fb56 \ No newline at end of file
diff --git a/ash/clipboard/clipboard_history_menu_model_adapter.cc b/ash/clipboard/clipboard_history_menu_model_adapter.cc index 8cbe91be..d6acdff 100644 --- a/ash/clipboard/clipboard_history_menu_model_adapter.cc +++ b/ash/clipboard/clipboard_history_menu_model_adapter.cc
@@ -12,8 +12,6 @@ #include "base/metrics/histogram_macros.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/clipboard/clipboard.h" -#include "ui/base/data_transfer_policy/data_transfer_endpoint.h" -#include "ui/base/data_transfer_policy/data_transfer_policy_controller.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_base_types.h" #include "ui/gfx/geometry/rect.h" @@ -27,17 +25,6 @@ namespace ash { -namespace { -bool IsDataReadAllowed(const ui::DataTransferEndpoint* source, - const ui::DataTransferEndpoint* destination) { - ui::DataTransferPolicyController* policy_controller = - ui::DataTransferPolicyController::Get(); - if (!policy_controller) - return true; - return policy_controller->IsDataReadAllowed(source, destination); -} -} // namespace - // static std::unique_ptr<ClipboardHistoryMenuModelAdapter> ClipboardHistoryMenuModelAdapter::Create( @@ -74,14 +61,6 @@ /*notify_if_restricted=*/false); for (const auto& item : items) { model_->AddItem(command_id, base::string16()); - - // Enable or disable the command depending on whether its corresponding - // clipboard history item is allowed to read or not. - // This clipboard read isn't initiated by the user, that's why it shouldn't - // notify if the clipboard is restricted. - model_->SetEnabledAt(model_->GetIndexOfCommandId(command_id), - IsDataReadAllowed(item.data().source(), &data_dst)); - item_snapshots_.emplace(command_id, item); ++command_id; } @@ -274,34 +253,26 @@ SelectMenuItemWithCommandId(next_selected_item_command); } -base::Optional<int> -ClipboardHistoryMenuModelAdapter::CalculateSelectedCommandIdAfterDeletion( +int ClipboardHistoryMenuModelAdapter::CalculateSelectedCommandIdAfterDeletion( int command_id) const { // If the menu item view to be deleted is the last one, Cancel() // should be called so this function should not be hit. DCHECK_GT(item_snapshots_.size(), 1u); - auto start_item = item_snapshots_.find(command_id); - DCHECK(start_item != item_snapshots_.cend()); + auto item_to_delete = item_snapshots_.find(command_id); + DCHECK(item_to_delete != item_snapshots_.cend()); - // Search in the forward direction. - auto check_function = [this](const auto& key_value) -> bool { - return model_->IsEnabledAt(model_->GetIndexOfCommandId(key_value.first)); - }; - auto selectable_iter_forward = std::find_if( - std::next(start_item, 1), item_snapshots_.cend(), check_function); - if (selectable_iter_forward != item_snapshots_.cend()) - return selectable_iter_forward->first; + // Use the menu item right after the one to be deleted if any. Otherwise, + // select the previous one. - // If no selectable item is found, then search in the reverse direction. - auto selectable_iter_reverse = - std::find_if(std::make_reverse_iterator(start_item), - item_snapshots_.crend(), check_function); - if (selectable_iter_reverse != item_snapshots_.crend()) - return selectable_iter_reverse->first; + auto next_item_iter = item_to_delete; + ++next_item_iter; + if (next_item_iter != item_snapshots_.cend()) + return next_item_iter->first; - // No other selectable item, then returns the invalid id. - return base::nullopt; + auto previous_item_iter = item_to_delete; + --previous_item_iter; + return previous_item_iter->first; } void ClipboardHistoryMenuModelAdapter::RemoveItemView(int command_id) {
diff --git a/ash/clipboard/clipboard_history_menu_model_adapter.h b/ash/clipboard/clipboard_history_menu_model_adapter.h index 8b88d80..d995d20 100644 --- a/ash/clipboard/clipboard_history_menu_model_adapter.h +++ b/ash/clipboard/clipboard_history_menu_model_adapter.h
@@ -105,11 +105,9 @@ // `reverse` is true). void AdvancePseudoFocusFromSelectedItem(bool reverse); - // Returns the command id of the menu item to be selected if any after the - // menu item specified by `command_id` is deleted. If no menu item is - // selectable after deletion, an absent value is returned. - base::Optional<int> CalculateSelectedCommandIdAfterDeletion( - int command_id) const; + // Returns the command id of the menu item to be selected after the + // menu item specified by `command_id` is deleted. + int CalculateSelectedCommandIdAfterDeletion(int command_id) const; // Removes the item view specified by `command_id` from the root menu. void RemoveItemView(int command_id);
diff --git a/ash/clipboard/views/clipboard_history_bitmap_item_view.cc b/ash/clipboard/views/clipboard_history_bitmap_item_view.cc index 658b8d17..60c287a5 100644 --- a/ash/clipboard/views/clipboard_history_bitmap_item_view.cc +++ b/ash/clipboard/views/clipboard_history_bitmap_item_view.cc
@@ -19,7 +19,6 @@ #include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/image/image_skia.h" -#include "ui/gfx/image/image_skia_operations.h" #include "ui/strings/grit/ui_strings.h" #include "ui/views/controls/image_view.h" #include "ui/views/layout/box_layout.h" @@ -51,13 +50,11 @@ public: FadeImageView(const ClipboardHistoryItem* clipboard_history_item, const ClipboardHistoryResourceManager* resource_manager, - float opacity, base::RepeatingClosure update_callback) : RoundedImageView(ClipboardHistoryViews::kImageRoundedCornerRadius, RoundedImageView::Alignment::kCenter), resource_manager_(resource_manager), clipboard_history_item_(*clipboard_history_item), - opacity_(opacity), update_callback_(update_callback) { resource_manager_->AddObserver(this); SetImageFromModel(); @@ -119,12 +116,7 @@ *(resource_manager_->GetImageModel(clipboard_history_item_) .GetImage() .ToImageSkia()); - if (opacity_ != 1.f) { - SetImage( - gfx::ImageSkiaOperations::CreateTransparentImage(image, opacity_)); - } else { SetImage(image); - } // When fading in a new image, the ImageView's image has likely changed // sizes. @@ -149,9 +141,6 @@ // The ClipboardHistoryItem represented by this class. const ClipboardHistoryItem clipboard_history_item_; - // The opacity of the image content. - const float opacity_; - // Used to notify of image changes. base::RepeatingClosure update_callback_; }; @@ -231,16 +220,11 @@ // if menu items have their own layers, the part beyond the container's // bounds is still visible when the context menu is in overflow. - const float image_opacity = - container_->IsItemEnabled() - ? 1.f - : ClipboardHistoryViews::kDisabledImageAlpha; const auto* clipboard_history_item = container_->clipboard_history_item(); switch (container_->data_format_) { case ui::ClipboardInternalFormat::kHtml: return std::make_unique<FadeImageView>( clipboard_history_item, container_->resource_manager_, - image_opacity, base::BindRepeating(&BitmapContentsView::UpdateImageViewSize, weak_ptr_factory_.GetWeakPtr())); case ui::ClipboardInternalFormat::kBitmap: { @@ -249,10 +233,6 @@ RoundedImageView::Alignment::kCenter); gfx::ImageSkia bitmap_image = gfx::ImageSkia::CreateFrom1xBitmap( clipboard_history_item->data().bitmap()); - if (image_opacity != 1.f) { - bitmap_image = gfx::ImageSkiaOperations::CreateTransparentImage( - bitmap_image, image_opacity); - } image_view->SetImage(bitmap_image); return image_view; }
diff --git a/ash/clipboard/views/clipboard_history_item_view.cc b/ash/clipboard/views/clipboard_history_item_view.cc index f57e815..4c46dee5 100644 --- a/ash/clipboard/views/clipboard_history_item_view.cc +++ b/ash/clipboard/views/clipboard_history_item_view.cc
@@ -234,10 +234,6 @@ } } -bool ClipboardHistoryItemView::IsItemEnabled() const { - return container_->GetEnabled(); -} - gfx::Size ClipboardHistoryItemView::CalculatePreferredSize() const { const int preferred_width = views::MenuConfig::instance().touchable_menu_width; @@ -283,7 +279,7 @@ } bool ClipboardHistoryItemView::ShouldHighlight() const { - return pseudo_focus_ == PseudoFocus::kMainButton && IsItemEnabled(); + return pseudo_focus_ == PseudoFocus::kMainButton; } bool ClipboardHistoryItemView::ShouldShowDeleteButton() const {
diff --git a/ash/clipboard/views/clipboard_history_item_view.h b/ash/clipboard/views/clipboard_history_item_view.h index bc4e948..c081d42f 100644 --- a/ash/clipboard/views/clipboard_history_item_view.h +++ b/ash/clipboard/views/clipboard_history_item_view.h
@@ -109,10 +109,6 @@ // Returns the name of the accessible node. virtual base::string16 GetAccessibleName() const = 0; - // Returns whether the item view is enabled. The item view is disabled when - // it is not allowed to read clipboard data. - bool IsItemEnabled() const; - const ClipboardHistoryItem* clipboard_history_item() const { return clipboard_history_item_; }
diff --git a/ash/clipboard/views/clipboard_history_label.cc b/ash/clipboard/views/clipboard_history_label.cc index c7802fc9..9662b46 100644 --- a/ash/clipboard/views/clipboard_history_label.cc +++ b/ash/clipboard/views/clipboard_history_label.cc
@@ -32,12 +32,8 @@ // TODO(andrewxu): remove this line after https://crbug.com/1143009 is fixed. ash::ScopedLightModeAsDefault scoped_light_mode_as_default; - const auto color_type = - GetEnabled() - ? ash::AshColorProvider::ContentLayerType::kTextColorPrimary - : ash::AshColorProvider::ContentLayerType::kTextColorSecondary; - SetEnabledColor( - ash::AshColorProvider::Get()->GetContentLayerColor(color_type)); + SetEnabledColor(ash::AshColorProvider::Get()->GetContentLayerColor( + ash::AshColorProvider::ContentLayerType::kTextColorPrimary)); } } // namespace ash
diff --git a/ash/clipboard/views/clipboard_history_text_item_view.cc b/ash/clipboard/views/clipboard_history_text_item_view.cc index 3c13c6e..7903ec9 100644 --- a/ash/clipboard/views/clipboard_history_text_item_view.cc +++ b/ash/clipboard/views/clipboard_history_text_item_view.cc
@@ -33,7 +33,6 @@ auto* label = AddChildView(std::make_unique<ClipboardHistoryLabel>(container->text_)); layout->SetFlexForView(label, /*flex_weight=*/1); - label->SetEnabled(container->IsItemEnabled()); InstallDeleteButton(); }
diff --git a/ash/clipboard/views/clipboard_history_view_constants.h b/ash/clipboard/views/clipboard_history_view_constants.h index 3443c49..71f65c3 100644 --- a/ash/clipboard/views/clipboard_history_view_constants.h +++ b/ash/clipboard/views/clipboard_history_view_constants.h
@@ -41,9 +41,6 @@ // The thickness of the image border. constexpr int kImageBorderThickness = 1; -// The opacity of the image shown in a disabled item view. -constexpr float kDisabledImageAlpha = 0.38f; - } // namespace ClipboardHistoryViews } // namespace ash
diff --git a/ash/public/cpp/ash_pref_names.cc b/ash/public/cpp/ash_pref_names.cc index c374cb1..7d3a3c2 100644 --- a/ash/public/cpp/ash_pref_names.cc +++ b/ash/public/cpp/ash_pref_names.cc
@@ -135,6 +135,9 @@ "settings.a11y.tablet_mode_shelf_nav_buttons_enabled"; // A boolean pref which determines whether dictation is enabled. const char kAccessibilityDictationEnabled[] = "settings.a11y.dictation"; +// Whether the Live Caption feature is enabled. +const char kLiveCaptionEnabled[] = + "accessibility.captions.live_caption_enabled"; // A boolean pref which determines whether the accessibility menu shows // regardless of the state of a11y features. const char kShouldAlwaysShowAccessibilityMenu[] = "settings.a11y.enable_menu";
diff --git a/ash/public/cpp/ash_pref_names.h b/ash/public/cpp/ash_pref_names.h index 2fd3d29e..e86ac4ad 100644 --- a/ash/public/cpp/ash_pref_names.h +++ b/ash/public/cpp/ash_pref_names.h
@@ -52,6 +52,7 @@ ASH_PUBLIC_EXPORT extern const char kAccessibilityTabletModeShelfNavigationButtonsEnabled[]; ASH_PUBLIC_EXPORT extern const char kAccessibilityDictationEnabled[]; +ASH_PUBLIC_EXPORT extern const char kLiveCaptionEnabled[]; ASH_PUBLIC_EXPORT extern const char kShouldAlwaysShowAccessibilityMenu[]; ASH_PUBLIC_EXPORT extern const char kContextualTooltips[];
diff --git a/ash/system/audio/unified_volume_view.cc b/ash/system/audio/unified_volume_view.cc index 78e2f1a..74641e3 100644 --- a/ash/system/audio/unified_volume_view.cc +++ b/ash/system/audio/unified_volume_view.cc
@@ -4,14 +4,23 @@ #include "ash/system/audio/unified_volume_view.h" +#include <cmath> +#include <memory> +#include <utility> + #include "ash/public/cpp/ash_features.h" +#include "ash/public/cpp/ash_pref_names.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller_impl.h" +#include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_provider.h" #include "ash/system/tray/tray_popup_utils.h" #include "base/i18n/rtl.h" #include "base/stl_util.h" +#include "components/prefs/pref_service.h" #include "components/vector_icons/vector_icons.h" +#include "media/base/media_switches.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image_skia_operations.h" @@ -21,6 +30,7 @@ #include "ui/views/animation/ink_drop_impl.h" #include "ui/views/animation/ink_drop_mask.h" #include "ui/views/background.h" +#include "ui/views/controls/button/image_button_factory.h" #include "ui/views/controls/highlight_path_generator.h" #include "ui/views/controls/image_view.h" #include "ui/views/layout/box_layout.h" @@ -53,15 +63,125 @@ return *kVolumeLevelIcons[index]; } -SkColor GetBackgroundColorOfMoreButton() { - return AshColorProvider::Get()->GetControlsLayerColor( - AshColorProvider::ControlsLayerType::kControlBackgroundColorInactive); -} +// A template class for the UnifiedVolumeView buttons, used by the More and +// Live Caption buttons. |T| must be a subtype of |views::Button|. +template <typename T> +class UnifiedVolumeViewButton : public T { + public: + static_assert(std::is_base_of<views::Button, T>::value, + "T must be a subtype of views::Button"); -class MoreButton : public views::Button { + // A constructor that forwards |args| to |T|'s constructor, so |args| are the + // exact same as required by |T|'s constructor. It sets up the ink drop on the + // view. + template <typename... Args> + explicit UnifiedVolumeViewButton(Args... args) + : T(std::forward<Args>(args)...) { + TrayPopupUtils::ConfigureTrayPopupButton(this); + + views::InstallRoundRectHighlightPathGenerator(this, gfx::Insets(), + kTrayItemCornerRadius); + T::SetBackground(views::CreateRoundedRectBackground(GetBackgroundColor(), + kTrayItemCornerRadius)); + } + + ~UnifiedVolumeViewButton() override = default; + + std::unique_ptr<views::InkDrop> CreateInkDrop() override { + return TrayPopupUtils::CreateInkDrop(this); + } + + std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override { + return TrayPopupUtils::CreateInkDropRipple( + TrayPopupInkDropStyle::FILL_BOUNDS, this, + T::GetInkDropCenterBasedOnLastEvent()); + } + + std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() + const override { + return TrayPopupUtils::CreateInkDropHighlight(this); + } + + void OnThemeChanged() override { + T::OnThemeChanged(); + auto* color_provider = AshColorProvider::Get(); + T::focus_ring()->SetColor(color_provider->GetControlsLayerColor( + AshColorProvider::ControlsLayerType::kFocusRingColor)); + T::background()->SetNativeControlColor(GetBackgroundColor()); + } + + SkColor GetIconColor() { + return AshColorProvider::Get()->GetContentLayerColor( + AshColorProvider::ContentLayerType::kButtonIconColor); + } + + SkColor GetBackgroundColor() { + return AshColorProvider::Get()->GetControlsLayerColor( + AshColorProvider::ControlsLayerType::kControlBackgroundColorInactive); + } +}; + +class LiveCaptionButton + : public UnifiedVolumeViewButton<views::ToggleImageButton> { + public: + explicit LiveCaptionButton(PressedCallback callback) + : UnifiedVolumeViewButton(std::move(callback)) { + DCHECK_EQ(GetDefaultSizeOfVectorIcon(vector_icons::kLiveCaptionOffIcon), + GetDefaultSizeOfVectorIcon(vector_icons::kLiveCaptionOnIcon)); + int icon_size = + GetDefaultSizeOfVectorIcon(vector_icons::kLiveCaptionOnIcon); + SetBorder( + views::CreateEmptyBorder(gfx::Insets((kTrayItemSize - icon_size) / 2))); + SetImageHorizontalAlignment(ALIGN_CENTER); + SetImageVerticalAlignment(ALIGN_MIDDLE); + + SetTooltipText(l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_LIVE_CAPTION_TOGGLE_TOOLTIP, + l10n_util::GetStringUTF16( + IDS_ASH_STATUS_TRAY_LIVE_CAPTION_DISABLED_STATE_TOOLTIP))); + SetToggledTooltipText(l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_LIVE_CAPTION_TOGGLE_TOOLTIP, + l10n_util::GetStringUTF16( + IDS_ASH_STATUS_TRAY_LIVE_CAPTION_ENABLED_STATE_TOOLTIP))); + + SetToggledBackground(views::CreateRoundedRectBackground( + GetToggledBackgroundColor(), kTrayItemCornerRadius)); + } + + ~LiveCaptionButton() override = default; + + const char* GetClassName() const override { return "LiveCaptionButton"; } + + void OnThemeChanged() override { + UnifiedVolumeViewButton::OnThemeChanged(); + const int icon_size = + GetDefaultSizeOfVectorIcon(vector_icons::kLiveCaptionOnIcon); + views::SetImageFromVectorIconWithColor( + this, vector_icons::kLiveCaptionOffIcon, icon_size, GetIconColor()); + views::SetToggledImageFromVectorIconWithColor( + this, vector_icons::kLiveCaptionOnIcon, icon_size, + GetToggledIconColor(), GetToggledIconColor()); + toggled_background()->SetNativeControlColor(GetToggledBackgroundColor()); + } + + SkColor GetToggledIconColor() { + return AshColorProvider::Get()->GetContentLayerColor( + AshColorProvider::ContentLayerType::kButtonIconColorPrimary); + } + + SkColor GetToggledBackgroundColor() { + return AshColorProvider::Get()->GetControlsLayerColor( + AshColorProvider::ControlsLayerType::kControlBackgroundColorActive); + } + + private: + DISALLOW_COPY_AND_ASSIGN(LiveCaptionButton); +}; + +class MoreButton : public UnifiedVolumeViewButton<views::Button> { public: explicit MoreButton(PressedCallback callback) - : views::Button(std::move(callback)) { + : UnifiedVolumeViewButton(std::move(callback)) { SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal, gfx::Insets((kTrayItemSize - @@ -76,38 +196,15 @@ more_image_ = AddChildView(std::make_unique<views::ImageView>()); more_image_->SetCanProcessEventsWithinSubtree(false); SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_AUDIO)); - TrayPopupUtils::ConfigureTrayPopupButton(this); - - views::InstallRoundRectHighlightPathGenerator(this, gfx::Insets(), - kTrayItemCornerRadius); - SetBackground(views::CreateRoundedRectBackground( - GetBackgroundColorOfMoreButton(), kTrayItemCornerRadius)); } ~MoreButton() override = default; - std::unique_ptr<views::InkDrop> CreateInkDrop() override { - return TrayPopupUtils::CreateInkDrop(this); - } - - std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override { - return TrayPopupUtils::CreateInkDropRipple( - TrayPopupInkDropStyle::FILL_BOUNDS, this, - GetInkDropCenterBasedOnLastEvent()); - } - - std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() - const override { - return TrayPopupUtils::CreateInkDropHighlight(this); - } - const char* GetClassName() const override { return "MoreButton"; } void OnThemeChanged() override { - views::Button::OnThemeChanged(); - auto* color_provider = AshColorProvider::Get(); - const SkColor icon_color = color_provider->GetContentLayerColor( - AshColorProvider::ContentLayerType::kIconColorPrimary); + UnifiedVolumeViewButton::OnThemeChanged(); + const SkColor icon_color = GetIconColor(); if (headset_image_) { headset_image_->SetImage( CreateVectorIcon(vector_icons::kHeadsetIcon, icon_color)); @@ -118,9 +215,6 @@ : SkBitmapOperations::ROTATION_90_CW; more_image_->SetImage(gfx::ImageSkiaOperations::CreateRotatedImage( CreateVectorIcon(kUnifiedMenuExpandIcon, icon_color), icon_rotation)); - focus_ring()->SetColor(color_provider->GetControlsLayerColor( - AshColorProvider::ControlsLayerType::kFocusRingColor)); - background()->SetNativeControlColor(GetBackgroundColorOfMoreButton()); } private: @@ -141,11 +235,15 @@ controller, kSystemMenuVolumeHighIcon, IDS_ASH_STATUS_TRAY_VOLUME_SLIDER_LABEL), + live_caption_button_(new LiveCaptionButton( + base::BindRepeating(&UnifiedVolumeView::OnLiveCaptionButtonPressed, + base::Unretained(this)))), more_button_(new MoreButton( base::BindRepeating(&UnifiedVolumeSliderController::Delegate:: OnAudioSettingsButtonClicked, base::Unretained(delegate)))) { CrasAudioHandler::Get()->AddAudioObserver(this); + AddChildViewAt(live_caption_button_, 0); AddChildView(more_button_); Update(false /* by_user */); } @@ -178,6 +276,12 @@ button()->SetTooltipText(l10n_util::GetStringFUTF16( IDS_ASH_STATUS_TRAY_VOLUME, state_tooltip_text)); + live_caption_button_->SetVisible( + base::FeatureList::IsEnabled(media::kLiveCaption)); + live_caption_button_->SetToggled( + Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean( + prefs::kLiveCaptionEnabled)); + more_button_->SetVisible(CrasAudioHandler::Get()->has_alternative_input() || CrasAudioHandler::Get()->has_alternative_output() || features::IsSystemTrayMicGainSettingEnabled()); @@ -220,4 +324,12 @@ Layout(); } +void UnifiedVolumeView::OnLiveCaptionButtonPressed() { + PrefService* prefs = + Shell::Get()->session_controller()->GetActivePrefService(); + bool enabled = !prefs->GetBoolean(prefs::kLiveCaptionEnabled); + prefs->SetBoolean(prefs::kLiveCaptionEnabled, enabled); + live_caption_button_->SetToggled(enabled); +} + } // namespace ash
diff --git a/ash/system/audio/unified_volume_view.h b/ash/system/audio/unified_volume_view.h index f19ce53..5ca0fed5 100644 --- a/ash/system/audio/unified_volume_view.h +++ b/ash/system/audio/unified_volume_view.h
@@ -35,6 +35,10 @@ // UnifiedSliderView: void ChildVisibilityChanged(views::View* child) override; + // views::Button::PressedCallback + void OnLiveCaptionButtonPressed(); + + views::ToggleImageButton* const live_caption_button_; views::Button* const more_button_; DISALLOW_COPY_AND_ASSIGN(UnifiedVolumeView);
diff --git a/ash/system/holding_space/holding_space_item_view.cc b/ash/system/holding_space/holding_space_item_view.cc index f4098ca..bed6b9c 100644 --- a/ash/system/holding_space/holding_space_item_view.cc +++ b/ash/system/holding_space/holding_space_item_view.cc
@@ -75,7 +75,7 @@ HoldingSpaceItemView::HoldingSpaceItemView( HoldingSpaceItemViewDelegate* delegate, const HoldingSpaceItem* item) - : delegate_(delegate), item_(item) { + : delegate_(delegate), item_(item), item_id_(item->id()) { SetProperty(kIsHoldingSpaceItemViewProperty, true); set_context_menu_controller(delegate_);
diff --git a/ash/system/holding_space/holding_space_item_view.h b/ash/system/holding_space/holding_space_item_view.h index edc51ad0..f61c97b 100644 --- a/ash/system/holding_space/holding_space_item_view.h +++ b/ash/system/holding_space/holding_space_item_view.h
@@ -20,8 +20,10 @@ class HoldingSpaceItem; class HoldingSpaceItemViewDelegate; -// Base class for HoldingSpaceItemChipView and -// HoldingSpaceItemScreenCaptureView. +// Base class for `HoldingSpaceItemChipView` and +// `HoldingSpaceItemScreenCaptureView`. Note that `HoldingSpaceItemView` may +// temporarily outlive its associated `HoldingSpaceItem` when it is being +// animated out. class ASH_EXPORT HoldingSpaceItemView : public views::InkDropHostView { public: METADATA_HEADER(HoldingSpaceItemView); @@ -57,6 +59,7 @@ ui::mojom::DragEventSource source); const HoldingSpaceItem* item() const { return item_; } + const std::string& item_id() const { return item_id_; } void SetSelected(bool selected); bool selected() const { return selected_; } @@ -73,7 +76,13 @@ HoldingSpaceItemViewDelegate* const delegate_; const HoldingSpaceItem* const item_; - views::ToggleImageButton* pin_ = nullptr; + + // Cache the id of the associated holding space item so that it can be + // accessed even after `item_` has been destroyed. Note that `item_` may be + // destroyed if this view is in the process of animating out. + const std::string item_id_; + + views::ToggleImageButton* pin_ = nullptr; // Owned by view hierarchy. // Owners for the layers used to paint focused and selected states. std::unique_ptr<ui::LayerOwner> selected_layer_owner_;
diff --git a/ash/system/holding_space/holding_space_item_view_delegate.cc b/ash/system/holding_space/holding_space_item_view_delegate.cc index 7a20f1f..f770e4a 100644 --- a/ash/system/holding_space/holding_space_item_view_delegate.cc +++ b/ash/system/holding_space/holding_space_item_view_delegate.cc
@@ -56,6 +56,20 @@ } // namespace +// HoldingSpaceItemViewDelegate::ScopedSelectionRestore ------------------------ + +HoldingSpaceItemViewDelegate::ScopedSelectionRestore::ScopedSelectionRestore( + HoldingSpaceItemViewDelegate* delegate) + : delegate_(delegate) { + for (const HoldingSpaceItemView* view : delegate_->GetSelection()) + selected_item_ids_.push_back(view->item_id()); +} + +HoldingSpaceItemViewDelegate::ScopedSelectionRestore:: + ~ScopedSelectionRestore() { + delegate_->SetSelection(selected_item_ids_); +} + // HoldingSpaceItemViewDelegate ------------------------------------------------ HoldingSpaceItemViewDelegate::HoldingSpaceItemViewDelegate() { @@ -391,4 +405,10 @@ view->SetSelected(view == selection); } +void HoldingSpaceItemViewDelegate::SetSelection( + const std::vector<std::string>& item_ids) { + for (HoldingSpaceItemView* view : views_) + view->SetSelected(base::Contains(item_ids, view->item_id())); +} + } // namespace ash
diff --git a/ash/system/holding_space/holding_space_item_view_delegate.h b/ash/system/holding_space/holding_space_item_view_delegate.h index 006f224..36d83f6 100644 --- a/ash/system/holding_space/holding_space_item_view_delegate.h +++ b/ash/system/holding_space/holding_space_item_view_delegate.h
@@ -41,6 +41,20 @@ public views::ViewObserver, public ui::SimpleMenuModel::Delegate { public: + // A class which caches the current selection of holding space item views on + // creation and restores that selection on destruction. + class ScopedSelectionRestore { + public: + explicit ScopedSelectionRestore(HoldingSpaceItemViewDelegate* delegate); + ScopedSelectionRestore(const ScopedSelectionRestore&) = delete; + ScopedSelectionRestore& operator=(const ScopedSelectionRestore&) = delete; + ~ScopedSelectionRestore(); + + private: + HoldingSpaceItemViewDelegate* const delegate_; + std::vector<std::string> selected_item_ids_; + }; + HoldingSpaceItemViewDelegate(); HoldingSpaceItemViewDelegate(const HoldingSpaceItemViewDelegate&) = delete; HoldingSpaceItemViewDelegate& operator=(const HoldingSpaceItemViewDelegate&) = @@ -103,6 +117,10 @@ // Marks `view` as selected. All other `views_` are marked unselected. void SetSelection(views::View* view); + // Marks any `views_` whose associated holding space items are contained in + // `item_ids` as selected. All other `views_` are marked unselected. + void SetSelection(const std::vector<std::string>& item_ids); + std::unique_ptr<ui::SimpleMenuModel> context_menu_model_; std::unique_ptr<views::MenuRunner> context_menu_runner_;
diff --git a/ash/system/holding_space/holding_space_item_views_container.cc b/ash/system/holding_space/holding_space_item_views_container.cc index bdf1915b..351b0d67 100644 --- a/ash/system/holding_space/holding_space_item_views_container.cc +++ b/ash/system/holding_space/holding_space_item_views_container.cc
@@ -5,11 +5,73 @@ #include "ash/system/holding_space/holding_space_item_views_container.h" #include "ash/public/cpp/holding_space/holding_space_item.h" +#include "ash/system/holding_space/holding_space_item_view.h" +#include "ash/system/holding_space/holding_space_item_view_delegate.h" +#include "ui/compositor/layer_animation_observer.h" +#include "ui/compositor/scoped_layer_animation_settings.h" namespace ash { -HoldingSpaceItemViewsContainer::HoldingSpaceItemViewsContainer() { +namespace { + +using AnimatableProperty = ui::LayerAnimationElement::AnimatableProperty; + +// CallbackAnimationObserver --------------------------------------------------- + +// An implicit animation observer which invokes a `callback` on animation +// completion. The `callback` will be notified whether the animation completed +// due to abort or if the animation completed normally. +class CallbackAnimationObserver : public ui::ImplicitAnimationObserver { + public: + using Callback = base::RepeatingCallback<void(bool aborted)>; + + explicit CallbackAnimationObserver(Callback callback) : callback_(callback) {} + CallbackAnimationObserver(const CallbackAnimationObserver&) = delete; + CallbackAnimationObserver& operator=(const CallbackAnimationObserver&) = + delete; + ~CallbackAnimationObserver() override = default; + + private: + // ui::ImplicitAnimationObserver: + void OnImplicitAnimationsCompleted() override { + bool aborted = false; + for (int i = AnimatableProperty::FIRST_PROPERTY; + i < AnimatableProperty::SENTINEL; ++i) { + const AnimatableProperty property = static_cast<AnimatableProperty>(i); + if (WasAnimationAbortedForProperty(property)) { + aborted = true; + break; + } + } + callback_.Run(aborted); + } + + Callback callback_; +}; + +} // namespace + +// HoldingSpaceItemViewsContainer ---------------------------------------------- + +HoldingSpaceItemViewsContainer::HoldingSpaceItemViewsContainer( + HoldingSpaceItemViewDelegate* delegate) + : delegate_(delegate), + animate_in_observer_( + std::make_unique<CallbackAnimationObserver>(base::BindRepeating( + &HoldingSpaceItemViewsContainer::OnAnimateInCompleted, + base::Unretained(this)))), + animate_out_observer_( + std::make_unique<CallbackAnimationObserver>(base::BindRepeating( + &HoldingSpaceItemViewsContainer::OnAnimateOutCompleted, + base::Unretained(this)))) { controller_observer_.Add(HoldingSpaceController::Get()); + + // The holding space views container will attach `animate_in_observer_` and + // `animate_out_observer_` to a `ui::ScopedLayerAnimationSettings` associated + // with itself in order to determine when animations are completed. To do so, + // the holding space item views container must have a layer. + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); } HoldingSpaceItemViewsContainer::~HoldingSpaceItemViewsContainer() = default; @@ -32,34 +94,121 @@ void HoldingSpaceItemViewsContainer::OnHoldingSpaceModelAttached( HoldingSpaceModel* model) { model_observer_.Add(model); - for (const auto& item : model->items()) { - if (item->IsFinalized()) - AddHoldingSpaceItemView(item.get(), /*due_to_finalization=*/false); - } + for (const auto& item : model->items()) + OnHoldingSpaceItemAdded(item.get()); } void HoldingSpaceItemViewsContainer::OnHoldingSpaceModelDetached( HoldingSpaceModel* model) { model_observer_.Remove(model); - RemoveAllHoldingSpaceItemViews(); + if (ContainsHoldingSpaceItemViews()) + MaybeAnimateOut(); } void HoldingSpaceItemViewsContainer::OnHoldingSpaceItemAdded( const HoldingSpaceItem* item) { if (!item->IsFinalized()) return; - - AddHoldingSpaceItemView(item, /*due_to_finalization=*/false); + if (WillAddHoldingSpaceItemView(item)) + MaybeAnimateOut(); } void HoldingSpaceItemViewsContainer::OnHoldingSpaceItemRemoved( const HoldingSpaceItem* item) { - RemoveHoldingSpaceItemView(item); + if (ContainsHoldingSpaceItemView(item)) + MaybeAnimateOut(); } void HoldingSpaceItemViewsContainer::OnHoldingSpaceItemFinalized( const HoldingSpaceItem* item) { - AddHoldingSpaceItemView(item, /*due_to_finalization=*/true); + if (WillAddHoldingSpaceItemView(item)) + MaybeAnimateOut(); +} + +void HoldingSpaceItemViewsContainer::MaybeAnimateIn() { + if (animation_state_ & AnimationState::kAnimatingIn) + return; + + animation_state_ |= AnimationState::kAnimatingIn; + + // In the event that the call to `AnimateIn()` did not result in an animation + // being scheduled, `OnAnimateInCompleted()` should still be called. To ensure + // this occurs, add the animation observer to a scoped settings doing nothing. + ui::ScopedLayerAnimationSettings animation_settings(layer()->GetAnimator()); + animation_settings.AddObserver(animate_in_observer_.get()); + + AnimateIn(animate_in_observer_.get()); +} + +void HoldingSpaceItemViewsContainer::MaybeAnimateOut() { + if (animation_state_ & AnimationState::kAnimatingOut) + return; + + animation_state_ |= AnimationState::kAnimatingOut; + + // Don't allow event processing while animating out. The views being animated + // out may be associated with holding space items that no longer exist and + // so should not be acted upon by the user during this time. + SetCanProcessEventsWithinSubtree(false); + + // In the event that the call to `AnimateOut()` did not result in an animation + // being scheduled, `OnAnimateOutCompleted()` should still be called. To + // ensure this occurs, add the animation observer to a scoped settings doing + // nothing. + ui::ScopedLayerAnimationSettings animation_settings(layer()->GetAnimator()); + animation_settings.AddObserver(animate_out_observer_.get()); + + AnimateOut(animate_out_observer_.get()); +} + +void HoldingSpaceItemViewsContainer::OnAnimateInCompleted(bool aborted) { + DCHECK(animation_state_ & AnimationState::kAnimatingIn); + animation_state_ &= ~AnimationState::kAnimatingIn; + + if (aborted) + return; + + DCHECK_EQ(animation_state_, AnimationState::kNotAnimating); + + // Restore event processing that was disabled while animating out. The views + // that have been animated in should all be associated with holding space + // items that exist in the model. + SetCanProcessEventsWithinSubtree(true); +} + +void HoldingSpaceItemViewsContainer::OnAnimateOutCompleted(bool aborted) { + DCHECK(animation_state_ & AnimationState::kAnimatingOut); + animation_state_ &= ~AnimationState::kAnimatingOut; + + if (aborted) + return; + + DCHECK_EQ(animation_state_, AnimationState::kNotAnimating); + + // All holding space item views are going to be removed after which views will + // be re-added for those items which still exist. A `ScopedSelectionRestore` + // will serve to persist the current selection during this modification. + HoldingSpaceItemViewDelegate::ScopedSelectionRestore scoped_selection_restore( + delegate_); + + if (ContainsHoldingSpaceItemViews()) + RemoveAllHoldingSpaceItemViews(); + + HoldingSpaceModel* model = HoldingSpaceController::Get()->model(); + if (!model) + return; + + bool is_empty = true; + + for (const auto& item : model->items()) { + if (item->IsFinalized() && WillAddHoldingSpaceItemView(item.get())) { + AddHoldingSpaceItemView(item.get()); + is_empty = false; + } + } + + if (!is_empty) + MaybeAnimateIn(); } } // namespace ash
diff --git a/ash/system/holding_space/holding_space_item_views_container.h b/ash/system/holding_space/holding_space_item_views_container.h index 5510e47..a32b0962 100644 --- a/ash/system/holding_space/holding_space_item_views_container.h +++ b/ash/system/holding_space/holding_space_item_views_container.h
@@ -13,15 +13,20 @@ #include "base/scoped_observer.h" #include "ui/views/view.h" +namespace ui { +class ImplicitAnimationObserver; +} // namespace ui + namespace ash { class HoldingSpaceItem; +class HoldingSpaceItemViewDelegate; class HoldingSpaceItemViewsContainer : public views::View, public HoldingSpaceControllerObserver, public HoldingSpaceModelObserver { public: - HoldingSpaceItemViewsContainer(); + explicit HoldingSpaceItemViewsContainer(HoldingSpaceItemViewDelegate*); HoldingSpaceItemViewsContainer(const HoldingSpaceItemViewsContainer& other) = delete; HoldingSpaceItemViewsContainer& operator=( @@ -33,11 +38,6 @@ // items are created while the bubble widget is being asynchronously closed. void Reset(); - virtual void AddHoldingSpaceItemView(const HoldingSpaceItem* item, - bool due_to_finalization) = 0; - virtual void RemoveAllHoldingSpaceItemViews() = 0; - virtual void RemoveHoldingSpaceItemView(const HoldingSpaceItem* item) = 0; - // views::View: void ChildPreferredSizeChanged(views::View* child) override; void ChildVisibilityChanged(views::View* child) override; @@ -51,7 +51,73 @@ void OnHoldingSpaceItemRemoved(const HoldingSpaceItem* item) override; void OnHoldingSpaceItemFinalized(const HoldingSpaceItem* item) override; + protected: + // Returns whether a view for the specified `item` exists in this holding + // space item views container. Note that returning true will result in a call + // to `RemoveAllHoldingSpaceItemViews()` after which views for existing + // holding space items will be re-added via call to + // `AddHoldingSpaceItemView()`. + virtual bool ContainsHoldingSpaceItemView(const HoldingSpaceItem* item) = 0; + + // Returns whether any views associated with holding space items exist which + // in this holding space item views container. Note that returning true will + // result in a call to `RemoveAllHoldingSpaceItemViews()`. + virtual bool ContainsHoldingSpaceItemViews() = 0; + + // Returns whether a view for the specified `item` will be added to this + // holding space item views container. Note that `AddHoldingSpaceItemView()` + // will only be invoked if this method returns true for the given `item`. + virtual bool WillAddHoldingSpaceItemView(const HoldingSpaceItem* item) = 0; + + // Invoked to add a view to this holding space item views container for the + // specified `item`. + virtual void AddHoldingSpaceItemView(const HoldingSpaceItem* item) = 0; + + // Invoked to remove all views associated with holding space items from this + // holding space item views container. + virtual void RemoveAllHoldingSpaceItemViews() = 0; + + // Invoked to initiate animate in of the contents of this holding space item + // views container. Any animations created must be associated with `observer`. + virtual void AnimateIn(ui::ImplicitAnimationObserver* observer) = 0; + + // Invoked to initiate animate out of the contents of this holding space item + // views container. Any animations created must be associated with `observer`. + virtual void AnimateOut(ui::ImplicitAnimationObserver* observer) = 0; + + HoldingSpaceItemViewDelegate* delegate() { return delegate_; } + private: + enum AnimationState : uint32_t { + kNotAnimating = 0, + kAnimatingIn = 1 << 1, + kAnimatingOut = 1 << 2, + }; + + // Invoke to start animating in the contents of this holding space item views + // container. No-ops if animate in is already in progress. + void MaybeAnimateIn(); + + // Invoke to start animating out the contents of this holding space item views + // container. No-ops if animate out is already in progress. + void MaybeAnimateOut(); + + // Invoked when an animate in/out of the contents of this holding space item + // views container has been completed. If `aborted` is true, the animation + // completed due to abort, otherwise the animation completed normally. + void OnAnimateInCompleted(bool aborted); + void OnAnimateOutCompleted(bool aborted); + + HoldingSpaceItemViewDelegate* const delegate_; + + std::unique_ptr<ui::ImplicitAnimationObserver> animate_in_observer_; + std::unique_ptr<ui::ImplicitAnimationObserver> animate_out_observer_; + + // Bit flag representation of current `AnimationState`. Note that it is + // briefly possible to be both `kAnimatingIn` and `kAnimatingOut` when one + // animation is preempting another. + uint32_t animation_state_ = AnimationState::kNotAnimating; + ScopedObserver<HoldingSpaceController, HoldingSpaceControllerObserver> controller_observer_{this}; ScopedObserver<HoldingSpaceModel, HoldingSpaceModelObserver> model_observer_{
diff --git a/ash/system/holding_space/pinned_files_container.cc b/ash/system/holding_space/pinned_files_container.cc index 3b67ea6..9887ce2a 100644 --- a/ash/system/holding_space/pinned_files_container.cc +++ b/ash/system/holding_space/pinned_files_container.cc
@@ -82,7 +82,7 @@ PinnedFilesContainer::PinnedFilesContainer( HoldingSpaceItemViewDelegate* delegate) - : delegate_(delegate) { + : HoldingSpaceItemViewsContainer(delegate) { SetID(kHoldingSpacePinnedFilesContainerId); SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -151,31 +151,28 @@ SetVisible(details.is_add); } -void PinnedFilesContainer::AddHoldingSpaceItemView(const HoldingSpaceItem* item, - bool due_to_finalization) { - DCHECK(!base::Contains(views_by_item_id_, item->id())); +bool PinnedFilesContainer::ContainsHoldingSpaceItemView( + const HoldingSpaceItem* item) { + return base::Contains(views_by_item_id_, item->id()); +} + +bool PinnedFilesContainer::ContainsHoldingSpaceItemViews() { + return !views_by_item_id_.empty(); +} + +bool PinnedFilesContainer::WillAddHoldingSpaceItemView( + const HoldingSpaceItem* item) { + return item->type() == HoldingSpaceItem::Type::kPinnedFile; +} + +void PinnedFilesContainer::AddHoldingSpaceItemView( + const HoldingSpaceItem* item) { DCHECK(item->IsFinalized()); - - if (item->type() != HoldingSpaceItem::Type::kPinnedFile) - return; - - size_t index = 0; - - if (due_to_finalization) { - // Find the position at which the view should be added. - for (const auto& candidate : - base::Reversed(HoldingSpaceController::Get()->model()->items())) { - if (candidate->id() == item->id()) - break; - if (candidate->IsFinalized() && - candidate->type() == HoldingSpaceItem::Type::kPinnedFile) { - ++index; - } - } - } + DCHECK_EQ(item->type(), HoldingSpaceItem::Type::kPinnedFile); + DCHECK(!base::Contains(views_by_item_id_, item->id())); views_by_item_id_[item->id()] = item_chips_container_->AddChildViewAt( - std::make_unique<HoldingSpaceItemChipView>(delegate_, item), index); + std::make_unique<HoldingSpaceItemChipView>(delegate(), item), 0); } void PinnedFilesContainer::RemoveAllHoldingSpaceItemViews() { @@ -183,14 +180,14 @@ item_chips_container_->RemoveAllChildViews(true); } -void PinnedFilesContainer::RemoveHoldingSpaceItemView( - const HoldingSpaceItem* item) { - auto it = views_by_item_id_.find(item->id()); - if (it == views_by_item_id_.end()) - return; +// TODO(dmblack): Implement. +void PinnedFilesContainer::AnimateIn(ui::ImplicitAnimationObserver* observer) { + NOTIMPLEMENTED(); +} - item_chips_container_->RemoveChildViewT(it->second); - views_by_item_id_.erase(it->first); +// TODO(dmblack): Implement. +void PinnedFilesContainer::AnimateOut(ui::ImplicitAnimationObserver* observer) { + NOTIMPLEMENTED(); } } // namespace ash
diff --git a/ash/system/holding_space/pinned_files_container.h b/ash/system/holding_space/pinned_files_container.h index 5f12183..828a489 100644 --- a/ash/system/holding_space/pinned_files_container.h +++ b/ash/system/holding_space/pinned_files_container.h
@@ -16,7 +16,6 @@ namespace ash { class HoldingSpaceItemChipsContainer; -class HoldingSpaceItemViewDelegate; // Container for pinned files that the user adds to the holding space bubble. class PinnedFilesContainer : public HoldingSpaceItemViewsContainer { @@ -28,14 +27,16 @@ // HoldingSpaceItemViewsContainer: void ViewHierarchyChanged(const views::ViewHierarchyChangedDetails&) override; - void AddHoldingSpaceItemView(const HoldingSpaceItem* item, - bool due_to_finalization) override; + bool ContainsHoldingSpaceItemView(const HoldingSpaceItem* item) override; + bool ContainsHoldingSpaceItemViews() override; + bool WillAddHoldingSpaceItemView(const HoldingSpaceItem* item) override; + void AddHoldingSpaceItemView(const HoldingSpaceItem* item) override; void RemoveAllHoldingSpaceItemViews() override; - void RemoveHoldingSpaceItemView(const HoldingSpaceItem* item) override; + void AnimateIn(ui::ImplicitAnimationObserver* observer) override; + void AnimateOut(ui::ImplicitAnimationObserver* observer) override; private: - HoldingSpaceItemViewDelegate* const delegate_; - + // Owned by view hierarchy. views::Label* empty_prompt_label_ = nullptr; HoldingSpaceItemChipsContainer* item_chips_container_ = nullptr;
diff --git a/ash/system/holding_space/recent_files_container.cc b/ash/system/holding_space/recent_files_container.cc index 417230d..fe0540d 100644 --- a/ash/system/holding_space/recent_files_container.cc +++ b/ash/system/holding_space/recent_files_container.cc
@@ -61,15 +61,6 @@ type == HoldingSpaceItem::Type::kScreenRecording; } -// Returns if items of the specified types belong to the same section. -bool BelongToSameSection(HoldingSpaceItem::Type type, - HoldingSpaceItem::Type other_type) { - return (BelongsToScreenCaptureSection(type) && - BelongsToScreenCaptureSection(other_type)) || - (BelongsToDownloadsSection(type) && - BelongsToDownloadsSection(other_type)); -} - // DownloadsHeader-------------------------------------------------------------- class DownloadsHeader : public views::Button { @@ -114,7 +105,7 @@ RecentFilesContainer::RecentFilesContainer( HoldingSpaceItemViewDelegate* delegate) - : delegate_(delegate) { + : HoldingSpaceItemViewsContainer(delegate) { SetID(kHoldingSpaceRecentFilesContainerId); SetVisible(false); @@ -170,34 +161,31 @@ OnDownloadsContainerViewHierarchyChanged(details); } -void RecentFilesContainer::AddHoldingSpaceItemView(const HoldingSpaceItem* item, - bool due_to_finalization) { +bool RecentFilesContainer::ContainsHoldingSpaceItemView( + const HoldingSpaceItem* item) { + return base::Contains(views_by_item_id_, item->id()); +} + +bool RecentFilesContainer::ContainsHoldingSpaceItemViews() { + return !views_by_item_id_.empty(); +} + +bool RecentFilesContainer::WillAddHoldingSpaceItemView( + const HoldingSpaceItem* item) { + return BelongsToDownloadsSection(item->type()) || + BelongsToScreenCaptureSection(item->type()); +} + +void RecentFilesContainer::AddHoldingSpaceItemView( + const HoldingSpaceItem* item) { DCHECK(item->IsFinalized()); - if (!BelongsToScreenCaptureSection(item->type()) && - !BelongsToDownloadsSection(item->type())) { - return; - } - - size_t index = 0; - - if (due_to_finalization) { - // Find the position at which the view should be added. - for (const auto& candidate : - base::Reversed(HoldingSpaceController::Get()->model()->items())) { - if (candidate->id() == item->id()) - break; - if (candidate->IsFinalized() && - BelongToSameSection(candidate->type(), item->type())) { - ++index; - } - } - } - if (BelongsToScreenCaptureSection(item->type())) - AddHoldingSpaceScreenCaptureView(item, index); + AddHoldingSpaceScreenCaptureView(item); else if (BelongsToDownloadsSection(item->type())) - AddHoldingSpaceDownloadView(item, index); + AddHoldingSpaceDownloadView(item); + else + NOTREACHED(); } void RecentFilesContainer::RemoveAllHoldingSpaceItemViews() { @@ -206,23 +194,21 @@ downloads_container_->RemoveAllChildViews(true); } -void RecentFilesContainer::RemoveHoldingSpaceItemView( - const HoldingSpaceItem* item) { - if (BelongsToScreenCaptureSection(item->type())) - RemoveHoldingSpaceScreenCaptureView(item); - else if (BelongsToDownloadsSection(item->type())) - RemoveHoldingSpaceDownloadView(item); +// TODO(dmblack): Implement. +void RecentFilesContainer::AnimateIn(ui::ImplicitAnimationObserver* observer) { + NOTIMPLEMENTED(); +} + +// TODO(dmblack): Implement. +void RecentFilesContainer::AnimateOut(ui::ImplicitAnimationObserver* observer) { + NOTIMPLEMENTED(); } void RecentFilesContainer::AddHoldingSpaceScreenCaptureView( - const HoldingSpaceItem* item, - size_t index) { + const HoldingSpaceItem* item) { DCHECK(BelongsToScreenCaptureSection(item->type())); DCHECK(!base::Contains(views_by_item_id_, item->id())); - if (index >= kMaxScreenCaptures) - return; - // Remove the last screen capture view if we are already at max capacity. if (screen_captures_container_->children().size() == kMaxScreenCaptures) { std::unique_ptr<views::View> view = @@ -234,51 +220,14 @@ // Add the screen capture view to the front in order to sort by recency. views_by_item_id_[item->id()] = screen_captures_container_->AddChildViewAt( - std::make_unique<HoldingSpaceItemScreenCaptureView>(delegate_, item), - index); -} - -void RecentFilesContainer::RemoveHoldingSpaceScreenCaptureView( - const HoldingSpaceItem* item) { - DCHECK(BelongsToScreenCaptureSection(item->type())); - - auto it = views_by_item_id_.find(item->id()); - if (it == views_by_item_id_.end()) - return; - - // Remove the screen capture view associated with `item`. - screen_captures_container_->RemoveChildViewT(it->second); - views_by_item_id_.erase(it); - - // Verify that we are *not* at max capacity. - DCHECK_LT(screen_captures_container_->children().size(), kMaxScreenCaptures); - - // Since we are under max capacity, we can add at most one screen capture view - // to replace the view we just removed. Note that we add the replacement to - // the back in order to maintain sort by recency. - for (const auto& candidate : - base::Reversed(HoldingSpaceController::Get()->model()->items())) { - if (candidate->IsFinalized() && - BelongsToScreenCaptureSection(item->type()) && - !base::Contains(views_by_item_id_, candidate->id())) { - views_by_item_id_[candidate->id()] = - screen_captures_container_->AddChildView( - std::make_unique<HoldingSpaceItemScreenCaptureView>( - delegate_, candidate.get())); - return; - } - } + std::make_unique<HoldingSpaceItemScreenCaptureView>(delegate(), item), 0); } void RecentFilesContainer::AddHoldingSpaceDownloadView( - const HoldingSpaceItem* item, - size_t index) { + const HoldingSpaceItem* item) { DCHECK(BelongsToDownloadsSection(item->type())); DCHECK(!base::Contains(views_by_item_id_, item->id())); - if (index >= kMaxDownloads) - return; - // Remove the last download view if we are already at max capacity. if (downloads_container_->children().size() == kMaxDownloads) { std::unique_ptr<views::View> view = downloads_container_->RemoveChildViewT( @@ -289,37 +238,7 @@ // Add the download view to the front in order to sort by recency. views_by_item_id_[item->id()] = downloads_container_->AddChildViewAt( - std::make_unique<HoldingSpaceItemChipView>(delegate_, item), index); -} - -void RecentFilesContainer::RemoveHoldingSpaceDownloadView( - const HoldingSpaceItem* item) { - DCHECK(BelongsToDownloadsSection(item->type())); - - auto it = views_by_item_id_.find(item->id()); - if (it == views_by_item_id_.end()) - return; - - // Remove the download view associated with `item`. - downloads_container_->RemoveChildViewT(it->second); - views_by_item_id_.erase(it); - - // Verify that we are *not* at max capacity. - DCHECK_LT(downloads_container_->children().size(), kMaxDownloads); - - // Since we are under max capacity, we can add at most one download view to - // replace the view we just removed. Note that we add the replacement to the - // back in order to maintain sort by recency. - for (const auto& candidate : - base::Reversed(HoldingSpaceController::Get()->model()->items())) { - if (candidate->IsFinalized() && BelongsToDownloadsSection(item->type()) && - !base::Contains(views_by_item_id_, candidate->id())) { - views_by_item_id_[candidate->id()] = downloads_container_->AddChildView( - std::make_unique<HoldingSpaceItemChipView>(delegate_, - candidate.get())); - return; - } - } + std::make_unique<HoldingSpaceItemChipView>(delegate(), item), 0); } void RecentFilesContainer::OnScreenCapturesContainerViewHierarchyChanged(
diff --git a/ash/system/holding_space/recent_files_container.h b/ash/system/holding_space/recent_files_container.h index 7f94ea67..dde4c0af 100644 --- a/ash/system/holding_space/recent_files_container.h +++ b/ash/system/holding_space/recent_files_container.h
@@ -16,7 +16,6 @@ namespace ash { class HoldingSpaceItemChipsContainer; -class HoldingSpaceItemViewDelegate; // Container for the recent files (e.g. screen captures, downloads, etc). class RecentFilesContainer : public HoldingSpaceItemViewsContainer { @@ -29,24 +28,23 @@ // HoldingSpaceItemViewsContainer: void ChildVisibilityChanged(views::View* child) override; void ViewHierarchyChanged(const views::ViewHierarchyChangedDetails&) override; - void AddHoldingSpaceItemView(const HoldingSpaceItem* item, - bool due_to_finalization) override; + bool ContainsHoldingSpaceItemView(const HoldingSpaceItem* item) override; + bool ContainsHoldingSpaceItemViews() override; + bool WillAddHoldingSpaceItemView(const HoldingSpaceItem* item) override; + void AddHoldingSpaceItemView(const HoldingSpaceItem* item) override; void RemoveAllHoldingSpaceItemViews() override; - void RemoveHoldingSpaceItemView(const HoldingSpaceItem* item) override; + void AnimateIn(ui::ImplicitAnimationObserver* observer) override; + void AnimateOut(ui::ImplicitAnimationObserver* observer) override; private: - void AddHoldingSpaceScreenCaptureView(const HoldingSpaceItem* item, - size_t index); - void RemoveHoldingSpaceScreenCaptureView(const HoldingSpaceItem* item); - void AddHoldingSpaceDownloadView(const HoldingSpaceItem* item, size_t index); - void RemoveHoldingSpaceDownloadView(const HoldingSpaceItem* item); + void AddHoldingSpaceScreenCaptureView(const HoldingSpaceItem* item); + void AddHoldingSpaceDownloadView(const HoldingSpaceItem* item); void OnScreenCapturesContainerViewHierarchyChanged( const views::ViewHierarchyChangedDetails& details); void OnDownloadsContainerViewHierarchyChanged( const views::ViewHierarchyChangedDetails& details); - HoldingSpaceItemViewDelegate* const delegate_; - + // Owned by view hierarchy. views::View* screen_captures_container_ = nullptr; views::Label* screen_captures_label_ = nullptr; HoldingSpaceItemChipsContainer* downloads_container_ = nullptr;
diff --git a/base/allocator/partition_allocator/page_allocator_internals_posix.h b/base/allocator/partition_allocator/page_allocator_internals_posix.h index 2a784d3..503fa7dd 100644 --- a/base/allocator/partition_allocator/page_allocator_internals_posix.h +++ b/base/allocator/partition_allocator/page_allocator_internals_posix.h
@@ -247,14 +247,20 @@ void* address, size_t length, PageAccessibilityDisposition accessibility_disposition) { - if (accessibility_disposition == PageUpdatePermissions) { - SetSystemPagesAccess(address, length, PageInaccessible); - } - // In POSIX, there is no decommit concept. Discarding is an effective way of // implementing the Windows semantics where the OS is allowed to not swap the // pages in the region. DiscardSystemPages(address, length); + + // Make pages inaccessible, unless the caller requested to keep permissions. + // + // Note, there is a small window between these calls when the pages can be + // incorrectly touched and brought back to memory. Not ideal, but doing those + // operaions in the opposite order resulted in PMF regression on Mac (see + // crbug.com/1153021). + if (accessibility_disposition == PageUpdatePermissions) { + SetSystemPagesAccess(address, length, PageInaccessible); + } } void RecommitSystemPagesInternal( @@ -262,12 +268,6 @@ size_t length, PageAccessibilityConfiguration accessibility, PageAccessibilityDisposition accessibility_disposition) { -#if defined(OS_APPLE) - // On macOS, to update accounting, we need to make another syscall. For more - // details, see https://crbug.com/823915. - madvise(address, length, MADV_FREE_REUSE); -#endif - // On POSIX systems, the caller need simply read the memory to recommit it. // This has the correct behavior because the API requires the permissions to // be the same as before decommitting and all configurations can read. @@ -276,6 +276,12 @@ if (accessibility_disposition == PageUpdatePermissions) { SetSystemPagesAccess(address, length, accessibility); } + +#if defined(OS_APPLE) + // On macOS, to update accounting, we need to make another syscall. For more + // details, see https://crbug.com/823915. + madvise(address, length, MADV_FREE_REUSE); +#endif } void DiscardSystemPagesInternal(void* address, size_t length) {
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc index 1c15ce3..8bfad3543 100644 --- a/base/allocator/partition_allocator/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -1432,7 +1432,12 @@ allocator.root()->AdjustPointerForExtrasSubtract(ptr)); EXPECT_EQ(nullptr, bucket->empty_slot_spans_head); EXPECT_EQ(1, slot_span->num_allocated_slots); +#if defined(OS_WIN) + // Windows uses lazy commit, thus committing only needed pages. size_t expected_committed_size = SystemPageSize(); +#else + size_t expected_committed_size = PartitionPageSize(); +#endif EXPECT_EQ(expected_committed_size, allocator.root()->get_total_size_of_committed_pages()); allocator.root()->Free(ptr); @@ -1446,7 +1451,15 @@ EXPECT_FALSE(slot_span->freelist_head); EXPECT_EQ(-1, slot_span->empty_cache_index); EXPECT_EQ(0, slot_span->num_allocated_slots); +#if defined(OS_WIN) size_t expected_size = SystemPageSize(); +#else + PartitionBucket<base::internal::ThreadSafe>* cycle_free_cache_bucket = + &allocator.root()->buckets[test_bucket_index_]; + size_t expected_size = + cycle_free_cache_bucket->num_system_pages_per_slot_span * + SystemPageSize(); +#endif EXPECT_EQ(expected_size, allocator.root()->get_total_size_of_committed_pages()); @@ -2565,7 +2578,12 @@ // A full slot span of size 1 partition page is committed. void* ptr = root.Alloc(small_size - kExtraAllocSize, type_name); +#if defined(OS_WIN) + // Windows uses lazy commit, thus committing only needed pages. size_t expected_committed_size = SystemPageSize(); +#else + size_t expected_committed_size = PartitionPageSize(); +#endif size_t expected_super_pages_size = kSuperPageSize; EXPECT_EQ(expected_committed_size, root.total_size_of_committed_pages); EXPECT_EQ(expected_super_pages_size, root.total_size_of_super_pages); @@ -2587,7 +2605,11 @@ // Allocating another size commits another slot span. ptr = root.Alloc(2 * small_size - kExtraAllocSize, type_name); +#if defined(OS_WIN) expected_committed_size += SystemPageSize(); +#else + expected_committed_size += PartitionPageSize(); +#endif EXPECT_EQ(expected_committed_size, root.total_size_of_committed_pages); EXPECT_EQ(expected_super_pages_size, root.total_size_of_super_pages);
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc index f8ef416..4d34540 100644 --- a/base/allocator/partition_allocator/partition_bucket.cc +++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -217,6 +217,14 @@ char* ret = root->next_partition_page; root->next_partition_page += slot_span_reserved_size; +#if !defined(OS_WIN) + // System pages in the super page come in a decommited state. Commit them + // before vending them back. + // Windows uses lazy commit. Pages will be committed when provisioning slots, + // in ProvisionMoreSlotsAndAllocOne(). + root->RecommitSystemPagesForData(ret, slot_span_committed_size, + PageUpdatePermissions); +#endif // Double check that we had enough space in the super page for the new slot // span. PA_DCHECK(root->next_partition_page <= root->next_partition_page_end); @@ -379,11 +387,15 @@ // to the page start and |next_slot| doesn't, thus only the latter gets // rounded up. PA_DCHECK(commit_end > commit_start); - // System pages in the slot span come in an initially decommitted state. - // Can't use PageKeepPermissionsIfPossible, because we have no knowledge - // which pages have been committed before. +#if defined(OS_WIN) + // Windows uses lazy commit, meaning system pages in the slot span come in an + // initially decommitted state. Commit them here. + // Note, we can't use PageKeepPermissionsIfPossible, because we have no + // knowledge which pages have been committed before (it doesn't matter on + // Windows anyway). root->RecommitSystemPagesForData(commit_start, commit_end - commit_start, PageUpdatePermissions); +#endif // The slot being returned is considered allocated, and no longer // unprovisioned. @@ -560,6 +572,14 @@ PA_DCHECK(new_slot_span->bucket == this); PA_DCHECK(new_slot_span->is_decommitted()); decommitted_slot_spans_head = new_slot_span->next_slot_span; +#if !defined(OS_WIN) + // Windows uses lazy commit. Pages will be recommitted when provisioning + // slots, in ProvisionMoreSlotsAndAllocOne(). + void* addr = SlotSpanMetadata<thread_safe>::ToPointer(new_slot_span); + root->RecommitSystemPagesForData( + addr, new_slot_span->bucket->get_bytes_per_span(), + PageKeepPermissionsIfPossible); +#endif new_slot_span->Reset(); *is_already_zeroed = kDecommittedPagesAreAlwaysZeroed; }
diff --git a/base/allocator/partition_allocator/partition_bucket.h b/base/allocator/partition_allocator/partition_bucket.h index a4c860f..c8d6e5b 100644 --- a/base/allocator/partition_allocator/partition_bucket.h +++ b/base/allocator/partition_allocator/partition_bucket.h
@@ -64,6 +64,21 @@ bool* is_already_zeroed) EXCLUSIVE_LOCKS_REQUIRED(root->lock_); + ALWAYS_INLINE bool CanStoreRawSize() const { + // For direct-map as well as single-slot slot spans (recognized by checking + // against |MaxSystemPagesPerSlotSpan()|), we have some spare metadata + // space in subsequent PartitionPage to store the raw size. It isn't only + // metadata space though, slot spans that have more than one slot can't have + // raw size stored, because we wouldn't know which slot it applies to. + if (LIKELY(slot_size <= MaxSystemPagesPerSlotSpan() * SystemPageSize())) + return false; + + PA_DCHECK((slot_size % SystemPageSize()) == 0); + PA_DCHECK(is_direct_mapped() || get_slots_per_span() == 1); + + return true; + } + ALWAYS_INLINE bool is_direct_mapped() const { return !num_system_pages_per_slot_span; }
diff --git a/base/allocator/partition_allocator/partition_page.cc b/base/allocator/partition_allocator/partition_page.cc index 2f93665..5131e6f 100644 --- a/base/allocator/partition_allocator/partition_page.cc +++ b/base/allocator/partition_allocator/partition_page.cc
@@ -169,7 +169,13 @@ PA_DCHECK(is_empty()); PA_DCHECK(!bucket->is_direct_mapped()); void* addr = SlotSpanMetadata::ToPointer(this); - size_t size_to_decommit = bits::Align(GetProvisionedSize(), SystemPageSize()); + size_t size_to_decommit = +#if defined(OS_WIN) + // Windows uses lazy commit, thus only provisioned slots are committed. + bits::Align(GetProvisionedSize(), SystemPageSize()); +#else + bucket->get_bytes_per_span(); +#endif // Not decommitted slot span must've had at least 1 allocation. PA_DCHECK(size_to_decommit > 0); root->DecommitSystemPagesForData(addr, size_to_decommit,
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h index d3a6938..1c776dd 100644 --- a/base/allocator/partition_allocator/partition_page.h +++ b/base/allocator/partition_allocator/partition_page.h
@@ -404,19 +404,9 @@ template <bool thread_safe> ALWAYS_INLINE bool SlotSpanMetadata<thread_safe>::CanStoreRawSize() const { - // For direct-map as well as single-slot slot spans (recognized by checking - // against |kMaxPartitionPagesPerSlotSpan|), we have some spare metadata space - // in subsequent PartitionPage to store the raw size. It isn't only metadata - // space though, slot spans that have more than one slot can't have raw size - // stored, because we wouldn't know which slot it applies to. - if (LIKELY(bucket->slot_size <= - MaxSystemPagesPerSlotSpan() * SystemPageSize())) - return false; - - PA_DCHECK((bucket->slot_size % SystemPageSize()) == 0); - PA_DCHECK(bucket->is_direct_mapped() || bucket->get_slots_per_span() == 1); - - return true; + // The answer is the same for all slot spans in a bucket, because it's based + // on the slot size. + return bucket->CanStoreRawSize(); } template <bool thread_safe>
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h index 7ff1299..f7f2552 100644 --- a/base/allocator/partition_allocator/partition_root.h +++ b/base/allocator/partition_allocator/partition_root.h
@@ -629,16 +629,16 @@ size_t raw_size, size_t* utilized_slot_size, bool* is_already_zeroed) { - *is_already_zeroed = false; - SlotSpan* slot_span = bucket->active_slot_spans_head; // Check that this slot span is neither full nor freed. PA_DCHECK(slot_span); PA_DCHECK(slot_span->num_allocated_slots >= 0); - *utilized_slot_size = bucket->slot_size; void* ret = slot_span->freelist_head; if (LIKELY(ret)) { + *is_already_zeroed = false; + *utilized_slot_size = bucket->slot_size; + // If these DCHECKs fire, you probably corrupted memory. TODO(palmer): See // if we can afford to make these CHECKs. PA_DCHECK(IsValidSlotSpan(slot_span)); @@ -646,6 +646,7 @@ // All large allocations must go through the slow path to correctly update // the size metadata. PA_DCHECK(!slot_span->CanStoreRawSize()); + PA_DCHECK(!slot_span->bucket->is_direct_mapped()); internal::PartitionFreelistEntry* new_head = slot_span->freelist_head->GetNext(); slot_span->SetFreelistHead(new_head); @@ -1026,9 +1027,6 @@ tcache = internal::ThreadCache::Create(this); with_thread_cache = true; } - // bucket->slot_size is 0 for direct-mapped allocations, as their bucket is - // the sentinel one. Since |bucket_index| is going to be kNumBuckets + 1, - // the thread cache allocation will return nullptr. ret = tcache->GetFromCache(bucket_index); is_already_zeroed = false; utilized_slot_size = bucket_at(bucket_index).slot_size; @@ -1038,18 +1036,20 @@ // for a non-thread cache allocation. if (ret) { SlotSpan* slot_span = SlotSpan::FromPointerNoAlignmentCheck(ret); + PA_DCHECK(IsValidSlotSpan(slot_span)); + PA_DCHECK(slot_span->bucket == &bucket_at(bucket_index)); // All large allocations must go through the RawAlloc path to correctly // set |utilized_slot_size|. PA_DCHECK(!slot_span->CanStoreRawSize()); - PA_DCHECK(IsValidSlotSpan(slot_span)); - PA_DCHECK(slot_span->bucket == &bucket_at(bucket_index)); + PA_DCHECK(!slot_span->bucket->is_direct_mapped()); } #endif } - if (!ret) + if (!ret) { ret = RawAlloc(buckets + bucket_index, flags, raw_size, &utilized_slot_size, &is_already_zeroed); + } if (UNLIKELY(!ret)) return nullptr;
diff --git a/base/allocator/partition_allocator/thread_cache.cc b/base/allocator/partition_allocator/thread_cache.cc index 42b0f7e..6203471 100644 --- a/base/allocator/partition_allocator/thread_cache.cc +++ b/base/allocator/partition_allocator/thread_cache.cc
@@ -9,6 +9,8 @@ #include <vector> #include "base/allocator/partition_allocator/partition_alloc.h" +#include "base/allocator/partition_allocator/partition_alloc_check.h" +#include "base/threading/thread_task_runner_handle.h" namespace base { @@ -29,6 +31,8 @@ } // namespace +constexpr base::TimeDelta ThreadCacheRegistry::kPurgeInterval; + // static ThreadCacheRegistry& ThreadCacheRegistry::Instance() { return g_instance; @@ -101,6 +105,74 @@ current_thread_tcache->Purge(); } +void ThreadCacheRegistry::StartPeriodicPurge() { + PostDelayedPurgeTask(); +} + +void ThreadCacheRegistry::PostDelayedPurgeTask() { + PA_DCHECK(!has_pending_purge_task_); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&ThreadCacheRegistry::PeriodicPurge, + base::Unretained(this)), + kPurgeInterval); + has_pending_purge_task_ = true; +} + +void ThreadCacheRegistry::PeriodicPurge() { + has_pending_purge_task_ = false; + ThreadCache* tcache = ThreadCache::Get(); + PA_DCHECK(tcache); + uint64_t allocations = tcache->stats_.alloc_count; + uint64_t allocations_since_last_purge = + allocations - allocations_at_last_purge_; + + // Purge should not run when there is little activity in the process. We + // assume that the main thread is a reasonable proxy for the process activity, + // where the main thread is the current one. + // + // If we didn't see enough allocations since the last purge, don't schedule a + // new one, and ask the thread cache to notify us of deallocations. This makes + // the next |kMinMainThreadAllocationsForPurging| deallocations slightly + // slower. + // + // Once the threshold is reached, reschedule a purge task. We count + // deallocations rather than allocations because these are the ones that fill + // the cache, and also because we already have a check on the deallocation + // path, not on the allocation one that we don't want to slow down. + bool enough_allocations = + allocations_since_last_purge >= kMinMainThreadAllocationsForPurging; + tcache->SetNotifiesRegistry(!enough_allocations); + deallocations_ = 0; + PurgeAll(); + + if (enough_allocations) { + allocations_at_last_purge_ = allocations; + PostDelayedPurgeTask(); + } +} + +void ThreadCacheRegistry::OnDeallocation() { + deallocations_++; + if (deallocations_ > kMinMainThreadAllocationsForPurging) { + ThreadCache* tcache = ThreadCache::Get(); + PA_DCHECK(tcache); + + deallocations_ = 0; + tcache->SetNotifiesRegistry(false); + + if (has_pending_purge_task_) + return; + + // This is called from the thread cache, which is called from the central + // allocator. This means that any allocation made by task posting will make + // it reentrant, unless we disable the thread cache. + tcache->Disable(); + PostDelayedPurgeTask(); + tcache->Enable(); + } +} + // static void ThreadCache::Init(PartitionRoot<ThreadSafe>* root) { PA_CHECK(root->buckets[kBucketCount - 1].slot_size == kSizeThreshold); @@ -146,8 +218,13 @@ } ThreadCache::ThreadCache(PartitionRoot<ThreadSafe>* root) - : buckets_(), stats_(), root_(root), next_(nullptr), prev_(nullptr) { - ThreadCacheRegistry::Instance().RegisterThreadCache(this); + : buckets_(), + stats_(), + root_(root), + registry_(&ThreadCacheRegistry::Instance()), + next_(nullptr), + prev_(nullptr) { + registry_->RegisterThreadCache(this); for (int index = 0; index < kBucketCount; index++) { const auto& root_bucket = root->buckets[index]; @@ -169,7 +246,7 @@ } ThreadCache::~ThreadCache() { - ThreadCacheRegistry::Instance().UnregisterThreadCache(this); + registry_->UnregisterThreadCache(this); Purge(); } @@ -215,6 +292,9 @@ size_t utilized_slot_size; bool is_already_zeroed; + PA_DCHECK(!root_->buckets[bucket_index].CanStoreRawSize()); + PA_DCHECK(!root_->buckets[bucket_index].is_direct_mapped()); + // Same as calling RawAlloc() |count| times, but acquires the lock only once. internal::ScopedGuard<internal::ThreadSafe> guard(root_->lock_); for (int i = 0; i < count; i++) { @@ -257,6 +337,22 @@ PA_DCHECK(bucket.count == limit); } +void ThreadCache::HandleNonNormalMode() { + switch (mode_.load(std::memory_order_relaxed)) { + case Mode::kPurge: + PurgeInternal(); + mode_.store(Mode::kNormal, std::memory_order_relaxed); + break; + + case Mode::kNotifyRegistry: + registry_->OnDeallocation(); + break; + + default: + break; + } +} + void ThreadCache::AccumulateStats(ThreadCacheStats* stats) const { stats->alloc_count += stats_.alloc_count; stats->alloc_hits += stats_.alloc_hits; @@ -277,9 +373,22 @@ } void ThreadCache::SetShouldPurge() { + // Purge may be triggered by an external event, in which case it should not + // take precedence over the notification mode, otherwise we risk disabling + // periodic purge entirely. + // + // Also, no other thread can set this to notification mode. + if (mode_.load(std::memory_order_relaxed) != Mode::kNormal) + return; + // We don't need any synchronization, and don't really care if the purge is // carried out "right away", hence relaxed atomics. - should_purge_.store(true, std::memory_order_relaxed); + mode_.store(Mode::kPurge, std::memory_order_relaxed); +} + +void ThreadCache::SetNotifiesRegistry(bool enabled) { + mode_.store(enabled ? Mode::kNotifyRegistry : Mode::kNormal, + std::memory_order_relaxed); } void ThreadCache::Purge() { @@ -290,8 +399,14 @@ void ThreadCache::PurgeInternal() { for (auto& bucket : buckets_) ClearBucket(bucket, 0); +} - should_purge_.store(false, std::memory_order_relaxed); +void ThreadCache::Disable() { + root_->with_thread_cache = false; +} + +void ThreadCache::Enable() { + root_->with_thread_cache = true; } } // namespace internal
diff --git a/base/allocator/partition_allocator/thread_cache.h b/base/allocator/partition_allocator/thread_cache.h index 48cbaec..3fc29c9 100644 --- a/base/allocator/partition_allocator/thread_cache.h +++ b/base/allocator/partition_allocator/thread_cache.h
@@ -19,6 +19,7 @@ #include "base/macros.h" #include "base/no_destructor.h" #include "base/partition_alloc_buildflags.h" +#include "base/sequenced_task_runner.h" #include "base/synchronization/lock.h" // Need TLS support. @@ -65,13 +66,27 @@ // a later point (during a deallocation). void PurgeAll(); + // Starts a periodic timer on the current thread to purge all thread caches. + void StartPeriodicPurge(); + void OnDeallocation(); + static PartitionLock& GetLock() { return Instance().lock_; } + bool has_pending_purge_task() const { return has_pending_purge_task_; } + + static constexpr TimeDelta kPurgeInterval = TimeDelta::FromSeconds(1); + static constexpr int kMinMainThreadAllocationsForPurging = 1000; + private: + void PeriodicPurge(); + void PostDelayedPurgeTask(); friend class NoDestructor<ThreadCacheRegistry>; // Not using base::Lock as the object's constructor must be constexpr. PartitionLock lock_; ThreadCache* list_head_ GUARDED_BY(GetLock()) = nullptr; + uint64_t allocations_at_last_purge_ = 0; + int deallocations_ = 0; + bool has_pending_purge_task_ = false; }; constexpr ThreadCacheRegistry::ThreadCacheRegistry() = default; @@ -175,12 +190,17 @@ // Asks this cache to trigger |Purge()| at a later point. Can be called from // any thread. void SetShouldPurge(); + void SetNotifiesRegistry(bool enabled); // Empties the cache. // The Partition lock must *not* be held when calling this. // Must be called from the thread this cache is for. void Purge(); void AccumulateStats(ThreadCacheStats* stats) const; + // Disables the thread cache for its associated root. + void Disable(); + void Enable(); + size_t bucket_count_for_testing(size_t index) const { return buckets_[index].count; } @@ -194,6 +214,7 @@ uint16_t count; uint16_t limit; }; + enum class Mode { kNormal, kPurge, kNotifyRegistry }; explicit ThreadCache(PartitionRoot<ThreadSafe>* root); static void Delete(void* thread_cache_ptr); @@ -203,6 +224,7 @@ // Empties the |bucket| until there are at most |limit| objects in it. void ClearBucket(Bucket& bucket, size_t limit); ALWAYS_INLINE void PutInBucket(Bucket& bucket, void* ptr); + void HandleNonNormalMode(); // TODO(lizeb): Optimize the threshold. static constexpr size_t kSizeThreshold = 512; @@ -214,10 +236,11 @@ kBucketCount < kNumBuckets, "Cannot have more cached buckets than what the allocator supports"); - std::atomic<bool> should_purge_{false}; + std::atomic<Mode> mode_{Mode::kNormal}; Bucket buckets_[kBucketCount]; ThreadCacheStats stats_; PartitionRoot<ThreadSafe>* const root_; + ThreadCacheRegistry* const registry_; #if DCHECK_IS_ON() bool is_in_thread_cache_ = false; #endif @@ -257,8 +280,8 @@ ClearBucket(bucket, bucket.limit / 2); } - if (UNLIKELY(should_purge_.load(std::memory_order_relaxed))) - PurgeInternal(); + if (UNLIKELY(mode_.load(std::memory_order_relaxed) != Mode::kNormal)) + HandleNonNormalMode(); return true; }
diff --git a/base/allocator/partition_allocator/thread_cache_unittest.cc b/base/allocator/partition_allocator/thread_cache_unittest.cc index e9b541a..b942947 100644 --- a/base/allocator/partition_allocator/thread_cache_unittest.cc +++ b/base/allocator/partition_allocator/thread_cache_unittest.cc
@@ -14,6 +14,7 @@ #include "base/callback.h" #include "base/synchronization/lock.h" #include "base/test/bind.h" +#include "base/test/task_environment.h" #include "base/threading/platform_thread.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" @@ -24,9 +25,7 @@ // With *SAN, PartitionAlloc is replaced in partition_alloc.h by ASAN, so we // cannot test the thread cache. // -// Finally, the thread cache currently uses `thread_local`, which causes issues -// on Windows 7 (at least). As long as it doesn't use something else on Windows, -// disable the cache (and tests) +// Finally, the thread cache is not supported on all platforms. #if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && \ !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) && \ defined(PA_THREAD_CACHE_SUPPORTED) @@ -103,7 +102,14 @@ ASSERT_TRUE(tcache); tcache->Purge(); } - void TearDown() override {} + + void TearDown() override { + task_env_.FastForwardUntilNoTasksRemain(); + ASSERT_FALSE(ThreadCacheRegistry::Instance().has_pending_purge_task()); + } + + base::test::TaskEnvironment task_env_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; }; TEST_F(ThreadCacheTest, Simple) { @@ -421,6 +427,103 @@ PlatformThread::Join(thread_handle); } +TEST_F(ThreadCacheTest, PeriodicPurge) { + ThreadCacheRegistry::Instance().StartPeriodicPurge(); + EXPECT_TRUE(ThreadCacheRegistry::Instance().has_pending_purge_task()); + + std::atomic<bool> other_thread_started{false}; + std::atomic<bool> purge_called{false}; + + size_t bucket_index = FillThreadCacheAndReturnIndex(kMediumSize); + ThreadCache* this_thread_tcache = g_root->thread_cache_for_testing(); + ThreadCache* other_thread_tcache = nullptr; + + LambdaThreadDelegate delegate{ + BindLambdaForTesting([&]() NO_THREAD_SAFETY_ANALYSIS { + FillThreadCacheAndReturnIndex(kMediumSize); + other_thread_tcache = g_root->thread_cache_for_testing(); + + other_thread_started.store(true, std::memory_order_release); + while (!purge_called.load(std::memory_order_acquire)) { + } + + // Purge() was not triggered from the other thread. + EXPECT_EQ(kFillCountForMediumBucket, + other_thread_tcache->bucket_count_for_testing(bucket_index)); + // Allocations do not trigger Purge(). + void* data = g_root->Alloc(1, ""); + EXPECT_EQ(kFillCountForMediumBucket, + other_thread_tcache->bucket_count_for_testing(bucket_index)); + // But deallocations do. + g_root->Free(data); + EXPECT_EQ(0u, + other_thread_tcache->bucket_count_for_testing(bucket_index)); + })}; + + PlatformThreadHandle thread_handle; + PlatformThread::Create(0, &delegate, &thread_handle); + + while (!other_thread_started.load(std::memory_order_acquire)) { + } + + EXPECT_EQ(kFillCountForMediumBucket, + this_thread_tcache->bucket_count_for_testing(bucket_index)); + EXPECT_EQ(kFillCountForMediumBucket, + other_thread_tcache->bucket_count_for_testing(bucket_index)); + + task_env_.FastForwardBy(ThreadCacheRegistry::kPurgeInterval); + // Not enough allocations since last purge, don't reschedule it. + EXPECT_FALSE(ThreadCacheRegistry::Instance().has_pending_purge_task()); + + // This thread is synchronously purged. + EXPECT_EQ(0u, this_thread_tcache->bucket_count_for_testing(bucket_index)); + // Not the other one. + EXPECT_EQ(kFillCountForMediumBucket, + other_thread_tcache->bucket_count_for_testing(bucket_index)); + + purge_called.store(true, std::memory_order_release); + PlatformThread::Join(thread_handle); +} + +TEST_F(ThreadCacheTest, PeriodicPurgeStopsAndRestarts) { + const size_t kTestSize = 100; + ThreadCacheRegistry::Instance().StartPeriodicPurge(); + EXPECT_TRUE(ThreadCacheRegistry::Instance().has_pending_purge_task()); + + size_t bucket_index = FillThreadCacheAndReturnIndex(kTestSize); + auto* tcache = ThreadCache::Get(); + EXPECT_GT(tcache->bucket_count_for_testing(bucket_index), 0u); + + task_env_.FastForwardBy(ThreadCacheRegistry::kPurgeInterval); + // Not enough allocations since last purge, don't reschedule it. + EXPECT_FALSE(ThreadCacheRegistry::Instance().has_pending_purge_task()); + + // This thread is synchronously purged. + EXPECT_EQ(0u, tcache->bucket_count_for_testing(bucket_index)); + + // 1 allocation is not enough to restart it. + FillThreadCacheAndReturnIndex(kTestSize); + EXPECT_FALSE(ThreadCacheRegistry::Instance().has_pending_purge_task()); + + for (int i = 0; i < ThreadCacheRegistry::kMinMainThreadAllocationsForPurging; + i++) { + FillThreadCacheAndReturnIndex(kTestSize); + } + EXPECT_TRUE(ThreadCacheRegistry::Instance().has_pending_purge_task()); + EXPECT_GT(tcache->bucket_count_for_testing(bucket_index), 0u); + + task_env_.FastForwardBy(ThreadCacheRegistry::kPurgeInterval); + EXPECT_EQ(0u, tcache->bucket_count_for_testing(bucket_index)); + // Since there were enough allocations, another task is posted. + EXPECT_TRUE(ThreadCacheRegistry::Instance().has_pending_purge_task()); + + FillThreadCacheAndReturnIndex(kTestSize); + task_env_.FastForwardBy(ThreadCacheRegistry::kPurgeInterval); + EXPECT_EQ(0u, tcache->bucket_count_for_testing(bucket_index)); + // Not enough this time. + EXPECT_FALSE(ThreadCacheRegistry::Instance().has_pending_purge_task()); +} + } // namespace internal } // namespace base
diff --git a/base/mac/mac_util.h b/base/mac/mac_util.h index f8275f3..8d1ccdd 100644 --- a/base/mac/mac_util.h +++ b/base/mac/mac_util.h
@@ -145,8 +145,7 @@ // Versions of macOS supported at runtime but whose SDK is not supported for // building. -DEFINE_OLD_IS_OS_FUNCS_CR_MIN_REQUIRED(10, OLD_TEST_DEPLOYMENT_TARGET) -DEFINE_OLD_IS_OS_FUNCS(11, OLD_TEST_DEPLOYMENT_TARGET) +DEFINE_OLD_IS_OS_FUNCS_CR_MIN_REQUIRED(11, OLD_TEST_DEPLOYMENT_TARGET) DEFINE_OLD_IS_OS_FUNCS(12, OLD_TEST_DEPLOYMENT_TARGET) DEFINE_OLD_IS_OS_FUNCS(13, OLD_TEST_DEPLOYMENT_TARGET) DEFINE_OLD_IS_OS_FUNCS(14, OLD_TEST_DEPLOYMENT_TARGET)
diff --git a/base/mac/mac_util_unittest.mm b/base/mac/mac_util_unittest.mm index 6266fda..f0a40d18 100644 --- a/base/mac/mac_util_unittest.mm +++ b/base/mac/mac_util_unittest.mm
@@ -174,23 +174,10 @@ EXPECT_FALSE(IsAtLeastOS##V()); if (major == 10) { - if (minor == 10) { - EXPECT_TRUE(IsOS10_10()); - EXPECT_TRUE(IsAtMostOS10_10()); + if (minor == 11) { + EXPECT_TRUE(IsOS10_11()); + EXPECT_TRUE(IsAtMostOS10_11()); - TEST_FOR_FUTURE_10_OS(11); - TEST_FOR_FUTURE_10_OS(12); - TEST_FOR_FUTURE_10_OS(13); - TEST_FOR_FUTURE_10_OS(14); - TEST_FOR_FUTURE_10_OS(15); - TEST_FOR_FUTURE_OS(11); - - EXPECT_FALSE(IsOSLaterThan11_DontCallThis()); - } else if (minor == 11) { - EXPECT_FALSE(IsOS10_10()); - EXPECT_FALSE(IsAtMostOS10_10()); - - TEST_FOR_SAME_10_OS(11); TEST_FOR_FUTURE_10_OS(12); TEST_FOR_FUTURE_10_OS(13); TEST_FOR_FUTURE_10_OS(14); @@ -199,10 +186,9 @@ EXPECT_FALSE(IsOSLaterThan11_DontCallThis()); } else if (minor == 12) { - EXPECT_FALSE(IsOS10_10()); - EXPECT_FALSE(IsAtMostOS10_10()); + EXPECT_FALSE(IsOS10_11()); + EXPECT_FALSE(IsAtMostOS10_11()); - TEST_FOR_PAST_10_OS(11); TEST_FOR_SAME_10_OS(12); TEST_FOR_FUTURE_10_OS(13); TEST_FOR_FUTURE_10_OS(14); @@ -211,10 +197,9 @@ EXPECT_FALSE(IsOSLaterThan11_DontCallThis()); } else if (minor == 13) { - EXPECT_FALSE(IsOS10_10()); - EXPECT_FALSE(IsAtMostOS10_10()); + EXPECT_FALSE(IsOS10_11()); + EXPECT_FALSE(IsAtMostOS10_11()); - TEST_FOR_PAST_10_OS(11); TEST_FOR_PAST_10_OS(12); TEST_FOR_SAME_10_OS(13); TEST_FOR_FUTURE_10_OS(14); @@ -223,10 +208,9 @@ EXPECT_FALSE(IsOSLaterThan11_DontCallThis()); } else if (minor == 14) { - EXPECT_FALSE(IsOS10_10()); - EXPECT_FALSE(IsAtMostOS10_10()); + EXPECT_FALSE(IsOS10_11()); + EXPECT_FALSE(IsAtMostOS10_11()); - TEST_FOR_PAST_10_OS(11); TEST_FOR_PAST_10_OS(12); TEST_FOR_PAST_10_OS(13); TEST_FOR_SAME_10_OS(14); @@ -235,10 +219,9 @@ EXPECT_FALSE(IsOSLaterThan11_DontCallThis()); } else if (minor == 15) { - EXPECT_FALSE(IsOS10_10()); - EXPECT_FALSE(IsAtMostOS10_10()); + EXPECT_FALSE(IsOS10_11()); + EXPECT_FALSE(IsAtMostOS10_11()); - TEST_FOR_PAST_10_OS(11); TEST_FOR_PAST_10_OS(12); TEST_FOR_PAST_10_OS(13); TEST_FOR_PAST_10_OS(14); @@ -251,10 +234,9 @@ EXPECT_TRUE(false); } } else if (major == 11) { - EXPECT_FALSE(IsOS10_10()); - EXPECT_FALSE(IsAtMostOS10_10()); + EXPECT_FALSE(IsOS10_11()); + EXPECT_FALSE(IsAtMostOS10_11()); - TEST_FOR_PAST_10_OS(11); TEST_FOR_PAST_10_OS(12); TEST_FOR_PAST_10_OS(13); TEST_FOR_PAST_10_OS(14);
diff --git a/base/power_monitor/power_monitor_device_source_mac.mm b/base/power_monitor/power_monitor_device_source_mac.mm index 54a2215..7ab0b5c9 100644 --- a/base/power_monitor/power_monitor_device_source_mac.mm +++ b/base/power_monitor/power_monitor_device_source_mac.mm
@@ -69,10 +69,7 @@ PowerObserver::DeviceThermalState PowerMonitorDeviceSource::GetCurrentThermalState() { - if (@available(macOS 10.10.3, *)) { - return thermal_state_observer_->GetCurrentThermalState(); - }; - return PowerObserver::DeviceThermalState::kUnknown; + return thermal_state_observer_->GetCurrentThermalState(); } namespace { @@ -107,10 +104,8 @@ CFRunLoopAddSource(CFRunLoopGetCurrent(), power_source_run_loop_source_, kCFRunLoopDefaultMode); - if (@available(macOS 10.10.3, *)) { - thermal_state_observer_ = std::make_unique<ThermalStateObserverMac>( - BindRepeating(&PowerMonitorSource::ProcessThermalEvent)); - }; + thermal_state_observer_ = std::make_unique<ThermalStateObserverMac>( + BindRepeating(&PowerMonitorSource::ProcessThermalEvent)); } void PowerMonitorDeviceSource::PlatformDestroy() {
diff --git a/build/android/adb_gdb b/build/android/adb_gdb index bd0f1f3..6de4273 100755 --- a/build/android/adb_gdb +++ b/build/android/adb_gdb
@@ -821,7 +821,7 @@ # Remove the fingerprint file in case pulling one of the libs fails. rm -f "$PULL_LIBS_DIR/build.fingerprint" SYSTEM_LIBS=$(echo "$MAPPINGS" | \ - awk '$6 ~ /\/system\/.*\.so$/ { print $6; }' | sort -u) + awk '$6 ~ /\/(system|apex|vendor)\/.*\.so$/ { print $6; }' | sort -u) for SYSLIB in /system/bin/linker$SUFFIX_64_BIT $SYSTEM_LIBS; do echo "Pulling from device: $SYSLIB" DST_FILE=$PULL_LIBS_DIR$SYSLIB
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 09175ac8..9e472bef 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -233,9 +233,8 @@ use_debug_fission == "default" || use_debug_fission || !use_debug_fission, "Invalid use_debug_fission.") if (use_debug_fission == "default") { - use_debug_fission = (is_android && is_official_build) || - (is_debug && !is_android && !is_fuchsia && !is_apple && - !is_win && (use_gold || use_lld) && cc_wrapper == "") + use_debug_fission = is_debug && !is_android && !is_fuchsia && !is_apple && + !is_win && (use_gold || use_lld) && cc_wrapper == "" } # If it wasn't manually set, set to an appropriate default.
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index b206e09..1a9a5740 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20201203.3.1 +0.20201204.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index d1d50ac..1a9a5740 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20201203.4.1 +0.20201204.1.1
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java index cb2bbc7..5211c43 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java
@@ -30,6 +30,7 @@ import org.chromium.chrome.browser.autofill_assistant.header.AssistantHeaderCoordinator; import org.chromium.chrome.browser.autofill_assistant.header.AssistantHeaderModel; import org.chromium.chrome.browser.autofill_assistant.infobox.AssistantInfoBoxCoordinator; +import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayCoordinator; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataCoordinator; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataModel; import org.chromium.chrome.browser.ui.TabObscuringHandler; @@ -54,6 +55,7 @@ private static final int CHANGE_BOUNDS_TRANSITION_TIME_MS = 250; private final AssistantModel mModel; + private final AssistantOverlayCoordinator mOverlayCoordinator; private final BottomSheetController mBottomSheetController; private final TabObscuringHandler mTabObscuringHandler; private final AssistantBottomSheetContent mContent; @@ -100,10 +102,11 @@ private int mShadowHeight; AssistantBottomBarCoordinator(Activity activity, AssistantModel model, - BottomSheetController controller, + AssistantOverlayCoordinator overlayCoordinator, BottomSheetController controller, ApplicationViewportInsetSupplier applicationViewportInsetSupplier, TabObscuringHandler tabObscuringHandler) { mModel = model; + mOverlayCoordinator = overlayCoordinator; mBottomSheetController = controller; mTabObscuringHandler = tabObscuringHandler; @@ -206,6 +209,14 @@ if (newState != BottomSheetController.SheetState.SCROLLING) { maybeShowHeaderChips(); } + + if (newState == SheetState.HIDDEN) { + mOverlayCoordinator.suppress(); + } + if (newState == SheetState.PEEK || newState == SheetState.HALF + || newState == SheetState.FULL) { + mOverlayCoordinator.restore(); + } } @Override
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java index 1939a19..0f8bdb32 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java
@@ -45,9 +45,10 @@ controller.getScrimCoordinator(), mModel.getOverlayModel()); } - mBottomBarCoordinator = new AssistantBottomBarCoordinator(activity, mModel, controller, - activity.getWindowAndroid().getApplicationBottomInsetProvider(), - tabObscuringHandler); + mBottomBarCoordinator = + new AssistantBottomBarCoordinator(activity, mModel, mOverlayCoordinator, controller, + activity.getWindowAndroid().getApplicationBottomInsetProvider(), + tabObscuringHandler); mKeyboardCoordinator = new AssistantKeyboardCoordinator(activity, activity.getWindowAndroid().getKeyboardDelegate(), activity.getCompositorViewHolder(), mModel, keyboardCoordinatorDelegate, @@ -57,9 +58,9 @@ /** Detaches and destroys the view. */ public void destroy() { mModel.setVisible(false); - mOverlayCoordinator.destroy(); mBottomBarCoordinator.destroy(); mBottomBarCoordinator = null; + mOverlayCoordinator.destroy(); } /**
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinator.java index 2c1149d..0e359f67 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantOnboardingCoordinator.java
@@ -156,12 +156,16 @@ mBottomSheetObserver = new EmptyBottomSheetObserver() { @Override public void onSheetStateChanged(int newState) { + if (mOverlayCoordinator == null) { + return; + } + if (newState == SheetState.HIDDEN) { - overlayModel.set(AssistantOverlayModel.STATE, AssistantOverlayState.HIDDEN); + mOverlayCoordinator.suppress(); } if (newState == SheetState.PEEK || newState == SheetState.HALF || newState == SheetState.FULL) { - overlayModel.set(AssistantOverlayModel.STATE, AssistantOverlayState.FULL); + mOverlayCoordinator.restore(); } } }; @@ -210,6 +214,8 @@ /** Hides the UI, if one is shown. */ void hide() { + mController.removeObserver(mBottomSheetObserver); + if (mOverlayCoordinator != null) { mOverlayCoordinator.destroy(); mOverlayCoordinator = null; @@ -224,8 +230,6 @@ mWebContentsObserver.destroy(); mWebContentsObserver = null; } - - mController.removeObserver(mBottomSheetObserver); } /**
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java index 4124fb6..f83fc61 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java
@@ -7,12 +7,8 @@ import android.content.Context; import android.graphics.RectF; -import org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiController; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.compositor.CompositorViewHolder; -import org.chromium.chrome.browser.image_fetcher.ImageFetcher; -import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig; -import org.chromium.chrome.browser.image_fetcher.ImageFetcherFactory; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; import org.chromium.components.browser_ui.widget.scrim.ScrimProperties; @@ -30,22 +26,13 @@ private final AssistantOverlayDrawable mDrawable; private final CompositorViewHolder mCompositorViewHolder; private final ScrimCoordinator mScrim; - private final ImageFetcher mImageFetcher; private boolean mScrimEnabled; + private boolean mScrimSuppressed; public AssistantOverlayCoordinator(Context context, BrowserControlsStateProvider browserControls, CompositorViewHolder compositorViewHolder, ScrimCoordinator scrim, AssistantOverlayModel model) { - this(context, browserControls, compositorViewHolder, scrim, model, - ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY, - AutofillAssistantUiController.getProfile())); - } - - public AssistantOverlayCoordinator(Context context, - BrowserControlsStateProvider browserControls, CompositorViewHolder compositorViewHolder, - ScrimCoordinator scrim, AssistantOverlayModel model, ImageFetcher imageFetcher) { mModel = model; - mImageFetcher = imageFetcher; mCompositorViewHolder = compositorViewHolder; mScrim = scrim; mEventFilter = @@ -103,9 +90,29 @@ } /** + * Suppress the Scrim. + */ + public void suppress() { + mScrimSuppressed = true; + setScrimEnabled(false); + } + + /** + * Restore the Scrim to the current state. + */ + public void restore() { + mScrimSuppressed = false; + setState(mModel.get(AssistantOverlayModel.STATE)); + } + + /** * Set the overlay state. */ private void setState(@AssistantOverlayState int state) { + if (mScrimSuppressed) { + return; + } + if (state == AssistantOverlayState.PARTIAL && ChromeAccessibilityUtil.get().isAccessibilityEnabled()) { // Touch exploration is fully disabled if there's an overlay in front. In this case, the
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantChromeTabIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantChromeTabIntegrationTest.java index c989b511..d12bf9ac 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantChromeTabIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantChromeTabIntegrationTest.java
@@ -46,6 +46,7 @@ import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto; import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto; +import org.chromium.chrome.browser.autofill_assistant.proto.ChipType; import org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto.PeekMode; import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto; import org.chromium.chrome.browser.autofill_assistant.proto.StopProto; @@ -489,7 +490,6 @@ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1131835") public void interactingWithLocationBarHidesAutofillAssistant() { ArrayList<ActionProto> list = new ArrayList<>(); list.add((ActionProto) ActionProto.newBuilder() @@ -508,6 +508,8 @@ startAutofillAssistantOnTab(TEST_PAGE_A); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); + waitUntilViewMatchesCondition(is(mScrimCoordinator.getViewForTesting()), + withEffectiveVisibility(Visibility.VISIBLE)); // Clicking location bar hides UI and shows the keyboard. onView(withId(org.chromium.chrome.R.id.url_bar)).perform(click()); @@ -517,6 +519,8 @@ // Closing keyboard brings it back. Espresso.pressBack(); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); + waitUntilViewMatchesCondition(is(mScrimCoordinator.getViewForTesting()), + withEffectiveVisibility(Visibility.VISIBLE)); // Committing URL shows error. onView(withId(org.chromium.chrome.R.id.url_bar)) @@ -526,6 +530,56 @@ @Test @MediumTest + public void interactingWithLocationBarDoesNotShowHiddenScrim() { + ArrayList<ActionProto> list = new ArrayList<>(); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder() + .setMessage("Browse") + .setBrowseMode(true) + .addChoices(PromptProto.Choice.newBuilder().setChip( + ChipProto.newBuilder() + .setType(ChipType.HIGHLIGHTED_ACTION) + .setText("Continue")))) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder().setMessage("Prompt").addChoices( + PromptProto.Choice.newBuilder())) + .build()); + + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + (SupportedScriptProto) SupportedScriptProto.newBuilder() + .setPath(TEST_PAGE_A) + .setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip( + ChipProto.newBuilder().setText("Done"))) + .build(), + list); + setupScripts(script); + startAutofillAssistantOnTab(TEST_PAGE_A); + + // Browse mode hides the Scrim. + waitUntilViewMatchesCondition(withText("Browse"), isCompletelyDisplayed()); + waitUntilViewMatchesCondition(is(mScrimCoordinator.getViewForTesting()), + not(withEffectiveVisibility(Visibility.VISIBLE))); + + // Clicking location bar hides UI and shows the keyboard. + onView(withId(org.chromium.chrome.R.id.url_bar)).perform(click()); + waitUntilViewMatchesCondition(withText("Browse"), not(isDisplayed())); + waitUntilKeyboardMatchesCondition(mTestRule, /* isShowing= */ true); + + // Closing keyboard brings back the UI but does not restore the Scrim. + Espresso.pressBack(); + waitUntilViewMatchesCondition(withText("Browse"), isCompletelyDisplayed()); + waitUntil(() -> mScrimCoordinator.getViewForTesting() == null); + + // Running the next action brings back the Scrim. + onView(withText("Continue")).perform(click()); + waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); + waitUntilViewMatchesCondition(is(mScrimCoordinator.getViewForTesting()), + withEffectiveVisibility(Visibility.VISIBLE)); + } + + @Test + @MediumTest public void switchingBackToTabWithStoppedAutofillAssistantShowsErrorMessage() { ArrayList<ActionProto> list = new ArrayList<>(); list.add((ActionProto) ActionProto.newBuilder()
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java index f49d12e0..07c8e1e 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java
@@ -93,17 +93,14 @@ private AssistantOverlayCoordinator createCoordinator( AssistantOverlayModel model, @Nullable Bitmap overlayImage) throws ExecutionException { ChromeActivity activity = mTestRule.getActivity(); - return runOnUiThreadBlocking( - () - -> new AssistantOverlayCoordinator(activity, - activity.getBrowserControlsManager(), - activity.getCompositorViewHolder(), - mTestRule.getActivity() - .getRootUiCoordinatorForTesting() - .getScrimCoordinator(), - model, - new AutofillAssistantUiTestUtil.MockImageFetcher( - overlayImage, null))); + return runOnUiThreadBlocking(() + -> new AssistantOverlayCoordinator(activity, + activity.getBrowserControlsManager(), + activity.getCompositorViewHolder(), + mTestRule.getActivity() + .getRootUiCoordinatorForTesting() + .getScrimCoordinator(), + model)); } /** Tests assumptions about the initial state of the infobox. */
diff --git a/chrome/android/features/keyboard_accessory/BUILD.gn b/chrome/android/features/keyboard_accessory/BUILD.gn index ce94f00..180261d 100644 --- a/chrome/android/features/keyboard_accessory/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/BUILD.gn
@@ -80,6 +80,7 @@ "//content/public/test/android:content_java_test_support", "//net/android:net_java_test_support", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_deps:espresso_java",
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_option_toggle.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_option_toggle.xml index 6e3d304..1d3df1d 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_option_toggle.xml +++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_option_toggle.xml
@@ -37,7 +37,7 @@ android:textAppearance="@style/TextAppearance.TextMedium.Secondary" /> </LinearLayout> - <android.widget.Switch + <androidx.appcompat.widget.SwitchCompat android:id="@+id/option_toggle_switch" android:layout_marginStart="16dp" android:layout_width="48dp"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AccessorySheetTabViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AccessorySheetTabViewBinder.java index 6c60169..561abdb9 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AccessorySheetTabViewBinder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AccessorySheetTabViewBinder.java
@@ -8,11 +8,11 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; -import android.widget.Switch; import android.widget.TextView; import androidx.annotation.LayoutRes; import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -119,7 +119,7 @@ TextView subtitleText = view.findViewById(R.id.option_toggle_subtitle); subtitleText.setText(optionToggle.isEnabled() ? R.string.text_on : R.string.text_off); - Switch switchView = view.findViewById(R.id.option_toggle_switch); + SwitchCompat switchView = view.findViewById(R.id.option_toggle_switch); switchView.setChecked(optionToggle.isEnabled()); switchView.setBackground(null); }
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java index 5fcd9ee..07630d7 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java
@@ -19,9 +19,9 @@ import android.text.method.PasswordTransformationMethod; import android.view.View; import android.view.ViewGroup; -import android.widget.Switch; import android.widget.TextView; +import androidx.appcompat.widget.SwitchCompat; import androidx.recyclerview.widget.RecyclerView; import androidx.test.filters.MediumTest; @@ -198,8 +198,8 @@ View switchView = mView.get().findViewById(R.id.option_toggle_switch); assertThat(switchView, is(not(nullValue()))); - assertThat(switchView, instanceOf(Switch.class)); - assertFalse(((Switch) switchView).isChecked()); + assertThat(switchView, instanceOf(SwitchCompat.class)); + assertFalse(((SwitchCompat) switchView).isChecked()); } @Test
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceViewBinder.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceViewBinder.java index 97c97c2..bbbd842 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceViewBinder.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceViewBinder.java
@@ -9,12 +9,15 @@ import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_BOTTOM_BAR_VISIBLE; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_EXPLORE_SURFACE_VISIBLE; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SHOWING_OVERVIEW; +import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.RESET_FEED_SURFACE_SCROLL_POSITION; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.TOP_MARGIN; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import androidx.recyclerview.widget.RecyclerView; + import org.chromium.ui.UiUtils; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -30,6 +33,8 @@ model.get(IS_EXPLORE_SURFACE_VISIBLE) && model.get(IS_SHOWING_OVERVIEW)); } else if (propertyKey == TOP_MARGIN) { setTopMargin(model); + } else if (propertyKey == RESET_FEED_SURFACE_SCROLL_POSITION) { + resetScrollPosition(model); } } @@ -76,4 +81,14 @@ layoutParams.topMargin = model.get(TOP_MARGIN); feedSurfaceView.setLayoutParams(layoutParams); } + + private static void resetScrollPosition(PropertyModel model) { + if (model.get(FEED_SURFACE_COORDINATOR) == null) return; + + RecyclerView feedStreamView = + (RecyclerView) model.get(FEED_SURFACE_COORDINATOR).getStream().getView(); + if (feedStreamView != null) { + feedStreamView.scrollToPosition(0); + } + } }
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 f0214c50..23acb3db 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
@@ -14,6 +14,7 @@ import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MORE_TABS_CLICK_LISTENER; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MV_TILES_CONTAINER_TOP_MARGIN; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MV_TILES_VISIBLE; +import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.RESET_TASK_SURFACE_HEADER_SCROLL_POSITION; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.TAB_SWITCHER_TITLE_TOP_MARGIN; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.TASKS_SURFACE_BODY_TOP_MARGIN; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.TRENDY_TERMS_VISIBLE; @@ -26,6 +27,7 @@ import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SECONDARY_SURFACE_VISIBLE; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SHOWING_OVERVIEW; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SHOWING_STACK_TAB_SWITCHER; +import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.RESET_FEED_SURFACE_SCROLL_POSITION; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.TOP_MARGIN; import android.content.Context; @@ -422,6 +424,13 @@ if (mPropertyModel == null || state == mStartSurfaceState) return; + // When entering the Start surface by tapping home button or new tab page, we need to reset + // the scrolling position. + if (state == StartSurfaceState.SHOWING_HOMEPAGE) { + mPropertyModel.set(RESET_TASK_SURFACE_HEADER_SCROLL_POSITION, true); + mPropertyModel.set(RESET_FEED_SURFACE_SCROLL_POSITION, true); + } + // Cache previous state. if (mStartSurfaceState != StartSurfaceState.NOT_SHOWN) { mPreviousStartSurfaceState = mStartSurfaceState;
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceProperties.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceProperties.java index 913e0e7..89670c98 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceProperties.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceProperties.java
@@ -43,8 +43,11 @@ new PropertyModel.WritableObjectPropertyKey<FeedSurfaceCoordinator>(); public static final PropertyModel.WritableIntPropertyKey TOP_MARGIN = new PropertyModel.WritableIntPropertyKey(); + public static final PropertyModel.WritableObjectPropertyKey RESET_FEED_SURFACE_SCROLL_POSITION = + new PropertyModel.WritableObjectPropertyKey<>(true /* skipEquality */); public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {BOTTOM_BAR_CLICKLISTENER, BOTTOM_BAR_HEIGHT, BOTTOM_BAR_SELECTED_TAB_POSITION, IS_BOTTOM_BAR_VISIBLE, IS_EXPLORE_SURFACE_VISIBLE, IS_SECONDARY_SURFACE_VISIBLE, IS_SHOWING_OVERVIEW, - IS_SHOWING_STACK_TAB_SWITCHER, FEED_SURFACE_COORDINATOR, TOP_MARGIN}; + IS_SHOWING_STACK_TAB_SWITCHER, FEED_SURFACE_COORDINATOR, TOP_MARGIN, + RESET_FEED_SURFACE_SCROLL_POSITION}; }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java index a623bde..18c1086 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -64,6 +64,8 @@ import androidx.test.espresso.matcher.ViewMatchers; import androidx.test.filters.MediumTest; +import com.google.android.material.appbar.AppBarLayout; + import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.Matchers; @@ -1499,6 +1501,49 @@ assertTrue(bottomSheetTestSupport.hasSuppressionTokens()); } + @Test + @MediumTest + @Feature({"StartSurface"}) + // clang-format off + @CommandLineFlags.Add({BASE_PARAMS + "/single"}) + public void testShow_SingleAsHomepage_ResetScrollPosition() { + // clang-format on + if (!mImmediateReturn) { + onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click()); + } + + ChromeTabbedActivity cta = mActivityTestRule.getActivity(); + CriteriaHelper.pollUiThread( + () -> cta.getLayoutManager() != null && cta.getLayoutManager().overviewVisible()); + waitForTabModel(); + TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0); + + // Scroll the toolbar. + scrollToolbar(); + AppBarLayout taskSurfaceHeader = + cta.findViewById(org.chromium.chrome.tab_ui.R.id.task_surface_header); + assertNotEquals(taskSurfaceHeader.getBottom(), taskSurfaceHeader.getHeight()); + + // Verifies the case of scrolling Start surface -> tab switcher -> tap "+1" button -> + // Start surface. The Start surface should reset its scroll position. + try { + TestThreadUtils.runOnUiThreadBlocking( + () + -> mActivityTestRule.getActivity() + .findViewById(org.chromium.chrome.tab_ui.R.id.more_tabs) + .performClick()); + } catch (ExecutionException e) { + fail("Failed to tap 'more tabs' " + e.toString()); + } + + onViewWaiting(withId(R.id.secondary_tasks_surface_view)); + TestThreadUtils.runOnUiThreadBlocking(() -> cta.getTabCreator(false).launchNTP()); + onViewWaiting( + allOf(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container), isDisplayed())); + + assertEquals(taskSurfaceHeader.getBottom(), taskSurfaceHeader.getHeight()); + } + private static Matcher<View> isView(final View targetView) { return new TypeSafeMatcher<View>() { @Override @@ -1527,6 +1572,16 @@ // requires mImmediateReturn to be true. assumeTrue(mImmediateReturn); + scrollToolbar(); + + // Check the toolbar's background color. + ToolbarPhone toolbar = + mActivityTestRule.getActivity().findViewById(org.chromium.chrome.R.id.toolbar); + Assert.assertEquals(toolbar.getToolbarDataProvider().getPrimaryColor(), + toolbar.getBackgroundDrawable().getColor()); + } + + private void scrollToolbar() { onViewWaiting(allOf(withId(R.id.feed_stream_recycler_view), isDisplayed())); // Default scrollTo() cannot be used for RecyclerView. Add a customized scrollTo for @@ -1570,12 +1625,6 @@ // Toolbar container view should show. onView(withId(R.id.toolbar_container)).check(matches(isDisplayed())); - - // Check the toolbar's background color. - ToolbarPhone toolbar = - mActivityTestRule.getActivity().findViewById(org.chromium.chrome.R.id.toolbar); - Assert.assertEquals(toolbar.getToolbarDataProvider().getPrimaryColor(), - toolbar.getBackgroundDrawable().getColor()); } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceProperties.java index 85af37f..5a034a9 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceProperties.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceProperties.java
@@ -75,6 +75,9 @@ new PropertyModel.WritableIntPropertyKey(); public static final PropertyModel.WritableBooleanPropertyKey TRENDY_TERMS_VISIBLE = new PropertyModel.WritableBooleanPropertyKey(); + public static final PropertyModel + .WritableObjectPropertyKey RESET_TASK_SURFACE_HEADER_SCROLL_POSITION = + new PropertyModel.WritableObjectPropertyKey<>(true /* skipEquality */); public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {IS_FAKE_SEARCH_BOX_VISIBLE, IS_INCOGNITO, IS_INCOGNITO_DESCRIPTION_INITIALIZED, IS_INCOGNITO_DESCRIPTION_VISIBLE, IS_SURFACE_BODY_VISIBLE, IS_TAB_CAROUSEL_VISIBLE, IS_VOICE_RECOGNITION_BUTTON_VISIBLE, @@ -85,5 +88,6 @@ INCOGNITO_LEARN_MORE_CLICK_LISTENER, FAKE_SEARCH_BOX_CLICK_LISTENER, FAKE_SEARCH_BOX_TEXT_WATCHER, MORE_TABS_CLICK_LISTENER, MV_TILES_VISIBLE, VOICE_SEARCH_BUTTON_CLICK_LISTENER, TASKS_SURFACE_BODY_TOP_MARGIN, - MV_TILES_CONTAINER_TOP_MARGIN, TAB_SWITCHER_TITLE_TOP_MARGIN, TRENDY_TERMS_VISIBLE}; + MV_TILES_CONTAINER_TOP_MARGIN, TAB_SWITCHER_TITLE_TOP_MARGIN, TRENDY_TERMS_VISIBLE, + RESET_TASK_SURFACE_HEADER_SCROLL_POSITION}; }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksView.java index 1a594c7..eb21254 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksView.java
@@ -342,6 +342,14 @@ } /** + * Reset the scrolling position by expanding the {@link #mHeaderView}. + */ + void resetScrollPosition() { + if (mHeaderView != null && mHeaderView.getHeight() != mHeaderView.getBottom()) { + mHeaderView.setExpanded(true); + } + } + /** * Add a header offset change listener. * @param onOffsetChangedListener The given header offset change listener. */
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksViewBinder.java index c6835ea..971be0d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksViewBinder.java
@@ -23,6 +23,7 @@ import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MORE_TABS_CLICK_LISTENER; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MV_TILES_CONTAINER_TOP_MARGIN; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.MV_TILES_VISIBLE; +import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.RESET_TASK_SURFACE_HEADER_SCROLL_POSITION; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.TAB_SWITCHER_TITLE_TOP_MARGIN; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.TASKS_SURFACE_BODY_TOP_MARGIN; import static org.chromium.chrome.browser.tasks.TasksSurfaceProperties.TRENDY_TERMS_VISIBLE; @@ -98,6 +99,8 @@ view.setTabSwitcherTitleTopMargin(model.get(TAB_SWITCHER_TITLE_TOP_MARGIN)); } else if (propertyKey == TRENDY_TERMS_VISIBLE) { view.setTrendyTermsVisibility(model.get(TRENDY_TERMS_VISIBLE)); + } else if (propertyKey == RESET_TASK_SURFACE_HEADER_SCROLL_POSITION) { + view.resetScrollPosition(); } } }
diff --git a/chrome/android/java/res/layout/start_top_toolbar.xml b/chrome/android/java/res/layout/start_top_toolbar.xml index 479e87a..1d3343ad 100644 --- a/chrome/android/java/res/layout/start_top_toolbar.xml +++ b/chrome/android/java/res/layout/start_top_toolbar.xml
@@ -14,6 +14,7 @@ android:visibility="gone"> <Switch + tools:ignore="UseSwitchCompatOrMaterialXml" android:id="@+id/incognito_switch" android:layout_width="wrap_content" android:layout_height="wrap_content"
diff --git a/chrome/android/java/res/layout/tab_switcher_toolbar.xml b/chrome/android/java/res/layout/tab_switcher_toolbar.xml index b7404b6..7248a68b 100644 --- a/chrome/android/java/res/layout/tab_switcher_toolbar.xml +++ b/chrome/android/java/res/layout/tab_switcher_toolbar.xml
@@ -6,6 +6,7 @@ <org.chromium.chrome.browser.toolbar.top.TabSwitcherModeTTPhone xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:id="@+id/tab_switcher_toolbar" android:layout_width="match_parent" android:layout_height="@dimen/toolbar_height_no_shadow" @@ -89,7 +90,8 @@ android:paddingEnd="16dp" android:thumb="@drawable/incognito_switch" android:track="@drawable/incognito_switch_track" - android:visibility="gone"/> + android:visibility="gone" + tools:ignore="UseSwitchCompatOrMaterialXml"/> <include layout="@layout/menu_button" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java index 02ed7d5b..213afa588 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -184,7 +184,7 @@ mCurrentPopulator.onMenuClosed(); mCurrentPopulator = null; } - if (LensUtils.enableImageChip(mIsIncognito)) { + if (mChipDelegate != null) { // If the image was being classified terminate the classification // Has no effect if the classification already succeeded. mChipDelegate.onMenuClosed();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java index e373938..67da2910 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java
@@ -86,8 +86,8 @@ .findViewById(R.id.account_picker_selected_account); mDismissButton = mViewFlipper.getChildAt(ViewState.COLLAPSED_ACCOUNT_LIST) .findViewById(R.id.account_picker_dismiss_button); - if (AccountPickerFeatureUtils.shouldShowNoThanksOnDismissButton()) { - mDismissButton.setText(R.string.no_thanks); + if (AccountPickerFeatureUtils.shouldHideDismissButton()) { + mDismissButton.setVisibility(View.GONE); } // TODO(https://crbug.com/1146990): Use different continue buttons for different view
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerFeatureUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerFeatureUtils.java index 2f6dc9c..a06e7c7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerFeatureUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerFeatureUtils.java
@@ -10,12 +10,12 @@ * This class is used to handle state of feature flags in the project * MobileIdentityConsistency. */ -public class AccountPickerFeatureUtils { +class AccountPickerFeatureUtils { private static final String DISMISS_BUTTON_PARAM = "dismiss_button"; - private static final String DISMISS_BUTTON_NO_THANKS = "no_thanks"; + private static final String HIDE_DISMISS_BUTTON = "hide"; - static boolean shouldShowNoThanksOnDismissButton() { - return DISMISS_BUTTON_NO_THANKS.equals(ChromeFeatureList.getFieldTrialParamByFeature( + static boolean shouldHideDismissButton() { + return HIDE_DISMISS_BUTTON.equals(ChromeFeatureList.getFieldTrialParamByFeature( ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY_VAR, DISMISS_BUTTON_PARAM)); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/IncognitoSwitchCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/IncognitoSwitchCoordinator.java index c58657f..ef77422 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/IncognitoSwitchCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/IncognitoSwitchCoordinator.java
@@ -31,6 +31,7 @@ private TabModelSelector mTabModelSelector; private TabModelSelectorObserver mTabModelSelectorObserver; + @SuppressWarnings({"UseSwitchCompatOrMaterialCode"}) public IncognitoSwitchCoordinator(ViewGroup root, TabModelSelector tabModelSelector) { assert tabModelSelector != null; mTabModelSelector = tabModelSelector;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/IncognitoSwitchViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/IncognitoSwitchViewBinder.java index 8f1d8e2..a00820a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/IncognitoSwitchViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/IncognitoSwitchViewBinder.java
@@ -24,6 +24,7 @@ * Build a binder that handles interaction between the model and the view that make up the * incognito switch. */ + @SuppressWarnings({"UseSwitchCompatOrMaterialCode"}) public static void bind(PropertyModel model, Switch incognitoSwitch, PropertyKey propertyKey) { if (IncognitoSwitchProperties.ON_CHECKED_CHANGE_LISTENER == propertyKey) { incognitoSwitch.setOnCheckedChangeListener(
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 7c642d5..be98975 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-89.0.4342.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-89.0.4343.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index dd01b838..c135928 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -5467,6 +5467,9 @@ <message name="IDS_ACCOUNT_MANAGER_WELCOME_BUTTON" desc="Label for the button to view accounts on the Chrome OS Account Manager Welcome screen."> View accounts </message> + <message name="IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_TITLE" desc="Title for the Welcome screen in Chrome OS 'Add account' dialog."> + Add a secondary Google Account for <ph name="USER_NAME">$1<ex>John</ex></ph> + </message> <message name="IDS_ACCOUNT_MANAGER_ERROR_NO_INTERNET_TITLE" desc="Title for the network error screen."> No Internet </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY.png.sha1 new file mode 100644 index 0000000..c56808f --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY.png.sha1
@@ -0,0 +1 @@ +1bd4e289cc5474bbdd1909fad5d723269a25a306 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_TITLE.png.sha1 new file mode 100644 index 0000000..91679cc5 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_TITLE.png.sha1
@@ -0,0 +1 @@ +c4dd21a1e21ef55bd5ef3c9d17df911348efa325 \ No newline at end of file
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index c20506d..858376d51 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -1091,6 +1091,14 @@ </message> </if> + <!-- Chrome OS in-session 'Add account' flow --> + <if expr="chromeos"> + <message name="IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY" desc="Text body for the Welcome screen in Chrome OS 'Add account' dialog."> + You can manage this and other Google Accounts you've added for <ph name="USER_NAME">$1<ex>John</ex></ph> from one place in <ph name="LINK_BEGIN"><a id="osSettingsLink" href="$2<ex>https://google.com/</ex>"></ph>Settings<ph name="LINK_END"></a></ph>. + Permissions you have granted to websites in the Chromium browser and apps from Google Play may apply to all accounts. + </message> + </if> + <!-- Native notifications for Windows 10 --> <if expr="is_win"> <message name="IDS_WIN_NOTIFICATION_SETTINGS_CONTEXT_MENU_ITEM_NAME" desc="The name of the button in Windows Notification Center which leads to Chrome notification settings.">
diff --git a/chrome/app/chromium_strings_grd/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY.png.sha1 b/chrome/app/chromium_strings_grd/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY.png.sha1 new file mode 100644 index 0000000..1b1a6f71 --- /dev/null +++ b/chrome/app/chromium_strings_grd/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY.png.sha1
@@ -0,0 +1 @@ +57468ecef9c8f19c1554aa0ce7a63f2411de021c \ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index acb86d9..10f678e 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -4927,6 +4927,12 @@ <message name="IDS_UPDATE_PASSWORD_DIFFERENT_DOMAINS_TITLE" desc="The title of the update password bubble when the submitted form origin isn't equal to saved credentials origin."> Update password for <ph name="ORIGIN">$1<ex>example.com</ex></ph>? </message> + <message name="IDS_SAVE_PASSWORD_TO_GOOGLE" desc="The title of the save password bubble when the user syncs passswors to thir Google account."> + Save password to your Google Account? + </message> + <message name="IDS_SAVE_ACCOUNT_TO_GOOGLE" desc="The title of the save password bubble when a federated credential can be saved to the user's Google account."> + Save username to your Google Account? + </message> <message name="IDS_SAVE_PASSWORD_FOOTER" desc="The footer text of the bubble that offers user to save a password to Chrome."> Passwords are saved in your Google Account so you can use them on any device </message>
diff --git a/chrome/app/generated_resources_grd/IDS_SAVE_ACCOUNT_TO_GOOGLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_SAVE_ACCOUNT_TO_GOOGLE.png.sha1 new file mode 100644 index 0000000..69a804d --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_SAVE_ACCOUNT_TO_GOOGLE.png.sha1
@@ -0,0 +1 @@ +d82dbe45f91b7573060266d89e8d5d7a91923458 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_SAVE_PASSWORD_TO_GOOGLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_SAVE_PASSWORD_TO_GOOGLE.png.sha1 new file mode 100644 index 0000000..fe695bb --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_SAVE_PASSWORD_TO_GOOGLE.png.sha1
@@ -0,0 +1 @@ +b53a8f296fc56d2e618e646ced5095d95857fefc \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index dde3d1a..2f8fc8d8 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -1105,6 +1105,14 @@ </message> </if> + <!-- Chrome OS in-session 'Add account' flow --> + <if expr="chromeos"> + <message name="IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY" desc="Text body for the Welcome screen in Chrome OS 'Add account' dialog."> + You can manage this and other Google Accounts you've added for <ph name="USER_NAME">$1<ex>John</ex></ph> from one place in <ph name="LINK_BEGIN"><a id="osSettingsLink" href="$2<ex>https://google.com/</ex>"></ph>Settings<ph name="LINK_END"></a></ph>. + Permissions you have granted to websites in the Chrome browser and apps from Google Play may apply to all accounts. + </message> + </if> + <!-- Native notifications for Windows 10 --> <if expr="is_win"> <message name="IDS_WIN_NOTIFICATION_SETTINGS_CONTEXT_MENU_ITEM_NAME" desc="The name of the button in Windows Notification Center which leads to Chrome notification settings.">
diff --git a/chrome/app/google_chrome_strings_grd/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY.png.sha1 new file mode 100644 index 0000000..91679cc5 --- /dev/null +++ b/chrome/app/google_chrome_strings_grd/IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY.png.sha1
@@ -0,0 +1 @@ +c4dd21a1e21ef55bd5ef3c9d17df911348efa325 \ No newline at end of file
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 50fec4d..d109f38 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -64,7 +64,6 @@ "keyboard_arrow_right.icon", "keyboard_arrow_up.icon", "laptop.icon", - "live_caption.icon", "media_toolbar_button.icon", "media_toolbar_button_touch.icon", "mixed_content.icon",
diff --git a/chrome/app/vector_icons/live_caption.icon b/chrome/app/vector_icons/live_caption.icon deleted file mode 100644 index 5962632..0000000 --- a/chrome/app/vector_icons/live_caption.icon +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -CANVAS_DIMENSIONS, 20, -MOVE_TO, 2, 5.5f, -CUBIC_TO, 2, 4.67f, 2.67f, 4, 3.5f, 4, -H_LINE_TO, 16.5f, -CUBIC_TO, 17.33f, 4, 18, 4.67f, 18, 5.5f, -V_LINE_TO, 14.5f, -CUBIC_TO, 18, 15.33f, 17.33f, 16, 16.5f, 16, -H_LINE_TO, 3.5f, -CUBIC_TO, 2.67f, 16, 2, 15.33f, 2, 14.5f, -V_LINE_TO, 5.5f, -CLOSE, -MOVE_TO, 4, 6, -H_LINE_TO, 16, -V_LINE_TO, 14, -H_LINE_TO, 4, -V_LINE_TO, 6, -CLOSE, -MOVE_TO, 5, 8, -H_LINE_TO, 9, -V_LINE_TO, 10, -H_LINE_TO, 5, -V_LINE_TO, 8, -CLOSE, -MOVE_TO, 5, 11, -H_LINE_TO, 12, -V_LINE_TO, 13, -H_LINE_TO, 5, -V_LINE_TO, 11, -CLOSE, -MOVE_TO, 15, 11, -H_LINE_TO, 13, -V_LINE_TO, 13, -H_LINE_TO, 15, -V_LINE_TO, 11, -CLOSE, -MOVE_TO, 10, 8, -H_LINE_TO, 15, -V_LINE_TO, 10, -H_LINE_TO, 10, -V_LINE_TO, 8, -CLOSE
diff --git a/chrome/browser/OWNERS b/chrome/browser/OWNERS index 010e6b7..d8d7143 100644 --- a/chrome/browser/OWNERS +++ b/chrome/browser/OWNERS
@@ -87,9 +87,8 @@ per-file chrome_back_forward_cache_browsertest.cc=altimin@chromium.org per-file chrome_back_forward_cache_browsertest.cc=file://content/OWNERS -# Cross-Origin-Opener-Policy: -per-file chrome_cross_origin_opener_policy_browsertest.cc=file://content/OWNERS -per-file chrome_cross_origin_opener_policy_browsertest.cc=arthursonzogni@chromium.org +# Web Platform security metrics tests: +per-file chrome_web_platform_security_metrics_browsertest.cc=file://content/OWNERS # COMPONENT: UI>Browser # TEAM: chromium-reviews@chromium.org
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index b2a53ed..ded9b6e 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -461,12 +461,12 @@ #endif // OS_ANDROID #if defined(OS_ANDROID) -const FeatureEntry::FeatureParam kDismissButtonWithNoThanks[] = { - {"dismiss_button", "no_thanks"}}; +const FeatureEntry::FeatureParam kHideDismissButton[] = { + {"dismiss_button", "hide"}}; const FeatureEntry::FeatureVariation kMobileIdentityConsistencyVariations[] = { - {"Dismiss No Thanks", kDismissButtonWithNoThanks, - base::size(kDismissButtonWithNoThanks), nullptr}}; + {"Hide Dismiss Button", kHideDismissButton, base::size(kHideDismissButton), + nullptr}}; #endif // OS_ANDROID #if !defined(OS_CHROMEOS) @@ -2919,7 +2919,7 @@ flag_descriptions::kAcceleratedVideoDecodeName, flag_descriptions::kAcceleratedVideoDecodeDescription, kOsLinux, - SINGLE_VALUE_TYPE(switches::kEnableAcceleratedVideoDecode), + FEATURE_VALUE_TYPE(media::kVaapiVideoDecodeLinux), }, #else {
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc index e9e209d..9d1b0c8 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.cc +++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -61,6 +61,7 @@ using ::base::android::JavaRef; using ::base::android::ScopedJavaGlobalRef; using ::base::android::ScopedJavaLocalRef; +using payments::FullCardRequest; Profile* GetProfile() { return ProfileManager::GetActiveUserProfile()->GetOriginalProfile(); @@ -79,7 +80,7 @@ // Self-deleting requester of full card details, including full PAN and the CVC // number. -class FullCardRequester : public payments::FullCardRequest::ResultDelegate, +class FullCardRequester : public FullCardRequest::ResultDelegate, public base::SupportsWeakPtr<FullCardRequester> { public: FullCardRequester() {} @@ -93,28 +94,28 @@ jdelegate_.Reset(env, jdelegate); if (!card_) { - OnFullCardRequestFailed(); + OnFullCardRequestFailed(FullCardRequest::FailureType::GENERIC_FAILURE); return; } content::WebContents* contents = content::WebContents::FromJavaWebContents(jweb_contents); if (!contents) { - OnFullCardRequestFailed(); + OnFullCardRequestFailed(FullCardRequest::FailureType::GENERIC_FAILURE); return; } ContentAutofillDriverFactory* factory = ContentAutofillDriverFactory::FromWebContents(contents); if (!factory) { - OnFullCardRequestFailed(); + OnFullCardRequestFailed(FullCardRequest::FailureType::GENERIC_FAILURE); return; } ContentAutofillDriver* driver = factory->DriverForFrame(contents->GetMainFrame()); if (!driver) { - OnFullCardRequestFailed(); + OnFullCardRequestFailed(FullCardRequest::FailureType::GENERIC_FAILURE); return; } @@ -140,7 +141,8 @@ } // payments::FullCardRequest::ResultDelegate: - void OnFullCardRequestFailed() override { + void OnFullCardRequestFailed( + FullCardRequest::FailureType failure_type) override { JNIEnv* env = base::android::AttachCurrentThread(); Java_FullCardRequestDelegate_onFullCardError(env, jdelegate_); delete this;
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index f238c3b..9ed123b 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -158,6 +158,7 @@ <if expr="not is_android"> <!-- Page not available for guest. --> <include name="IDR_PAGE_NOT_AVAILABLE_FOR_GUEST_APP_HTML" file="resources\page_not_available_for_guest\app.html" type="BINDATA" /> + <!-- In-session login flow --> <include name="IDR_INLINE_LOGIN_HTML" file="resources\inline_login\inline_login.html" type="BINDATA" /> <include name="IDR_INLINE_LOGIN_APP_JS" file="${root_gen_dir}\chrome\browser\resources\inline_login\inline_login_app.js" use_base_dir="false" type ="BINDATA" preprocess="true" /> <include name="IDR_INLINE_LOGIN_BROWSER_PROXY_JS" file="resources\inline_login\inline_login_browser_proxy.js" type ="BINDATA"/> @@ -165,6 +166,8 @@ <if expr="chromeos"> <include name="IDR_CHROME_URLS_DISABLED_PAGE_HTML" file="resources\chromeos\chrome_urls_disabled_page\app.html" type="BINDATA" /> + <!-- In-session login flow --> + <include name="IDR_INLINE_LOGIN_WELCOME_PAGE_APP_JS" file="${root_gen_dir}\chrome\browser\resources\inline_login\welcome_page_app.js" use_base_dir="false" type ="BINDATA" preprocess="true" /> </if> <include name="IDR_IDENTITY_API_SCOPE_APPROVAL_MANIFEST" file="resources\identity_scope_approval_dialog\manifest.json" type="BINDATA" />
diff --git a/chrome/browser/chrome_cross_origin_opener_policy_browsertest.cc b/chrome/browser/chrome_cross_origin_opener_policy_browsertest.cc deleted file mode 100644 index 8ec9cb5..0000000 --- a/chrome/browser/chrome_cross_origin_opener_policy_browsertest.cc +++ /dev/null
@@ -1,185 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/command_line.h" -#include "base/test/scoped_feature_list.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "components/network_session_configurator/common/network_switches.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/content_browser_test_utils.h" -#include "net/dns/mock_host_resolver.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "services/network/public/cpp/features.h" -#include "services/network/public/mojom/cross_origin_opener_policy.mojom.h" - -#include "content/public/browser/web_contents.h" -// Cross-Origin-Opener-Policy is a web platform feature implemented by content/. -// However, since ContentBrowserClientImpl::LogWebFeatureForCurrentPage() is -// currently left blank in content/, it can't be tested from content/. So it is -// tested from chrome/ instead. -class ChromeCrossOriginOpenerPolicyBrowserTest : public InProcessBrowserTest { - public: - ChromeCrossOriginOpenerPolicyBrowserTest() { - features_.InitWithFeatures( - { - // Enabled: - network::features::kCrossOriginOpenerPolicy, - network::features::kCrossOriginEmbedderPolicy, - network::features::kCrossOriginOpenerPolicyReporting, - }, - {}); - } - - content::WebContents* web_contents() const { - return browser()->tab_strip_model()->GetActiveWebContents(); - } - - private: - void SetUpOnMainThread() final { host_resolver()->AddRule("*", "127.0.0.1"); } - - void SetUpCommandLine(base::CommandLine* command_line) final { - InProcessBrowserTest::SetUpCommandLine(command_line); - command_line->AppendSwitch(switches::kIgnoreCertificateErrors); - } - - base::test::ScopedFeatureList features_; -}; - -// Check the kCrossOriginOpenerPolicyReporting feature usage. -IN_PROC_BROWSER_TEST_F(ChromeCrossOriginOpenerPolicyBrowserTest, - ReportingUsage) { - net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); - net::EmbeddedTestServer http_server(net::EmbeddedTestServer::TYPE_HTTP); - https_server.AddDefaultHandlers(GetChromeTestDataDir()); - http_server.AddDefaultHandlers(GetChromeTestDataDir()); - https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK); - ASSERT_TRUE(https_server.Start()); - ASSERT_TRUE(http_server.Start()); - - int expected_count = 0; - base::HistogramTester histogram; - - auto expect_histogram_increased_by = [&](int count) { - expected_count += count; - histogram.ExpectBucketCount( - "Blink.UseCounter.Features", - blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting, - expected_count); - }; - - // No header => 0 count. - { - GURL url = https_server.GetURL("a.com", "/title1.html"); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - expect_histogram_increased_by(0); - } - - // COOP-Report-Only + HTTP => 0 count. - { - GURL url = http_server.GetURL("a.com", - "/set-header?" - "Cross-Origin-Opener-Policy-Report-Only: " - "same-origin; report-to%3d\"a\""); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - expect_histogram_increased_by(0); - } - - // COOP-Report-Only + HTTPS => 1 count. - { - GURL url = https_server.GetURL("a.com", - "/set-header?" - "Cross-Origin-Opener-Policy-Report-Only: " - "same-origin; report-to%3d\"a\""); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - expect_histogram_increased_by(1); - } - - // COOP + HTPS => 1 count. - { - GURL url = https_server.GetURL("a.com", - "/set-header?" - "Cross-Origin-Opener-Policy: " - "same-origin; report-to%3d\"a\""); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - expect_histogram_increased_by(1); - } - - // COOP + COOP-RO + HTTPS => 1 count. - { - GURL url = https_server.GetURL("a.com", - "/set-header?" - "Cross-Origin-Opener-Policy: " - "same-origin; report-to%3d\"a\"&" - "Cross-Origin-Opener-Policy-Report-Only: " - "same-origin; report-to%3d\"a\""); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - expect_histogram_increased_by(1); - } - // No report endpoints defined => 0 count. - { - GURL url = https_server.GetURL( - "a.com", - "/set-header?" - "Cross-Origin-Opener-Policy: same-origin&" - "Cross-Origin-Opener-Policy-Report-Only: same-origin"); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - expect_histogram_increased_by(0); - } - - // Main frame (COOP-RO), subframe (COOP-RO) => 1 count. - { - GURL url = https_server.GetURL("a.com", - "/set-header?" - "Cross-Origin-Opener-Policy-Report-Only: " - "same-origin; report-to%3d\"a\""); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - EXPECT_TRUE(content::ExecJs(web_contents(), content::JsReplace(R"( - new Promise(resolve => { - let iframe = document.createElement("iframe"); - iframe.src = $1; - iframe.onload = resolve; - document.body.appendChild(iframe); - }); - )", - url))); - expect_histogram_increased_by(1); - } - - // Main frame (no-headers), subframe (COOP-RO) => 0 count. - { - GURL main_document_url = https_server.GetURL("a.com", "/title1.html"); - GURL sub_document_url = - https_server.GetURL("a.com", - "/set-header?" - "Cross-Origin-Opener-Policy-Report-Only: " - "same-origin; report-to%3d\"a\""); - EXPECT_TRUE(content::NavigateToURL(web_contents(), main_document_url)); - EXPECT_TRUE( - content::ExecJs(web_contents(), content::JsReplace(R"( - new Promise(resolve => { - let iframe = document.createElement("iframe"); - iframe.src = $1; - iframe.onload = resolve; - document.body.appendChild(iframe); - }); - )", - sub_document_url))); - expect_histogram_increased_by(0); - } -} - -// TODO(arthursonzogni): Add basic test(s) for the WebFeatures: -// - CrossOriginOpenerPolicySameOrigin -// - CrossOriginOpenerPolicySameOriginAllowPopups -// - CrossOriginEmbedderPolicyRequireCorp -// - CoopAndCoepIsolated -// -// Added by: -// https://chromium-review.googlesource.com/c/chromium/src/+/2122140 -// -// In particular, it would be interesting knowing what happens with iframes? -// Are CoopCoepOriginIsolated nested document counted as CoopAndCoepIsolated? -// Not doing it would underestimate the usage metric.
diff --git a/chrome/browser/chrome_web_platform_security_metrics_browsertest.cc b/chrome/browser/chrome_web_platform_security_metrics_browsertest.cc new file mode 100644 index 0000000..09d05d0 --- /dev/null +++ b/chrome/browser/chrome_web_platform_security_metrics_browsertest.cc
@@ -0,0 +1,294 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/command_line.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/network_session_configurator/common/network_switches.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test_utils.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "services/network/public/cpp/features.h" +#include "services/network/public/mojom/cross_origin_opener_policy.mojom.h" + +// Web platform security features are implemented by content/ and blink/. +// However, since ContentBrowserClientImpl::LogWebFeatureForCurrentPage() is +// currently left blank in content/, metrics logging can't be tested from +// content/. So it is tested from chrome/ instead. +class ChromeWebPlatformSecurityMetricsBrowserTest + : public InProcessBrowserTest { + public: + ChromeWebPlatformSecurityMetricsBrowserTest() + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS), + http_server_(net::EmbeddedTestServer::TYPE_HTTP) { + features_.InitWithFeatures( + { + // Enabled: + network::features::kCrossOriginOpenerPolicy, + network::features::kCrossOriginEmbedderPolicy, + network::features::kCrossOriginOpenerPolicyReporting, + }, + {}); + } + + content::WebContents* web_contents() const { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + void set_monitored_feature(blink::mojom::WebFeature feature) { + monitored_feature_ = feature; + } + + void LoadIFrame(const GURL& url) { + EXPECT_TRUE(content::ExecJs(web_contents(), content::JsReplace(R"( + new Promise(resolve => { + let iframe = document.createElement("iframe"); + iframe.src = $1; + iframe.onload = resolve; + document.body.appendChild(iframe); + }); + )", + url))); + } + + void ExpectHistogramIncreasedBy(int count) { + expected_count_ += count; + EXPECT_TRUE(content::NavigateToURL(web_contents(), GURL("about:blank"))); + histogram_.ExpectBucketCount("Blink.UseCounter.Features", + monitored_feature_, expected_count_); + } + + net::EmbeddedTestServer& https_server() { return https_server_; } + net::EmbeddedTestServer& http_server() { return http_server_; } + + private: + void SetUpOnMainThread() final { + host_resolver()->AddRule("*", "127.0.0.1"); + https_server_.AddDefaultHandlers(GetChromeTestDataDir()); + http_server_.AddDefaultHandlers(GetChromeTestDataDir()); + https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK); + ASSERT_TRUE(https_server_.Start()); + ASSERT_TRUE(http_server_.Start()); + EXPECT_TRUE(content::NavigateToURL(web_contents(), GURL("about:blank"))); + } + + void SetUpCommandLine(base::CommandLine* command_line) final { + InProcessBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); + } + + net::EmbeddedTestServer https_server_; + net::EmbeddedTestServer http_server_; + int expected_count_ = 0; + base::HistogramTester histogram_; + blink::mojom::WebFeature monitored_feature_; + base::test::ScopedFeatureList features_; +}; + +// Check the kCrossOriginOpenerPolicyReporting feature usage. No header => 0 +// count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginOpenerPolicyReportingNoHeader) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting); + GURL url = https_server().GetURL("a.com", "/title1.html"); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + ExpectHistogramIncreasedBy(0); +} + +// Check the kCrossOriginOpenerPolicyReporting feature usage. COOP-Report-Only + +// HTTP => 0 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginOpenerPolicyReportingReportOnlyHTTP) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting); + GURL url = http_server().GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + ExpectHistogramIncreasedBy(0); +} + +// Check the kCrossOriginOpenerPolicyReporting feature usage. COOP-Report-Only + +// HTTPS => 1 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginOpenerPolicyReportingReportOnlyHTTPS) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting); + GURL url = https_server().GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + ExpectHistogramIncreasedBy(1); +} + +// Check the kCrossOriginOpenerPolicyReporting feature usage. COOP + HTPS => 1 +// count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginOpenerPolicyReportingCOOPHTTPS) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting); + GURL url = https_server().GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + ExpectHistogramIncreasedBy(1); +} + +// Check the kCrossOriginOpenerPolicyReporting feature usage. COOP + COOP-RO + +// HTTPS => 1 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginOpenerPolicyReportingCOOPAndReportOnly) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting); + GURL url = https_server().GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy: " + "same-origin; report-to%3d\"a\"&" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + ExpectHistogramIncreasedBy(1); +} + +// Check the kCrossOriginOpenerPolicyReporting feature usage. No report +// endpoints defined => 0 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginOpenerPolicyReportingNoEndpoint) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting); + GURL url = https_server().GetURL( + "a.com", + "/set-header?" + "Cross-Origin-Opener-Policy: same-origin&" + "Cross-Origin-Opener-Policy-Report-Only: same-origin"); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + ExpectHistogramIncreasedBy(0); +} + +// Check the kCrossOriginOpenerPolicyReporting feature usage. Main frame +// (COOP-RO), subframe (COOP-RO) => 1 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginOpenerPolicyReportingMainFrameAndSubframe) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting); + GURL url = https_server().GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + LoadIFrame(url); + ExpectHistogramIncreasedBy(1); +} + +// Check the kCrossOriginOpenerPolicyReporting feature usage. Main frame +// (no-headers), subframe (COOP-RO) => 0 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginOpenerPolicyReportingUsageSubframeOnly) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting); + GURL main_document_url = https_server().GetURL("a.com", "/title1.html"); + GURL sub_document_url = + https_server().GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), main_document_url)); + LoadIFrame(sub_document_url); + ExpectHistogramIncreasedBy(0); +} + +// Check kCrossOriginSubframeWithoutEmbeddingControl reporting. Same-origin +// iframe (no headers) => 0 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginSubframeWithoutEmbeddingControlSameOrigin) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginSubframeWithoutEmbeddingControl); + GURL url = https_server().GetURL("a.com", "/title1.html"); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + LoadIFrame(url); + ExpectHistogramIncreasedBy(0); +} + +// Check kCrossOriginSubframeWithoutEmbeddingControl reporting. Cross-origin +// iframe (no headers) => 0 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginSubframeWithoutEmbeddingControlNoHeaders) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginSubframeWithoutEmbeddingControl); + GURL main_document_url = https_server().GetURL("a.com", "/title1.html"); + GURL sub_document_url = https_server().GetURL("b.com", "/title1.html"); + EXPECT_TRUE(content::NavigateToURL(web_contents(), main_document_url)); + LoadIFrame(sub_document_url); + ExpectHistogramIncreasedBy(1); +} + +// Check kCrossOriginSubframeWithoutEmbeddingControl reporting. Cross-origin +// iframe (CSP frame-ancestors) => 0 count. +IN_PROC_BROWSER_TEST_F( + ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginSubframeWithoutEmbeddingControlFrameAncestors) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginSubframeWithoutEmbeddingControl); + GURL main_document_url = https_server().GetURL("a.com", "/title1.html"); + url::Origin main_document_origin = url::Origin::Create(main_document_url); + std::string csp_header = "Content-Security-Policy: frame-ancestors 'self' *;"; + GURL sub_document_url = + https_server().GetURL("b.com", "/set-header?" + csp_header); + EXPECT_TRUE(content::NavigateToURL(web_contents(), main_document_url)); + LoadIFrame(sub_document_url); + ExpectHistogramIncreasedBy(0); +} + +// Check kCrossOriginSubframeWithoutEmbeddingControl reporting. Cross-origin +// iframe (blocked by CSP header) => 0 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginSubframeWithoutEmbeddingControlNoEmbedding) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginSubframeWithoutEmbeddingControl); + GURL main_document_url = https_server().GetURL("a.com", "/title1.html"); + GURL sub_document_url = + https_server().GetURL("b.com", + "/set-header?" + "Content-Security-Policy: frame-ancestors 'self';"); + EXPECT_TRUE(content::NavigateToURL(web_contents(), main_document_url)); + LoadIFrame(sub_document_url); + ExpectHistogramIncreasedBy(0); +} + +// Check kCrossOriginSubframeWithoutEmbeddingControl reporting. Cross-origin +// iframe (other CSP header) => 1 count. +IN_PROC_BROWSER_TEST_F(ChromeWebPlatformSecurityMetricsBrowserTest, + CrossOriginSubframeWithoutEmbeddingControlOtherCSP) { + set_monitored_feature( + blink::mojom::WebFeature::kCrossOriginSubframeWithoutEmbeddingControl); + GURL main_document_url = https_server().GetURL("a.com", "/title1.html"); + GURL sub_document_url = + https_server().GetURL("b.com", + "/set-header?" + "Content-Security-Policy: script-src 'self';"); + EXPECT_TRUE(content::NavigateToURL(web_contents(), main_document_url)); + LoadIFrame(sub_document_url); + ExpectHistogramIncreasedBy(1); +} + +// TODO(arthursonzogni): Add basic test(s) for the WebFeatures: +// - CrossOriginOpenerPolicySameOrigin +// - CrossOriginOpenerPolicySameOriginAllowPopups +// - CrossOriginEmbedderPolicyRequireCorp +// - CoopAndCoepIsolated +// +// Added by: +// https://chromium-review.googlesource.com/c/chromium/src/+/2122140 +// +// In particular, it would be interesting knowing what happens with iframes? +// Are CoopCoepOriginIsolated nested document counted as CoopAndCoepIsolated? +// Not doing it would underestimate the usage metric.
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.cc b/chrome/browser/chromeos/arc/arc_optin_uma.cc index 68d75f0..0f82375 100644 --- a/chrome/browser/chromeos/arc/arc_optin_uma.cc +++ b/chrome/browser/chromeos/arc/arc_optin_uma.cc
@@ -75,11 +75,11 @@ base::UmaHistogramEnumeration("Arc.OptInResult", result); } -void UpdateProvisioningResultUMA(ProvisioningResultUMA result, +void UpdateProvisioningStatusUMA(ProvisioningStatus status, const Profile* profile) { - DCHECK_NE(result, ProvisioningResultUMA::CHROME_SERVER_COMMUNICATION_ERROR); + DCHECK_NE(status, ProvisioningStatus::CHROME_SERVER_COMMUNICATION_ERROR); base::UmaHistogramEnumeration( - GetHistogramNameByUserType("Arc.Provisioning.Result", profile), result); + GetHistogramNameByUserType("Arc.Provisioning.Status", profile), status); } void UpdateCloudProvisionFlowErrorUMA(mojom::CloudProvisionFlowError error, @@ -89,8 +89,22 @@ error); } -void UpdateSecondarySigninResultUMA(ProvisioningResultUMA result) { - base::UmaHistogramEnumeration("Arc.Secondary.Signin.Result", result); +void UpdateGMSSignInErrorUMA(mojom::GMSSignInError error, + const Profile* profile) { + base::UmaHistogramEnumeration( + GetHistogramNameByUserType("Arc.Provisioning.SignInError", profile), + error); +} + +void UpdateGMSCheckInErrorUMA(mojom::GMSCheckInError error, + const Profile* profile) { + base::UmaHistogramEnumeration( + GetHistogramNameByUserType("Arc.Provisioning.CheckInError", profile), + error); +} + +void UpdateSecondarySigninResultUMA(ProvisioningStatus status) { + base::UmaHistogramEnumeration("Arc.Secondary.Signin.Result", status); } void UpdateProvisioningTiming(const base::TimeDelta& elapsed_time, @@ -106,11 +120,11 @@ base::TimeDelta::FromSeconds(1), base::TimeDelta::FromMinutes(6), 50); } -void UpdateReauthorizationResultUMA(ProvisioningResultUMA result, +void UpdateReauthorizationResultUMA(ProvisioningStatus status, const Profile* profile) { base::UmaHistogramEnumeration( GetHistogramNameByUserType("Arc.Reauthorization.Result", profile), - result); + status); } void UpdatePlayAutoInstallRequestState(mojom::PaiFlowState state, @@ -206,29 +220,31 @@ static_cast<int>(state)); } -ProvisioningResultUMA GetProvisioningResultUMA( +ProvisioningStatus GetProvisioningStatus( const ArcProvisioningResult& provisioning_result) { if (provisioning_result.is_stopped()) - return ProvisioningResultUMA::ARC_STOPPED; + return ProvisioningStatus::ARC_STOPPED; if (provisioning_result.is_timedout()) - return ProvisioningResultUMA::OVERALL_SIGN_IN_TIMEOUT; + return ProvisioningStatus::CHROME_PROVISIONING_TIMEOUT; const mojom::ArcSignInResult* result = provisioning_result.sign_in_result(); - if (result->is_success()) { - if (result->get_success() == mojom::ArcSignInSuccess::SUCCESS) - return ProvisioningResultUMA::SUCCESS; - else - return ProvisioningResultUMA::SUCCESS_ALREADY_PROVISIONED; - } + if (result->is_success()) + return ProvisioningStatus::SUCCESS; if (result->get_error()->is_cloud_provision_flow_error()) - return ProvisioningResultUMA::CLOUD_PROVISION_FLOW_ERROR; + return ProvisioningStatus::CLOUD_PROVISION_FLOW_ERROR; + + if (result->get_error()->is_check_in_error()) + return ProvisioningStatus::GMS_CHECK_IN_ERROR; + + if (result->get_error()->is_sign_in_error()) + return ProvisioningStatus::GMS_SIGN_IN_ERROR; if (result->get_error()->is_general_error()) { #define MAP_GENERAL_ERROR(name) \ case mojom::GeneralSignInError::name: \ - return ProvisioningResultUMA::name + return ProvisioningStatus::name switch (result->get_error()->get_general_error()) { MAP_GENERAL_ERROR(UNKNOWN_ERROR); @@ -243,75 +259,37 @@ #undef MAP_GENERAL_ERROR } - if (result->get_error()->is_check_in_error()) { -#define MAP_CHECKIN_ERROR(name) \ - case mojom::GMSCheckInError::name: \ - return ProvisioningResultUMA::name - - switch (result->get_error()->get_check_in_error()) { - MAP_CHECKIN_ERROR(GMS_CHECK_IN_FAILED); - MAP_CHECKIN_ERROR(GMS_CHECK_IN_TIMEOUT); - MAP_CHECKIN_ERROR(GMS_CHECK_IN_INTERNAL_ERROR); - } -#undef MAP_CHECKIN_ERROR - } - - if (result->get_error()->is_sign_in_error()) { -#define MAP_GMS_ERROR(name) \ - case mojom::GMSSignInError::name: \ - return ProvisioningResultUMA::name - - switch (result->get_error()->get_sign_in_error()) { - MAP_GMS_ERROR(GMS_SIGN_IN_NETWORK_ERROR); - MAP_GMS_ERROR(GMS_SIGN_IN_SERVICE_UNAVAILABLE); - MAP_GMS_ERROR(GMS_SIGN_IN_BAD_AUTHENTICATION); - MAP_GMS_ERROR(GMS_SIGN_IN_FAILED); - MAP_GMS_ERROR(GMS_SIGN_IN_TIMEOUT); - MAP_GMS_ERROR(GMS_SIGN_IN_INTERNAL_ERROR); - } -#undef MAP_GMS_ERROR - } - - NOTREACHED() << "unknown sign result"; - return ProvisioningResultUMA::UNKNOWN_ERROR; + NOTREACHED() << "unexpected provisioning result"; + return ProvisioningStatus::UNKNOWN_ERROR; } -std::ostream& operator<<(std::ostream& os, - const ProvisioningResultUMA& result) { +std::ostream& operator<<(std::ostream& os, const ProvisioningStatus& status) { #define MAP_PROVISIONING_RESULT(name) \ - case ProvisioningResultUMA::name: \ + case ProvisioningStatus::name: \ return os << #name - switch (result) { + switch (status) { MAP_PROVISIONING_RESULT(SUCCESS); MAP_PROVISIONING_RESULT(UNKNOWN_ERROR); - MAP_PROVISIONING_RESULT(GMS_SIGN_IN_NETWORK_ERROR); - MAP_PROVISIONING_RESULT(GMS_SIGN_IN_SERVICE_UNAVAILABLE); - MAP_PROVISIONING_RESULT(GMS_SIGN_IN_BAD_AUTHENTICATION); - MAP_PROVISIONING_RESULT(GMS_CHECK_IN_FAILED); + MAP_PROVISIONING_RESULT(GMS_SIGN_IN_ERROR); + MAP_PROVISIONING_RESULT(GMS_CHECK_IN_ERROR); + MAP_PROVISIONING_RESULT(CLOUD_PROVISION_FLOW_ERROR); MAP_PROVISIONING_RESULT(MOJO_VERSION_MISMATCH); MAP_PROVISIONING_RESULT(GENERIC_PROVISIONING_TIMEOUT); - MAP_PROVISIONING_RESULT(GMS_CHECK_IN_TIMEOUT); - MAP_PROVISIONING_RESULT(GMS_CHECK_IN_INTERNAL_ERROR); - MAP_PROVISIONING_RESULT(GMS_SIGN_IN_FAILED); - MAP_PROVISIONING_RESULT(GMS_SIGN_IN_TIMEOUT); - MAP_PROVISIONING_RESULT(GMS_SIGN_IN_INTERNAL_ERROR); + MAP_PROVISIONING_RESULT(CHROME_PROVISIONING_TIMEOUT); MAP_PROVISIONING_RESULT(ARC_STOPPED); - MAP_PROVISIONING_RESULT(OVERALL_SIGN_IN_TIMEOUT); + MAP_PROVISIONING_RESULT(ARC_DISABLED); MAP_PROVISIONING_RESULT(CHROME_SERVER_COMMUNICATION_ERROR); MAP_PROVISIONING_RESULT(NO_NETWORK_CONNECTION); - MAP_PROVISIONING_RESULT(ARC_DISABLED); - MAP_PROVISIONING_RESULT(SUCCESS_ALREADY_PROVISIONED); MAP_PROVISIONING_RESULT(UNSUPPORTED_ACCOUNT_TYPE); MAP_PROVISIONING_RESULT(CHROME_ACCOUNT_NOT_FOUND); - MAP_PROVISIONING_RESULT(CLOUD_PROVISION_FLOW_ERROR); } #undef MAP_PROVISIONING_RESULT // Some compilers report an error even if all values of an enum-class are // covered exhaustively in a switch statement. - NOTREACHED() << "Invalid value " << static_cast<int>(result); + NOTREACHED() << "Invalid value " << static_cast<int>(status); return os; }
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.h b/chrome/browser/chromeos/arc/arc_optin_uma.h index 17aa45e..724a5f0 100644 --- a/chrome/browser/chromeos/arc/arc_optin_uma.h +++ b/chrome/browser/chromeos/arc/arc_optin_uma.h
@@ -103,70 +103,54 @@ }; // The values should be listed in ascending order. They are also persisted to -// logs, and their values should therefore never be renumbered nor reused. For -// detailed meaning, please consult auth.mojom. -enum class ProvisioningResultUMA : int { - // Provisioning was successful. Note, SUCCESS_ALREADY_PROVISIONED is also - // successful state. +// logs, and their values should therefore never be renumbered nor reused. +enum class ProvisioningStatus { + // Provisioning was successful. SUCCESS = 0, // Unclassified failure. UNKNOWN_ERROR = 1, - // GMS errors. More errors defined below. - GMS_SIGN_IN_NETWORK_ERROR = 2, - GMS_SIGN_IN_SERVICE_UNAVAILABLE = 3, - GMS_SIGN_IN_BAD_AUTHENTICATION = 4, - - // Check in error. More errors defined below. - GMS_CHECK_IN_FAILED = 5, - - // Mojo errors. - MOJO_VERSION_MISMATCH = 7, - - // ARC did not finish provisioning within a reasonable amount of time. - GENERIC_PROVISIONING_TIMEOUT = 8, + // Unmanaged sign-in error. + GMS_SIGN_IN_ERROR = 2, // Check in error. - GMS_CHECK_IN_TIMEOUT = 9, - GMS_CHECK_IN_INTERNAL_ERROR = 10, + GMS_CHECK_IN_ERROR = 3, - // GMS errors: - GMS_SIGN_IN_FAILED = 11, - GMS_SIGN_IN_TIMEOUT = 12, - GMS_SIGN_IN_INTERNAL_ERROR = 13, + // Managed sign-in error. + CLOUD_PROVISION_FLOW_ERROR = 4, + + // Mojo errors. + MOJO_VERSION_MISMATCH = 5, + + // ARC did not finish provisioning within a reasonable amount of time. + GENERIC_PROVISIONING_TIMEOUT = 6, + + // ARC instance did not report provisioning status within a reasonable amount + // of time. + CHROME_PROVISIONING_TIMEOUT = 7, // ARC instance is stopped during the sign in procedure. - ARC_STOPPED = 16, + ARC_STOPPED = 8, - // ARC instance did not report sign in status within a reasonable amount of - // time. - OVERALL_SIGN_IN_TIMEOUT = 17, + // ARC is not enabled. + ARC_DISABLED = 9, // In Chrome, server communication error occurs. // For backward compatibility, the UMA is handled differently. Please see // ArcSessionManager::OnProvisioningFinished for details. - CHROME_SERVER_COMMUNICATION_ERROR = 18, + CHROME_SERVER_COMMUNICATION_ERROR = 10, // Network connection is unavailable in ARC. - NO_NETWORK_CONNECTION = 19, - - // ARC is not enabled. - ARC_DISABLED = 20, - - // Device was already provisioned. - SUCCESS_ALREADY_PROVISIONED = 21, + NO_NETWORK_CONNECTION = 11, // Account type is not supported for authorization. - UNSUPPORTED_ACCOUNT_TYPE = 22, + UNSUPPORTED_ACCOUNT_TYPE = 12, // Account is not present in Chrome OS Account Manager. - CHROME_ACCOUNT_NOT_FOUND = 23, + CHROME_ACCOUNT_NOT_FOUND = 13, - // Top level error for cloud DPC failure. - CLOUD_PROVISION_FLOW_ERROR = 24, - - kMaxValue = CLOUD_PROVISION_FLOW_ERROR, + kMaxValue = CHROME_ACCOUNT_NOT_FOUND, }; enum class OptInFlowResult : int { @@ -226,15 +210,19 @@ void UpdateOptInActionUMA(OptInActionType type); void UpdateOptInCancelUMA(OptInCancelReason reason); void UpdateOptInFlowResultUMA(OptInFlowResult result); -void UpdateProvisioningResultUMA(ProvisioningResultUMA result, +void UpdateProvisioningStatusUMA(ProvisioningStatus status, const Profile* profile); void UpdateCloudProvisionFlowErrorUMA(mojom::CloudProvisionFlowError error, const Profile* profile); -void UpdateSecondarySigninResultUMA(ProvisioningResultUMA result); +void UpdateGMSSignInErrorUMA(mojom::GMSSignInError error, + const Profile* profile); +void UpdateGMSCheckInErrorUMA(mojom::GMSCheckInError error, + const Profile* profile); +void UpdateSecondarySigninResultUMA(ProvisioningStatus status); void UpdateProvisioningTiming(const base::TimeDelta& elapsed_time, bool success, const Profile* profile); -void UpdateReauthorizationResultUMA(ProvisioningResultUMA result, +void UpdateReauthorizationResultUMA(ProvisioningStatus status, const Profile* profile); void UpdatePlayAutoInstallRequestState(mojom::PaiFlowState state, const Profile* profile); @@ -266,11 +254,11 @@ // Returns the enum for use in UMA stat and displaying error code on the UI. // This enum should not be used anywhere else. Please work with the object // instead. -ProvisioningResultUMA GetProvisioningResultUMA( +ProvisioningStatus GetProvisioningStatus( const ArcProvisioningResult& provisioning_result); // Outputs the stringified |result| to |os|. This is only for logging purposes. -std::ostream& operator<<(std::ostream& os, const ProvisioningResultUMA& result); +std::ostream& operator<<(std::ostream& os, const ProvisioningStatus& status); } // namespace arc
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc index b2e693c..c3999d98 100644 --- a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc +++ b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
@@ -326,8 +326,7 @@ return; } - ProvisioningResultUMA provisioning_result_enum = - GetProvisioningResultUMA(provisioning_result); + const ProvisioningStatus status = GetProvisioningStatus(provisioning_result); if (!account->is_account_name() || !account->get_account_name() || account->get_account_name().value().empty() || @@ -337,11 +336,9 @@ // The check for |!account_name.has_value()| is for backwards compatibility // with older ARC versions, for which Mojo will set |account_name| to // empty/null. - DCHECK_NE(ProvisioningResultUMA::SUCCESS_ALREADY_PROVISIONED, - provisioning_result_enum); - UpdateReauthorizationResultUMA(provisioning_result_enum, profile_); + UpdateReauthorizationResultUMA(status, profile_); } else { - UpdateSecondarySigninResultUMA(provisioning_result_enum); + UpdateSecondarySigninResultUMA(status); } }
diff --git a/chrome/browser/chromeos/arc/session/arc_provisioning_result.cc b/chrome/browser/chromeos/arc/session/arc_provisioning_result.cc index 309120e..74e21c9 100644 --- a/chrome/browser/chromeos/arc/session/arc_provisioning_result.cc +++ b/chrome/browser/chromeos/arc/session/arc_provisioning_result.cc
@@ -62,7 +62,7 @@ std::ostream& operator<<(std::ostream& os, const ArcProvisioningResult& result) { - return os << GetProvisioningResultUMA(result); + return os << GetProvisioningStatus(result); } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/session/arc_provisioning_result.h b/chrome/browser/chromeos/arc/session/arc_provisioning_result.h index 3fc6931..2a1d02a4 100644 --- a/chrome/browser/chromeos/arc/session/arc_provisioning_result.h +++ b/chrome/browser/chromeos/arc/session/arc_provisioning_result.h
@@ -11,7 +11,7 @@ #include "components/arc/session/arc_stop_reason.h" #include "third_party/abseil-cpp/absl/types/variant.h" -enum class ProvisioningResultUMA : int; +enum class ProvisioningStatus; namespace arc {
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.cc b/chrome/browser/chromeos/arc/session/arc_session_manager.cc index b61980e..14d013e 100644 --- a/chrome/browser/chromeos/arc/session/arc_session_manager.cc +++ b/chrome/browser/chromeos/arc/session/arc_session_manager.cc
@@ -624,10 +624,17 @@ UpdateProvisioningTiming(base::TimeTicks::Now() - sign_in_start_time_, provisioning_successful, profile_); - UpdateProvisioningResultUMA(GetProvisioningResultUMA(result), profile_); - if (sign_in_error && sign_in_error->is_cloud_provision_flow_error()) { - UpdateCloudProvisionFlowErrorUMA( - sign_in_error->get_cloud_provision_flow_error(), profile_); + UpdateProvisioningStatusUMA(GetProvisioningStatus(result), profile_); + + if (sign_in_error) { + if (sign_in_error->is_cloud_provision_flow_error()) { + UpdateCloudProvisionFlowErrorUMA( + sign_in_error->get_cloud_provision_flow_error(), profile_); + } else if (sign_in_error->is_sign_in_error()) { + UpdateGMSSignInErrorUMA(sign_in_error->get_sign_in_error(), profile_); + } else if (sign_in_error->is_check_in_error()) { + UpdateGMSCheckInErrorUMA(sign_in_error->get_check_in_error(), profile_); + } } if (!provisioning_successful) @@ -727,8 +734,8 @@ base::Optional<int> error_code; if (support_error == ArcSupportHost::Error::SIGN_IN_UNKNOWN_ERROR) { - error_code = static_cast<std::underlying_type_t<ProvisioningResultUMA>>( - GetProvisioningResultUMA(result)); + error_code = static_cast<std::underlying_type_t<ProvisioningStatus>>( + GetProvisioningStatus(result)); } else if (sign_in_error) { error_code = GetSignInErrorCode(sign_in_error); } @@ -1250,8 +1257,8 @@ // State::STOPPED appears here in following scenario. // Initial provisioning finished with state - // ProvisioningResultUMA::ArcStop or - // ProvisioningResultUMA::CHROME_SERVER_COMMUNICATION_ERROR. + // ProvisioningStatus::ArcStop or + // ProvisioningStatus::CHROME_SERVER_COMMUNICATION_ERROR. // At this moment |prefs::kArcTermsAccepted| is set to true, once user // confirmed ToS prior to provisioning flow. Once user presses "Try Again" // button, OnRetryClicked calls this immediately. @@ -1536,8 +1543,8 @@ } else { // Otherwise, we start ARC once it is stopped now. Usually ARC container is // left active after provisioning failure but in case - // ProvisioningResultUMA::ARC_STOPPED and - // ProvisioningResultUMA::CHROME_SERVER_COMMUNICATION_ERROR failures + // ProvisioningStatus::ARC_STOPPED and + // ProvisioningStatus::CHROME_SERVER_COMMUNICATION_ERROR failures // container is stopped. At this point ToS is already accepted and // IsArcTermsOfServiceNegotiationNeeded returns true or ToS needs not to be // shown at all. However there is an exception when this does not happen in
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.h b/chrome/browser/chromeos/arc/session/arc_session_manager.h index 78eeb26..5a64db6 100644 --- a/chrome/browser/chromeos/arc/session/arc_session_manager.h +++ b/chrome/browser/chromeos/arc/session/arc_session_manager.h
@@ -45,7 +45,7 @@ class ArcTermsOfServiceNegotiator; class ArcUiAvailabilityReporter; -enum class ProvisioningResultUMA : int; +enum class ProvisioningStatus; enum class ArcStopReason; // This class is responsible for handing stages of ARC life-cycle.
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc index c476016..88cb811 100644 --- a/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc +++ b/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc
@@ -1155,12 +1155,12 @@ constexpr ProvisioningErrorDisplayTestParam kProvisioningErrorDisplayTestCases[] = { {ArcStopReason::GENERIC_BOOT_FAILURE, - ArcSupportHost::Error::SIGN_IN_UNKNOWN_ERROR, 16 /*ARC_STOPPED*/}, + ArcSupportHost::Error::SIGN_IN_UNKNOWN_ERROR, 8 /*ARC_STOPPED*/}, {ArcStopReason::LOW_DISK_SPACE, ArcSupportHost::Error::LOW_DISK_SPACE_ERROR, {}}, {ArcStopReason::CRASH, ArcSupportHost::Error::SIGN_IN_UNKNOWN_ERROR, - 16 /*ARC_STOPPED*/}}; + 8 /*ARC_STOPPED*/}}; class ProvisioningErrorDisplayTest : public ArcSessionManagerTest,
diff --git a/chrome/browser/chromeos/file_manager/file_manager_string_util.cc b/chrome/browser/chromeos/file_manager/file_manager_string_util.cc index dc959d1..f8787b3 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_string_util.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_string_util.cc
@@ -831,6 +831,12 @@ IDS_FILE_BROWSER_REPARTITION_DIALOG_MESSAGE); SET_STRING("RESTORE_FROM_TRASH_BUTTON_LABEL", IDS_FILE_BROWSER_RESTORE_FROM_TRASH_BUTTON_LABEL); + SET_STRING("RESTORE_FROM_TRASH_ERROR", + IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ERROR); + SET_STRING("RESTORE_FROM_TRASH_FILE_NAME", + IDS_FILE_BROWSER_RESTORE_FROM_TRASH_FILE_NAME); + SET_STRING("RESTORE_FROM_TRASH_ITEMS_REMAINING", + IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ITEMS_REMAINING); SET_STRING("UNPIN_FOLDER_BUTTON_LABEL", IDS_FILE_BROWSER_UNPIN_FOLDER_BUTTON_LABEL); SET_STRING("RENAME_BUTTON_LABEL", IDS_FILE_BROWSER_RENAME_BUTTON_LABEL);
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc index 6130bdad..e2536bc 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
@@ -152,7 +152,8 @@ "fr", "se", "jp", - "hu"}; + "hu", + "de"}; auto mock_delegate = std::make_unique<MockComponentExtensionIMEManagerDelegate>(); @@ -306,6 +307,13 @@ ext_xkb_engine_hu.layouts.emplace_back("hu"); ext_xkb.engines.push_back(ext_xkb_engine_hu); + ComponentExtensionEngine ext_xkb_engine_de; + ext_xkb_engine_de.engine_id = "xkb:de::ger"; + ext_xkb_engine_de.display_name = "xkb:de::ger"; + ext_xkb_engine_de.language_codes.emplace_back("de"); + ext_xkb_engine_de.layouts.emplace_back("de"); + ext_xkb.engines.push_back(ext_xkb_engine_de); + ime_list.push_back(ext_xkb); ComponentExtensionIME ext1;
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc index 90f90cf..6508733 100644 --- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc +++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc
@@ -255,6 +255,8 @@ VLOG(1) << "AutoEnrollmentCheckScreen::SignalCompletion()"; network_portal_detector::GetInstance()->RemoveObserver(this); + error_screen_->SetHideCallback(base::OnceClosure()); + error_screen_->SetParentScreen(OobeScreen::SCREEN_UNKNOWN); auto_enrollment_progress_subscription_ = {}; connect_request_subscription_ = {};
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc index 181523ef..f323486 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/chromeos/login/test/js_checker.h" #include "chrome/browser/chromeos/login/test/kiosk_test_helpers.h" #include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" +#include "chrome/browser/chromeos/login/test/network_portal_detector_mixin.h" #include "chrome/browser/chromeos/login/test/oobe_base_test.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" #include "chrome/browser/chromeos/login/test/oobe_screens_utils.h" @@ -196,6 +197,9 @@ ->GetStateKeysBroker(); } + protected: + NetworkPortalDetectorMixin network_portal_detector_{&mixin_host_}; + private: DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentLocalPolicyServer); }; @@ -618,6 +622,18 @@ EXPECT_TRUE(InstallAttributes::Get()->IsCloudManaged()); } +// Verify able to advance to login screen when error screen is shown. +IN_PROC_BROWSER_TEST_F(AutoEnrollmentLocalPolicyServer, TestCaptivePortal) { + network_portal_detector_.SimulateDefaultNetworkState( + NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL); + host()->StartWizard(AutoEnrollmentCheckScreenView::kScreenId); + OobeScreenWaiter(ErrorScreenView::kScreenId).Wait(); + + network_portal_detector_.SimulateDefaultNetworkState( + NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE); + OobeScreenWaiter(GetFirstSigninScreen()).Wait(); +} + // FRE explicitly required in VPD, but the state keys are missing. IN_PROC_BROWSER_TEST_F(AutoEnrollmentNoStateKeys, FREExplicitlyRequired) { SetFRERequiredKey("1");
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc index 032450f..9419e00 100644 --- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc +++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
@@ -7,6 +7,9 @@ #include "base/json/json_writer.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/chromeos/crostini/crostini_manager.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" +#include "chrome/browser/chromeos/crostini/fake_crostini_features.h" #include "chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h" @@ -44,6 +47,23 @@ policy, /*recommended=*/base::DictionaryValue(), ProfileManager::GetActiveUserProfile()); } + + void SetupCrostini() { + crostini::FakeCrostiniFeatures crostini_features; + crostini_features.set_is_allowed_now(true); + crostini_features.set_enabled(true); + + // Setup CrostiniManager for testing. + crostini::CrostiniManager* crostini_manager = + crostini::CrostiniManager::GetForProfile(GetProfileForActiveUser()); + crostini_manager->set_skip_restart_for_testing(); + crostini_manager->AddRunningVmForTesting(crostini::kCrostiniDefaultVmName); + crostini_manager->AddRunningContainerForTesting( + crostini::kCrostiniDefaultVmName, + crostini::ContainerInfo(crostini::kCrostiniDefaultContainerName, + "testuser", "/home/testuser", + "PLACEHOLDER_IP")); + } }; IN_PROC_BROWSER_TEST_F(DataTransferDlpBrowserTest, EmptyPolicy) { @@ -140,6 +160,8 @@ SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, kEmptyServices); + SetupCrostini(); + const std::string kUrl1 = "https://mail.google.com"; base::Value rules(base::Value::Type::LIST); @@ -171,19 +193,13 @@ ui::ClipboardBuffer::kCopyPaste, &data_dst1, &result1); EXPECT_EQ(base::UTF8ToUTF16(kClipboardText), result1); - // `notify_if_restricted` should be set false, otherwise the test would fail, - // because no guest os is actually running. - ui::DataTransferEndpoint data_dst2(ui::EndpointType::kArc, - /*notify_if_restricted=*/false); + ui::DataTransferEndpoint data_dst2(ui::EndpointType::kArc); base::string16 result2; ui::Clipboard::GetForCurrentThread()->ReadText( ui::ClipboardBuffer::kCopyPaste, &data_dst2, &result2); EXPECT_EQ(base::string16(), result2); - // `notify_if_restricted` should be set false, otherwise the test would fail, - // because no guest os is actually running. - ui::DataTransferEndpoint data_dst3(ui::EndpointType::kGuestOs, - /*notify_if_restricted=*/false); + ui::DataTransferEndpoint data_dst3(ui::EndpointType::kGuestOs); base::string16 result3; ui::Clipboard::GetForCurrentThread()->ReadText( ui::ClipboardBuffer::kCopyPaste, &data_dst3, &result3);
diff --git a/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc b/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc index 7b6e398..1c137442 100644 --- a/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc +++ b/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc
@@ -473,12 +473,10 @@ void AddErrorCodesToFailureEvent( const extensions::InstallStageTracker::InstallationData& data, em::ExtensionInstallReportLogEvent* event) { - if (data.response_code) { + if (data.response_code) event->set_fetch_error_code(data.response_code.value()); - } else { - DCHECK(data.network_error_code); + else if (data.network_error_code) event->set_fetch_error_code(data.network_error_code.value()); - } DCHECK(data.fetch_tries); event->set_fetch_tries(data.fetch_tries.value_or(0));
diff --git a/chrome/browser/chromeos/usb/cros_usb_detector.cc b/chrome/browser/chromeos/usb/cros_usb_detector.cc index 5493ef0..d4ff953 100644 --- a/chrome/browser/chromeos/usb/cros_usb_detector.cc +++ b/chrome/browser/chromeos/usb/cros_usb_detector.cc
@@ -293,7 +293,7 @@ class FilesystemUnmounter : public base::RefCounted<FilesystemUnmounter> { public: - static void UnmountPaths(const std::vector<std::string>& paths, + static void UnmountPaths(const std::set<std::string>& paths, base::OnceCallback<void(bool success)> callback); private: @@ -310,7 +310,7 @@ }; void FilesystemUnmounter::UnmountPaths( - const std::vector<std::string>& paths, + const std::set<std::string>& paths, base::OnceCallback<void(bool success)> callback) { scoped_refptr<FilesystemUnmounter> unmounter = new FilesystemUnmounter(std::move(callback)); @@ -388,10 +388,12 @@ chromeos::DBusThreadManager::Get() ->GetVmPluginDispatcherClient() ->AddObserver(this); + disks::DiskMountManager::GetInstance()->AddObserver(this); } CrosUsbDetector::~CrosUsbDetector() { DCHECK_EQ(this, g_cros_usb_detector); + disks::DiskMountManager::GetInstance()->RemoveObserver(this); chromeos::DBusThreadManager::Get()->GetConciergeClient()->RemoveVmObserver( this); chromeos::DBusThreadManager::Get() @@ -434,6 +436,12 @@ return devices; } +bool CrosUsbDetector::SharingRequiresReassignPrompt( + const CrosUsbDeviceInfo& device_info) const { + return device_info.shared_vm_name.has_value() || + !device_info.mount_points.empty(); +} + void CrosUsbDetector::ConnectToDeviceManager() { // Tests may set a fake manager. if (!device_manager_) { @@ -493,6 +501,41 @@ } } +void CrosUsbDetector::OnMountEvent( + disks::DiskMountManager::MountEvent event, + MountError error_code, + const disks::DiskMountManager::MountPointInfo& mount_info) { + if (mount_info.mount_type != MOUNT_TYPE_DEVICE) { + return; + } + + const chromeos::disks::Disk* disk = + disks::DiskMountManager::GetInstance()->FindDiskBySourcePath( + mount_info.source_path); + + // This can be null if a drive is physically removed. + if (!disk) { + return; + } + + for (auto& device : usb_devices_) { + if (device.bus_number == disk->bus_number() && + device.port_number == disk->device_number()) { + bool was_empty = device.mount_points.empty(); + if (event == disks::DiskMountManager::MOUNTING) { + device.mount_points.insert(mount_info.mount_path); + } else { + device.mount_points.erase(mount_info.mount_path); + } + + if (!device.is_unmounting && was_empty != device.mount_points.empty()) { + SignalUsbDeviceObservers(); + } + return; + } + } +} + void CrosUsbDetector::OnDeviceChecked( device::mojom::UsbDeviceInfoPtr device_info, bool hide_notification, @@ -648,6 +691,7 @@ // with an in progress attach. RelinquishDeviceClaim(guid); device.shared_vm_name = base::nullopt; + SignalUsbDeviceObservers(); std::move(callback).Run(/*success=*/true); return; } @@ -678,8 +722,8 @@ const std::string& vm_name, const std::string& guid, base::OnceCallback<void(bool success)> callback) { - const CrosUsbDeviceInfo* cur_device = nullptr; - for (const auto& device : usb_devices_) { + CrosUsbDeviceInfo* cur_device = nullptr; + for (auto& device : usb_devices_) { if (device.guid == guid) { cur_device = &device; break; @@ -691,19 +735,12 @@ return; } - std::vector<std::string> paths_to_unmount; - for (const auto& iter : disks::DiskMountManager::GetInstance()->disks()) { - if (iter.second->bus_number() == cur_device->bus_number && - iter.second->device_number() == cur_device->port_number && - iter.second->is_mounted()) { - paths_to_unmount.push_back(iter.second->mount_path()); - } - } - + cur_device->is_unmounting = true; FilesystemUnmounter::UnmountPaths( - paths_to_unmount, base::BindOnce(&CrosUsbDetector::OnUnmountFilesystems, - weak_ptr_factory_.GetWeakPtr(), vm_name, - guid, std::move(callback))); + cur_device->mount_points, + base::BindOnce(&CrosUsbDetector::OnUnmountFilesystems, + weak_ptr_factory_.GetWeakPtr(), vm_name, guid, + std::move(callback))); } void CrosUsbDetector::OnUnmountFilesystems( @@ -711,40 +748,45 @@ const std::string& guid, base::OnceCallback<void(bool success)> callback, bool unmount_success) { - if (!unmount_success) { - // FilesystemUnmounter already logged the error. - std::move(callback).Run(false); + for (auto& device : usb_devices_) { + if (device.guid != guid) { + continue; + } + + device.is_unmounting = false; + + if (!unmount_success) { + // FilesystemUnmounter already logged the error. + std::move(callback).Run(false); + return; + } + + // Detach first if device is attached elsewhere + if (device.shared_vm_name && device.shared_vm_name != vm_name) { + DetachUsbDeviceFromVm( + *device.shared_vm_name, guid, + base::BindOnce(&CrosUsbDetector::AttachAfterDetach, + weak_ptr_factory_.GetWeakPtr(), vm_name, guid, + device.allowed_interfaces_mask, std::move(callback))); + } else { + // Mark the USB device shared so that we know to reattach it on VM + // restart. Setting this flag early also allows the UI not to flicker + // because of the notification resulting from the default VM detach below. + device.shared_vm_name = vm_name; + // The guest port will be set on completion. + + // The device isn't attached. + AttachAfterDetach(vm_name, guid, device.allowed_interfaces_mask, + std::move(callback), + /*detach_success=*/true); + } + return; } - uint32_t allowed_interfaces_mask = 0; - for (auto& device : usb_devices_) { - if (device.guid == guid) { - // Detach first if device is attached elsewhere - if (device.shared_vm_name && device.shared_vm_name != vm_name) { - DetachUsbDeviceFromVm( - *device.shared_vm_name, guid, - base::BindOnce(&CrosUsbDetector::AttachAfterDetach, - weak_ptr_factory_.GetWeakPtr(), vm_name, guid, - device.allowed_interfaces_mask, - std::move(callback))); - return; - } - - // Mark the USB device shared so that we know to reattach it on VM - // restart. - // Setting this flag early also allows the UI not to flicker because of - // the notification resulting from the default VM detach below. - device.shared_vm_name = vm_name; - allowed_interfaces_mask = device.allowed_interfaces_mask; - // The guest port will be set on completion. - break; - } - } - - // The device isn't attached. - AttachAfterDetach(vm_name, guid, allowed_interfaces_mask, std::move(callback), - /*detach_success=*/true); + LOG(ERROR) << "Couldn't find device " << guid; + std::move(callback).Run(false); + return; } void CrosUsbDetector::AttachAfterDetach(
diff --git a/chrome/browser/chromeos/usb/cros_usb_detector.h b/chrome/browser/chromeos/usb/cros_usb_detector.h index e08b9e7..410f828 100644 --- a/chrome/browser/chromeos/usb/cros_usb_detector.h +++ b/chrome/browser/chromeos/usb/cros_usb_detector.h
@@ -17,6 +17,7 @@ #include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chromeos/dbus/concierge_client.h" #include "chromeos/dbus/vm_plugin_dispatcher_client.h" +#include "chromeos/disks/disk_mount_manager.h" #include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" @@ -64,6 +65,10 @@ base::Optional<uint8_t> guest_port; // Interfaces shareable with guest OSes uint32_t allowed_interfaces_mask = 0; + // For a mass storage device, the mount points for active mounts. + std::set<std::string> mount_points; + // An internal flag to suppress observer events as mount_points empties. + bool is_unmounting = false; // TODO(nverne): Add current state and errors etc. }; @@ -77,7 +82,8 @@ // with CrOS, Web or GuestOSs. class CrosUsbDetector : public device::mojom::UsbDeviceManagerClient, public chromeos::ConciergeClient::VmObserver, - public chromeos::VmPluginDispatcherClient::Observer { + public chromeos::VmPluginDispatcherClient::Observer, + public disks::DiskMountManager::Observer { public: // Used to namespace USB notifications to avoid clashes with WebUsbDetector. static std::string MakeNotificationId(const std::string& guid); @@ -132,6 +138,10 @@ // include all connected devices. std::vector<CrosUsbDeviceInfo> GetDevicesSharableWithCrostini() const; + // Returns whether we should prompt the user before sharing the device. + bool SharingRequiresReassignPrompt( + const CrosUsbDeviceInfo& device_info) const; + private: // chromeos::ConciergeClient::VmObserver: void OnVmStarted(const vm_tools::concierge::VmStartedSignal& signal) override; @@ -144,6 +154,12 @@ void OnVmStateChanged( const vm_tools::plugin_dispatcher::VmStateChangedSignal& signal) override; + // disks::DiskMountManager::Observer: + void OnMountEvent( + disks::DiskMountManager::MountEvent event, + MountError error_code, + const disks::DiskMountManager::MountPointInfo& mount_info) override; + // Called after USB device access has been checked. void OnDeviceChecked(device::mojom::UsbDeviceInfoPtr device, bool hide_notification,
diff --git a/chrome/browser/chromeos/usb/cros_usb_detector_unittest.cc b/chrome/browser/chromeos/usb/cros_usb_detector_unittest.cc index 89bf813..a0fc9a1 100644 --- a/chrome/browser/chromeos/usb/cros_usb_detector_unittest.cc +++ b/chrome/browser/chromeos/usb/cros_usb_detector_unittest.cc
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/gmock_move_support.h" #include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/chromeos/crostini/crostini_pref_names.h" #include "chrome/browser/chromeos/crostini/crostini_test_helper.h" @@ -123,11 +124,6 @@ int notify_count_ = 0; }; -// testing::SaveArg doesn't work with move-only types -auto SaveMountCallback(MountCallback* out) { - return [out](std::string, MountCallback in) { *out = std::move(in); }; -} - } // namespace class CrosUsbDetectorTest : public BrowserWithTestWindowTest { @@ -144,8 +140,6 @@ mock_disk_mount_manager_ = new testing::NiceMock<chromeos::disks::MockDiskMountManager>; - ON_CALL(*mock_disk_mount_manager_, disks()) - .WillByDefault(ReturnRef(disks_)); chromeos::disks::DiskMountManager::InitializeForTesting( mock_disk_mount_manager_); } @@ -236,16 +230,29 @@ return devices.front(); } - void AddDisk(std::string name, + void AddDisk(const std::string& name, int bus_number, int device_number, bool mounted) { - disks_[name] = chromeos::disks::Disk::Builder() - .SetBusNumber(bus_number) - .SetDeviceNumber(device_number) - .SetMountPath("/mount/" + name) - .SetIsMounted(mounted) - .Build(); + mock_disk_mount_manager_->CreateDiskEntryForMountDevice( + chromeos::disks::Disk::Builder() + .SetBusNumber(bus_number) + .SetDeviceNumber(device_number) + .SetDevicePath("/dev/" + name) + .SetMountPath("/mount/" + name) + .SetIsMounted(mounted) + .Build()); + if (mounted) + NotifyMountEvent(name, chromeos::disks::DiskMountManager::MOUNTING); + } + + void NotifyMountEvent(const std::string& name, + chromeos::disks::DiskMountManager::MountEvent event) { + chromeos::disks::DiskMountManager::MountPointInfo info( + "/dev/" + name, "/mount/" + name, chromeos::MOUNT_TYPE_DEVICE, + chromeos::disks::MOUNT_CONDITION_NONE); + mock_disk_mount_manager_->NotifyMountEvent( + event, chromeos::MOUNT_ERROR_NONE, info); } protected: @@ -985,10 +992,9 @@ ConnectToDeviceManager(); base::RunLoop().RunUntilIdle(); - auto device = base::MakeRefCounted<device::FakeUsbDeviceInfo>( + device_manager_.CreateAndAddDevice( 0x0200, 0xff, 0xff, 0xff, 0x0100, 1, 2, /*bus_number=*/3, /*port_number=*/4, kManufacturerName, kProductName_1, "5"); - device_manager_.AddDevice(device); base::RunLoop().RunUntilIdle(); AddDisk("disk1", 3, 4, true); @@ -999,19 +1005,22 @@ MountCallback callback1; MountCallback callback4; EXPECT_CALL(*mock_disk_mount_manager_, UnmountPath("/mount/disk1", _)) - .WillOnce(SaveMountCallback(&callback1)); + .WillOnce(MoveArg<1>(&callback1)); EXPECT_CALL(*mock_disk_mount_manager_, UnmountPath("/mount/disk4", _)) - .WillOnce(SaveMountCallback(&callback4)); + .WillOnce(MoveArg<1>(&callback4)); AttachDeviceToVm("VM1", GetSingleDeviceInfo().guid); EXPECT_FALSE(fake_concierge_client_->attach_usb_device_called()); + // Unmount events would normally be fired by the DiskMountManager. + NotifyMountEvent("disk1", chromeos::disks::DiskMountManager::UNMOUNTING); std::move(callback1).Run(chromeos::MOUNT_ERROR_NONE); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(GetSingleDeviceInfo().shared_vm_name.has_value()); EXPECT_FALSE(fake_concierge_client_->attach_usb_device_called()); // All unmounts must complete before sharing succeeds. + NotifyMountEvent("disk4", chromeos::disks::DiskMountManager::UNMOUNTING); std::move(callback4).Run(chromeos::MOUNT_ERROR_NONE); base::RunLoop().RunUntilIdle(); @@ -1023,10 +1032,9 @@ ConnectToDeviceManager(); base::RunLoop().RunUntilIdle(); - auto device = base::MakeRefCounted<device::FakeUsbDeviceInfo>( + device_manager_.CreateAndAddDevice( 0x0200, 0xff, 0xff, 0xff, 0x0100, 1, 2, /*bus_number=*/1, /*port_number=*/5, kManufacturerName, kProductName_1, "5"); - device_manager_.AddDevice(device); base::RunLoop().RunUntilIdle(); AddDisk("disk1", 1, 5, true); @@ -1036,15 +1044,18 @@ MountCallback callback2; MountCallback callback3; EXPECT_CALL(*mock_disk_mount_manager_, UnmountPath("/mount/disk1", _)) - .WillOnce(SaveMountCallback(&callback1)); + .WillOnce(MoveArg<1>(&callback1)); EXPECT_CALL(*mock_disk_mount_manager_, UnmountPath("/mount/disk2", _)) - .WillOnce(SaveMountCallback(&callback2)); + .WillOnce(MoveArg<1>(&callback2)); EXPECT_CALL(*mock_disk_mount_manager_, UnmountPath("/mount/disk3", _)) - .WillOnce(SaveMountCallback(&callback3)); + .WillOnce(MoveArg<1>(&callback3)); + // Unmount events would normally be fired by the DiskMountManager. AttachDeviceToVm("VM1", GetSingleDeviceInfo().guid, /*success=*/false); + NotifyMountEvent("disk1", chromeos::disks::DiskMountManager::UNMOUNTING); std::move(callback1).Run(chromeos::MOUNT_ERROR_NONE); std::move(callback2).Run(chromeos::MOUNT_ERROR_UNKNOWN); + NotifyMountEvent("disk3", chromeos::disks::DiskMountManager::UNMOUNTING); std::move(callback3).Run(chromeos::MOUNT_ERROR_NONE); base::RunLoop().RunUntilIdle(); @@ -1052,3 +1063,43 @@ // callback, so there's not much to check here. EXPECT_FALSE(fake_concierge_client_->attach_usb_device_called()); } + +TEST_F(CrosUsbDetectorTest, ReassignPromptForSharedDevice) { + ConnectToDeviceManager(); + base::RunLoop().RunUntilIdle(); + + device_manager_.CreateAndAddDevice(0x1234, 0x5678); + base::RunLoop().RunUntilIdle(); + + auto device_info = GetSingleDeviceInfo(); + EXPECT_FALSE(cros_usb_detector_->SharingRequiresReassignPrompt(device_info)); + + AttachDeviceToVm("VM1", device_info.guid); + device_info = GetSingleDeviceInfo(); + EXPECT_TRUE(cros_usb_detector_->SharingRequiresReassignPrompt(device_info)); + + DetachDeviceFromVm("VM1", device_info.guid, /*expected_success=*/true); + device_info = GetSingleDeviceInfo(); + EXPECT_FALSE(cros_usb_detector_->SharingRequiresReassignPrompt(device_info)); +} + +TEST_F(CrosUsbDetectorTest, ReassignPromptForStorageDevice) { + ConnectToDeviceManager(); + base::RunLoop().RunUntilIdle(); + + device_manager_.CreateAndAddDevice( + 0x0200, 0xff, 0xff, 0xff, 0x0100, 1, 2, /*bus_number=*/1, + /*port_number=*/5, kManufacturerName, kProductName_1, "5"); + base::RunLoop().RunUntilIdle(); + + auto device_info = GetSingleDeviceInfo(); + EXPECT_FALSE(cros_usb_detector_->SharingRequiresReassignPrompt(device_info)); + + AddDisk("disk1", 1, 5, true); + device_info = GetSingleDeviceInfo(); + EXPECT_TRUE(cros_usb_detector_->SharingRequiresReassignPrompt(device_info)); + + NotifyMountEvent("disk1", chromeos::disks::DiskMountManager::UNMOUNTING); + device_info = GetSingleDeviceInfo(); + EXPECT_FALSE(cros_usb_detector_->SharingRequiresReassignPrompt(device_info)); +}
diff --git a/chrome/browser/continuous_search/android/javatests/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelperTest.java b/chrome/browser/continuous_search/android/javatests/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelperTest.java index de98cb9..8c8edbf6 100644 --- a/chrome/browser/continuous_search/android/javatests/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelperTest.java +++ b/chrome/browser/continuous_search/android/javatests/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelperTest.java
@@ -154,12 +154,9 @@ SearchResultUserData searchResultUserData = tab.getUserDataHost().getUserData(SearchResultUserData.USER_DATA_KEY); Assert.assertTrue(searchResultUserData.isValid()); - Assert.assertEquals( - mServer.getURLWithHostName("www.google.com", TEST_URL + "?q=cat+dog&cs=0"), - observer.mMetadata.getResultUrl().getSpec()); - Assert.assertEquals( - mServer.getURLWithHostName("www.google.com", TEST_URL + "?q=cat+dog&cs=0"), - observer.mUrl.getSpec()); + String url = mServer.getURLWithHostName("www.google.com", TEST_URL + "?q=cat+dog"); + Assert.assertTrue(observer.mMetadata.getResultUrl().getSpec().startsWith(url)); + Assert.assertTrue(observer.mUrl.getSpec().startsWith(url)); tab.loadUrl(new LoadUrlParams(UrlConstants.ABOUT_URL)); });
diff --git a/chrome/browser/enterprise/reporting/report_request_queue_generator_unittest.cc b/chrome/browser/enterprise/reporting/report_request_queue_generator_unittest.cc index 01a549bf..0e4c554 100644 --- a/chrome/browser/enterprise/reporting/report_request_queue_generator_unittest.cc +++ b/chrome/browser/enterprise/reporting/report_request_queue_generator_unittest.cc
@@ -255,7 +255,8 @@ 0); } -TEST_P(ReportRequestQueueGeneratorTest, ReportSeparation) { +// TODO(1153593): Test is very flaky on all bots. Disabling until zmin@ is back. +TEST_P(ReportRequestQueueGeneratorTest, DISABLED_ReportSeparation) { CreateActiveProfilesWithContent(); auto basic_request = GenerateBasicRequest(); auto requests = GenerateRequests(*basic_request);
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc index 3d6059a..638eda69 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
@@ -10,16 +10,16 @@ #include "base/bind.h" #include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" #include "base/path_service.h" #include "base/run_loop.h" #include "base/stl_util.h" #include "base/task/post_task.h" +#include "base/values.h" #include "chrome/browser/extensions/api/platform_keys/platform_keys_test_base.h" -#include "chrome/browser/extensions/policy_test_utils.h" #include "chrome/browser/net/nss_context.h" +#include "chrome/browser/policy/extension_force_install_mixin.h" #include "chrome/common/chrome_paths.h" +#include "components/policy/core/common/mock_configuration_policy_provider.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" @@ -27,11 +27,14 @@ #include "crypto/nss_util_internal.h" #include "crypto/scoped_nss_types.h" #include "crypto/scoped_test_system_nss_key_slot.h" +#include "extensions/browser/event_router.h" +#include "extensions/browser/extension_event_histogram_value.h" #include "extensions/browser/extension_registry.h" +#include "extensions/common/api/test.h" +#include "extensions/common/extension_id.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "net/cert/nss_cert_database.h" -#include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -39,16 +42,16 @@ namespace { -// The test extension will query for the state of the system token. -constexpr char kWaitingForSystemTokenStateMessage[] = - "Waiting for system token state message"; - -// The message sent from a browsertest to the background script in case the -// system token is enabled. -constexpr char kSystemTokenEnabledMessage[] = "System token enabled."; -// The message sent from a browsertest to the background script in case the -// system token is disabled. -constexpr char kSystemTokenDisabledMessage[] = "System token disabled."; +// This message sent from a browsertest to the background script to test the API +// behavior for an extension running in a user session with system token +// enabled. +constexpr char kUserSessionWithSystemTokenEnabledMode[] = + "User session with system token enabled mode."; +// This message sent from a browsertest to the background script to test the API +// behavior for an extension running in a user session with system token +// disabled. +constexpr char kUserSessionWithSystemTokenDisabledMode[] = + "User session with system token disabled mode."; // The test extension has a certificate referencing this private key which will // be stored in the user's token in the test setup. @@ -121,6 +124,18 @@ 0xd8, 0x71, 0x69, 0x5e, 0x8d, 0xb4, 0x48, 0x1c, 0xa4, 0x01, 0xce, 0xc1, 0xb5, 0x6f, 0xe9, 0x1b, 0x32, 0x91, 0x34, 0x38}; +base::FilePath GetExtensionDirName() { + return base::PathService::CheckedGet(chrome::DIR_TEST_DATA) + .Append( + FILE_PATH_LITERAL("extensions/api_test/enterprise_platform_keys/")); +} + +base::FilePath GetExtensionPemFileName() { + return base::PathService::CheckedGet(chrome::DIR_TEST_DATA) + .Append(FILE_PATH_LITERAL( + "extensions/api_test/enterprise_platform_keys.pem")); +} + void ImportPrivateKeyPKCS8ToSlot(const unsigned char* pkcs8_der, size_t pkcs8_der_size, PK11SlotInfo* slot) { @@ -142,18 +157,6 @@ crypto::ScopedSECKEYPrivateKey seckey(seckey_raw); } -// The managed_storage extension has a key defined in its manifest, so that -// its extension ID is well-known and the policy system can push policies for -// the extension. -const char kTestExtensionID[] = "aecpbnckhoppanpmefllkdkohionpmig"; -const char kTestExtensionUpdateManifest[] = - R"(<?xml version='1.0' encoding='UTF-8'?> - <gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'> - <app appid='$1'> - <updatecheck codebase='$2' version='0.1' /> - </app> - </gupdate>)"; - struct Params { Params(PlatformKeysTestBase::SystemTokenStatus system_token_status, PlatformKeysTestBase::EnrollmentStatus enrollment_status, @@ -185,24 +188,10 @@ } void SetUpOnMainThread() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - - embedded_test_server()->ServeFilesFromDirectory(temp_dir_.GetPath()); - - crx_path_ = temp_dir_.GetPath().Append(kCrxFileName); - update_manifest_path_ = temp_dir_.GetPath().Append(kUpdateManifestFileName); - - extension_path_ = test_data_dir_.Append(kExtensionDirName); - pem_path_ = test_data_dir_.Append(kPemFileName); - - base::FilePath created_crx_path = - PackExtensionWithOptions(extension_path_, crx_path_, pem_path_, - /*pem_out_path=*/base::FilePath()); - ASSERT_EQ(created_crx_path, crx_path_); - - GenerateUpdateManifestFile(); - PlatformKeysTestBase::SetUpOnMainThread(); + + extension_force_install_mixin_.InitWithMockPolicyProvider( + profile(), mock_policy_provider()); } void DidGetCertDatabase(const base::Closure& done_callback, @@ -216,18 +205,20 @@ } protected: - const std::string kUpdateManifestFileName = - "enterprise_platform_keys_update_manifest.xml"; + std::string GetTestMode() { + // Only if the system token exists, and the current user is of the same + // domain as the device is enrolled to, the system token is available to the + // extension. + if (system_token_status() == SystemTokenStatus::EXISTS && + enrollment_status() == EnrollmentStatus::ENROLLED && + user_status() == UserStatus::MANAGED_AFFILIATED_DOMAIN) { + return kUserSessionWithSystemTokenEnabledMode; + } - void SetUpTestListeners() { - catcher_ = std::make_unique<extensions::ResultCatcher>(); - listener_ = std::make_unique<ExtensionTestMessageListener>( - kWaitingForSystemTokenStateMessage, - /*will_reply=*/true); + return kUserSessionWithSystemTokenDisabledMode; } - std::unique_ptr<extensions::ResultCatcher> catcher_; - std::unique_ptr<ExtensionTestMessageListener> listener_; + ExtensionForceInstallMixin extension_force_install_mixin_{&mixin_host_}; private: void PrepareTestSystemSlotOnIO( @@ -239,29 +230,6 @@ system_slot->slot()); } - void GenerateUpdateManifestFile() { - const std::string kContent = base::ReplaceStringPlaceholders( - kTestExtensionUpdateManifest, - {kTestExtensionID, - embedded_test_server()->GetURL("/" + kCrxFileName).spec().c_str()}, - /*offsets=*/nullptr); - - int written_bytes = base::WriteFile(update_manifest_path_, kContent.data(), - kContent.size()); - ASSERT_EQ(written_bytes, static_cast<int>(kContent.length())); - } - - const std::string kCrxFileName = "enterprise_platform_keys.crx"; - const std::string kExtensionDirName = "enterprise_platform_keys"; - const std::string kPemFileName = "enterprise_platform_keys.pem"; - - base::FilePath crx_path_; - base::FilePath extension_path_; - base::FilePath pem_path_; - base::FilePath update_manifest_path_; - - base::ScopedTempDir temp_dir_; - DISALLOW_COPY_AND_ASSIGN(EnterprisePlatformKeysTest); }; @@ -280,26 +248,25 @@ base::Unretained(this), loop.QuitClosure())); loop.Run(); } - policy_test_utils::SetExtensionInstallForcelistPolicy( - kTestExtensionID, - embedded_test_server()->GetURL("/" + kUpdateManifestFileName), profile(), - mock_policy_provider()); - SetUpTestListeners(); - ASSERT_TRUE(listener_->WaitUntilSatisfied()); + extensions::ExtensionId extension_id; + ASSERT_TRUE(extension_force_install_mixin_.ForceInstallFromSourceDir( + GetExtensionDirName(), GetExtensionPemFileName(), + ExtensionForceInstallMixin::WaitMode::kBackgroundPageFirstLoad, + &extension_id)); - // Only if the system token exists, and the current user is of the same domain - // as the device is enrolled to, the system token is available to the - // extension. - if (system_token_status() == SystemTokenStatus::EXISTS && - enrollment_status() == EnrollmentStatus::ENROLLED && - user_status() == UserStatus::MANAGED_AFFILIATED_DOMAIN) { - listener_->Reply(kSystemTokenEnabledMessage); - } else { - listener_->Reply(kSystemTokenDisabledMessage); - } + api::test::OnMessage::Info info; + info.data = GetTestMode(); - ASSERT_TRUE(catcher_->GetNextResult()); + auto event = std::make_unique<extensions::Event>( + extensions::events::FOR_TEST, + extensions::api::test::OnMessage::kEventName, + api::test::OnMessage::Create(info), profile()); + extensions::EventRouter::Get(profile())->DispatchEventToExtension( + extension_id, std::move(event)); + + extensions::ResultCatcher catcher; + ASSERT_TRUE(catcher.GetNextResult()); } INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.cc b/chrome/browser/extensions/api/image_writer_private/operation.cc index 374eae9..eae57092 100644 --- a/chrome/browser/extensions/api/image_writer_private/operation.cc +++ b/chrome/browser/extensions/api/image_writer_private/operation.cc
@@ -115,7 +115,7 @@ SetStage(image_writer_api::STAGE_UNZIP); auto unzip_helper = base::MakeRefCounted<UnzipHelper>( - task_runner(), base::Bind(&Operation::OnUnzipOpenComplete, this), + base::Bind(&Operation::OnUnzipOpenComplete, this), base::Bind(&Operation::CompleteAndContinue, this, continuation), base::Bind(&Operation::OnUnzipFailure, this), base::Bind(&Operation::OnUnzipProgress, this));
diff --git a/chrome/browser/extensions/api/image_writer_private/unzip_helper.cc b/chrome/browser/extensions/api/image_writer_private/unzip_helper.cc index 54e7d2d..a2a1ea4 100644 --- a/chrome/browser/extensions/api/image_writer_private/unzip_helper.cc +++ b/chrome/browser/extensions/api/image_writer_private/unzip_helper.cc
@@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/files/file_util.h" -#include "base/single_thread_task_runner.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "chrome/browser/extensions/api/image_writer_private/error_messages.h" @@ -18,13 +17,11 @@ namespace image_writer { UnzipHelper::UnzipHelper( - scoped_refptr<base::SequencedTaskRunner> owner_task_runner, const base::Callback<void(const base::FilePath&)>& open_callback, const base::Closure& complete_callback, const base::Callback<void(const std::string&)>& failure_callback, const base::Callback<void(int64_t, int64_t)>& progress_callback) - : owner_task_runner_(owner_task_runner), - open_callback_(open_callback), + : open_callback_(open_callback), complete_callback_(complete_callback), failure_callback_(failure_callback), progress_callback_(progress_callback), @@ -34,15 +31,6 @@ void UnzipHelper::Unzip(const base::FilePath& image_path, const base::FilePath& temp_dir_path) { - scoped_refptr<base::SingleThreadTaskRunner> task_runner = - base::ThreadPool::CreateSingleThreadTaskRunner( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); - task_runner->PostTask(FROM_HERE, base::BindOnce(&UnzipHelper::UnzipImpl, this, - image_path, temp_dir_path)); -} - -void UnzipHelper::UnzipImpl(const base::FilePath& image_path, - const base::FilePath& temp_dir_path) { if (!zip_reader_->Open(image_path) || !zip_reader_->AdvanceToNextEntry() || !zip_reader_->OpenCurrentEntryInZip()) { OnError(error::kUnzipGenericError); @@ -74,22 +62,19 @@ } void UnzipHelper::OnError(const std::string& error) { - owner_task_runner_->PostTask(FROM_HERE, - base::BindOnce(failure_callback_, error)); + failure_callback_.Run(error); } void UnzipHelper::OnOpenSuccess(const base::FilePath& image_path) { - owner_task_runner_->PostTask(FROM_HERE, - base::BindOnce(open_callback_, image_path)); + open_callback_.Run(image_path); } void UnzipHelper::OnComplete() { - owner_task_runner_->PostTask(FROM_HERE, complete_callback_); + complete_callback_.Run(); } void UnzipHelper::OnProgress(int64_t total_bytes, int64_t curr_bytes) { - owner_task_runner_->PostTask( - FROM_HERE, base::BindOnce(progress_callback_, total_bytes, curr_bytes)); + progress_callback_.Run(total_bytes, curr_bytes); } } // namespace image_writer
diff --git a/chrome/browser/extensions/api/image_writer_private/unzip_helper.h b/chrome/browser/extensions/api/image_writer_private/unzip_helper.h index 984b037..35ae85b 100644 --- a/chrome/browser/extensions/api/image_writer_private/unzip_helper.h +++ b/chrome/browser/extensions/api/image_writer_private/unzip_helper.h
@@ -5,8 +5,8 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_UNZIP_HELPER_H_ #define CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_UNZIP_HELPER_H_ +#include "base/callback.h" #include "base/memory/ref_counted_memory.h" -#include "base/sequenced_task_runner.h" #include "build/build_config.h" namespace base { @@ -21,16 +21,9 @@ namespace image_writer { // A helper to provide Unzip operation. -// Currently ZipReader requires SingleThreadTaskRunner, this class is -// responsible for running ZipReader on a SingleThreadTaskRunner. Unzip -// should be called from sequences (|owner_task_runner_|) and all the -// callbacks of this class is called on that task runner. -// TODO(satorux/lazyboy): Make ZipReader Sequence friendly and remove -// SingleThreadTaskRunner from this class. https://crbug.com/752702. class UnzipHelper : public base::RefCountedThreadSafe<UnzipHelper> { public: explicit UnzipHelper( - scoped_refptr<base::SequencedTaskRunner> owner_task_runner, const base::Callback<void(const base::FilePath&)>& open_callback, const base::Closure& complete_callback, const base::Callback<void(const std::string&)>& failure_callback, @@ -43,15 +36,11 @@ friend class base::RefCountedThreadSafe<UnzipHelper>; ~UnzipHelper(); - void UnzipImpl(const base::FilePath& image_path, - const base::FilePath& temp_dir); void OnError(const std::string& error); void OnOpenSuccess(const base::FilePath& image_path); void OnComplete(); void OnProgress(int64_t total_bytes, int64_t curr_bytes); - scoped_refptr<base::SequencedTaskRunner> owner_task_runner_; - base::Callback<void(const base::FilePath&)> open_callback_; base::Closure complete_callback_; base::Callback<void(const std::string&)> failure_callback_;
diff --git a/chrome/browser/media/history/media_history_browsertest.cc b/chrome/browser/media/history/media_history_browsertest.cc index a636b62e..85a6e7d 100644 --- a/chrome/browser/media/history/media_history_browsertest.cc +++ b/chrome/browser/media/history/media_history_browsertest.cc
@@ -112,6 +112,14 @@ return played; } + static bool EnterPictureInPicture(Browser* browser) { + bool success = false; + return content::ExecuteScriptAndExtractBool( + browser->tab_strip_model()->GetActiveWebContents(), + "enterPictureInPicture();", &success) && + success; + } + static bool SetMediaMetadata(Browser* browser) { return content::ExecuteScript( browser->tab_strip_model()->GetActiveWebContents(), @@ -399,8 +407,8 @@ observer.WaitForExpectedImagesOfType( media_session::mojom::MediaSessionImageType::kArtwork, expected_artwork); - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); + observer.WaitForAudioVideoStates( + {media_session::mojom::MediaAudioVideoState::kAudioVideo}); } SimulateNavigationToCommit(browser); @@ -473,8 +481,8 @@ observer.WaitForState( media_session::mojom::MediaSessionInfo::SessionState::kActive); observer.WaitForExpectedMetadata(expected_metadata); - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); + observer.WaitForAudioVideoStates( + {media_session::mojom::MediaAudioVideoState::kAudioVideo}); } SimulateNavigationToCommit(browser); @@ -518,8 +526,8 @@ observer.WaitForState( media_session::mojom::MediaSessionInfo::SessionState::kActive); observer.WaitForExpectedMetadata(expected_metadata); - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); + observer.WaitForAudioVideoStates( + {media_session::mojom::MediaAudioVideoState::kAudioVideo}); } SimulateNavigationToCommit(browser); @@ -599,8 +607,8 @@ observer.WaitForState( media_session::mojom::MediaSessionInfo::SessionState::kActive); observer.WaitForExpectedMetadata(GetExpectedMetadata()); - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); + observer.WaitForAudioVideoStates( + {media_session::mojom::MediaAudioVideoState::kAudioVideo}); } SimulateNavigationToCommit(browser); @@ -614,8 +622,8 @@ observer.WaitForState( media_session::mojom::MediaSessionInfo::SessionState::kActive); observer.WaitForExpectedMetadata(expected_default_metadata); - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); + observer.WaitForAudioVideoStates( + {media_session::mojom::MediaAudioVideoState::kAudioVideo}); } SimulateNavigationToCommit(browser); @@ -707,8 +715,8 @@ observer.WaitForState( media_session::mojom::MediaSessionInfo::SessionState::kActive); observer.WaitForExpectedMetadata(expected_default_metadata); - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); + observer.WaitForAudioVideoStates( + {media_session::mojom::MediaAudioVideoState::kAudioVideo}); } SimulateNavigationToCommit(browser); @@ -740,8 +748,8 @@ observer.WaitForState( media_session::mojom::MediaSessionInfo::SessionState::kActive); observer.WaitForExpectedMetadata(GetExpectedMetadata()); - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); + observer.WaitForAudioVideoStates( + {media_session::mojom::MediaAudioVideoState::kAudioVideo}); } SimulateNavigationToCommit(browser); @@ -1060,8 +1068,8 @@ *GetMediaSession(browser)); observer.WaitForState( media_session::mojom::MediaSessionInfo::SessionState::kActive); - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioOnly); + observer.WaitForAudioVideoStates( + {media_session::mojom::MediaAudioVideoState::kAudioOnly}); } SimulateNavigationToCommit(browser); @@ -1086,6 +1094,29 @@ } IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest, + DoNotRecordSessionForVideoOnlyInPictureInPicture) { + auto* browser = CreateBrowserFromParam(); + + ASSERT_TRUE(SetupPageAndStartPlayingVideoOnly(browser, GetTestURL())); + ASSERT_TRUE(EnterPictureInPicture(browser)); + + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession(browser)); + observer.WaitForState( + media_session::mojom::MediaSessionInfo::SessionState::kActive); + observer.WaitForAudioVideoStates( + {media_session::mojom::MediaAudioVideoState::kVideoOnly}); + } + + SimulateNavigationToCommit(browser); + + // Verify the session was not recorded. + auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 1); + EXPECT_TRUE(sessions.empty()); +} + +IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest, ResetFeedsWhenBrowsingDataCleared) { auto* browser = CreateBrowserFromParam(); auto* service = GetMediaHistoryService(browser);
diff --git a/chrome/browser/media/history/media_history_contents_observer.cc b/chrome/browser/media/history/media_history_contents_observer.cc index 4e839d4..c3806cc 100644 --- a/chrome/browser/media/history/media_history_contents_observer.cc +++ b/chrome/browser/media/history/media_history_contents_observer.cc
@@ -69,11 +69,11 @@ has_been_active_ = true; } - if (session_info->audio_video_state == - media_session::mojom::MediaAudioVideoState::kAudioVideo) { - has_video_ = true; + if (base::Contains(*session_info->audio_video_states, + media_session::mojom::MediaAudioVideoState::kAudioVideo)) { + has_audio_and_video_ = true; } else { - has_video_ = false; + has_audio_and_video_ = false; } } @@ -112,7 +112,7 @@ // If the media session has never played anything, does not have any metadata // or does not have video then we should not commit the media session. if (!has_been_active_ || !cached_metadata_ || cached_metadata_->IsEmpty() || - !service_ || !has_video_) { + !service_ || !has_audio_and_video_) { return; }
diff --git a/chrome/browser/media/history/media_history_contents_observer.h b/chrome/browser/media/history/media_history_contents_observer.h index e184405..9d156d7 100644 --- a/chrome/browser/media/history/media_history_contents_observer.h +++ b/chrome/browser/media/history/media_history_contents_observer.h
@@ -59,8 +59,8 @@ // Stores whether the media session on this web contents have ever played. bool has_been_active_ = false; - // Stores whether the media session on this web contents has video. - bool has_video_ = false; + // Stores whether the media session on this web contents has audio and video. + bool has_audio_and_video_ = false; // If the web contents is currently navigating then we freeze any updates to // the media session metadata and position. This is because it is cleared
diff --git a/chrome/browser/nearby_sharing/nearby_share_delegate_impl_unittest.cc b/chrome/browser/nearby_sharing/nearby_share_delegate_impl_unittest.cc index 8d0398b..7bd556b 100644 --- a/chrome/browser/nearby_sharing/nearby_share_delegate_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/nearby_share_delegate_impl_unittest.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/nearby_sharing/nearby_share_delegate_impl.h" +#include <memory> + #include "ash/public/cpp/nearby_share_controller.h" #include "ash/public/cpp/session/session_controller.h" #include "base/time/clock.h" @@ -44,9 +46,10 @@ NearbyShareDelegateImplTest() : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME), test_local_device_data_(kDefaultDeviceName), - settings_(&test_pref_service_, &test_local_device_data_), delegate_(&controller_) { RegisterNearbySharingPrefs(test_pref_service_.registry()); + settings_ = std::make_unique<NearbyShareSettings>(&test_pref_service_, + &test_local_device_data_); } ~NearbyShareDelegateImplTest() override = default; @@ -66,10 +69,10 @@ } void SetUp() override { - settings_.SetEnabled(false); + settings_->SetEnabled(false); EXPECT_CALL(nearby_share_service_, GetSettings()) - .WillRepeatedly(Return(&settings_)); + .WillRepeatedly(Return(settings_.get())); EXPECT_CALL(nearby_share_service_, IsInHighVisibility()) .WillRepeatedly(ReturnPointee(&high_visibility_on_)); EXPECT_CALL(nearby_share_service_, AddObserver(_)) @@ -87,13 +90,15 @@ delegate_.set_settings_opener_for_test(std::move(settings_opener)); } + NearbyShareSettings* settings() { return settings_.get(); } + protected: content::BrowserTaskEnvironment task_environment_; MockNearbySharingService nearby_share_service_; TestSessionController session_controller_; sync_preferences::TestingPrefServiceSyncable test_pref_service_; FakeNearbyShareLocalDeviceDataManager test_local_device_data_; - NearbyShareSettings settings_; + std::unique_ptr<NearbyShareSettings> settings_; MockSettingsOpener* settings_opener_; MockNearbyShareController controller_; NearbyShareDelegateImpl delegate_; @@ -102,7 +107,7 @@ }; TEST_F(NearbyShareDelegateImplTest, StartHighVisibilityAndTimeout) { - settings_.SetEnabled(true); + settings()->SetEnabled(true); EXPECT_CALL(*settings_opener_, ShowSettingsPage(_)); EXPECT_CALL(controller_, HighVisibilityEnabledChanged(true)); @@ -119,7 +124,7 @@ } TEST_F(NearbyShareDelegateImplTest, StartStopHighVisibility) { - settings_.SetEnabled(true); + settings()->SetEnabled(true); EXPECT_CALL(*settings_opener_, ShowSettingsPage(_)); EXPECT_CALL(controller_, HighVisibilityEnabledChanged(true)); @@ -135,7 +140,7 @@ } TEST_F(NearbyShareDelegateImplTest, ShowOnboardingAndTurnOnHighVisibility) { - settings_.SetEnabled(false); + settings()->SetEnabled(false); // Called once to start onboarding and once to enter high visibility EXPECT_CALL(*settings_opener_, ShowSettingsPage(_)).Times(2); @@ -146,7 +151,7 @@ // Delegate will observe Nearby Share enabled within onboarding wait period // and will turn on high visibility. - settings_.SetEnabled(true); + settings()->SetEnabled(true); SetHighVisibilityOn(true); EXPECT_CALL(nearby_share_service_, ClearForegroundReceiveSurfaces()); @@ -158,10 +163,10 @@ } TEST_F(NearbyShareDelegateImplTest, ShowOnboardingAndTimeout) { - settings_.SetEnabled(false); + settings()->SetEnabled(false); EXPECT_CALL(nearby_share_service_, GetSettings()) - .WillRepeatedly(Return(&settings_)); + .WillRepeatedly(Return(settings())); EXPECT_CALL(*settings_opener_, ShowSettingsPage(_)); delegate_.EnableHighVisibility(); @@ -173,11 +178,11 @@ // Delegate will observe Nearby Share enabled outside of onboarding wait // period and will not turn on high visibility. - settings_.SetEnabled(true); + settings()->SetEnabled(true); } TEST_F(NearbyShareDelegateImplTest, StopHighVisibilityOnScreenLock) { - settings_.SetEnabled(true); + settings()->SetEnabled(true); EXPECT_CALL(controller_, HighVisibilityEnabledChanged(true)); EXPECT_CALL(*settings_opener_, ShowSettingsPage(_));
diff --git a/chrome/browser/nearby_sharing/nearby_share_settings.cc b/chrome/browser/nearby_sharing/nearby_share_settings.cc index 796d844..1232531 100644 --- a/chrome/browser/nearby_sharing/nearby_share_settings.cc +++ b/chrome/browser/nearby_sharing/nearby_share_settings.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/nearby_sharing/nearby_share_settings.h" +#include "base/metrics/histogram_functions.h" #include "base/values.h" #include "chrome/browser/nearby_sharing/common/nearby_share_enums.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" @@ -34,6 +35,11 @@ base::Unretained(this))); local_device_data_manager_->AddObserver(this); + + if (GetEnabled()) { + base::UmaHistogramEnumeration("Nearby.Share.VisibilityChoice", + GetVisibility()); + } } NearbyShareSettings::~NearbyShareSettings() {
diff --git a/chrome/browser/nearby_sharing/nearby_share_settings_unittest.cc b/chrome/browser/nearby_sharing/nearby_share_settings_unittest.cc index 8e1867d..0a77a63 100644 --- a/chrome/browser/nearby_sharing/nearby_share_settings_unittest.cc +++ b/chrome/browser/nearby_sharing/nearby_share_settings_unittest.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/nearby_sharing/nearby_share_settings.h" +#include <memory> + #include "base/feature_list.h" #include "base/run_loop.h" #include "base/test/bind.h" @@ -70,50 +72,59 @@ scoped_feature_list_.InitAndEnableFeature(features::kNearbySharing); RegisterNearbySharingPrefs(pref_service_.registry()); + nearby_share_settings_ = std::make_unique<NearbyShareSettings>( + &pref_service_, &local_device_data_manager_); + nearby_share_settings_waiter_ = + std::make_unique<NearbyShareSettingsAsyncWaiter>( + nearby_share_settings_.get()); - nearby_share_settings_.AddSettingsObserver( + nearby_share_settings_->AddSettingsObserver( observer_.receiver_.BindNewPipeAndPassRemote()); } ~NearbyShareSettingsTest() override = default; void FlushMojoMessages() { observer_.receiver_.FlushForTesting(); } + NearbyShareSettings* settings() { return nearby_share_settings_.get(); } + + NearbyShareSettingsAsyncWaiter* settings_waiter() { + return nearby_share_settings_waiter_.get(); + } + protected: content::BrowserTaskEnvironment task_environment_; base::test::ScopedFeatureList scoped_feature_list_; TestingPrefServiceSimple pref_service_; FakeNearbyShareLocalDeviceDataManager local_device_data_manager_; FakeNearbyShareSettingsObserver observer_; - NearbyShareSettings nearby_share_settings_{&pref_service_, - &local_device_data_manager_}; - NearbyShareSettingsAsyncWaiter nearby_share_settings_waiter_{ - &nearby_share_settings_}; + std::unique_ptr<NearbyShareSettings> nearby_share_settings_; + std::unique_ptr<NearbyShareSettingsAsyncWaiter> nearby_share_settings_waiter_; }; TEST_F(NearbyShareSettingsTest, GetAndSetEnabled) { EXPECT_EQ(false, observer_.enabled); - nearby_share_settings_.SetEnabled(true); - EXPECT_EQ(true, nearby_share_settings_.GetEnabled()); + settings()->SetEnabled(true); + EXPECT_EQ(true, settings()->GetEnabled()); FlushMojoMessages(); EXPECT_EQ(true, observer_.enabled); bool enabled = false; - nearby_share_settings_waiter_.GetEnabled(&enabled); + settings_waiter()->GetEnabled(&enabled); EXPECT_EQ(true, enabled); - nearby_share_settings_.SetEnabled(false); - EXPECT_EQ(false, nearby_share_settings_.GetEnabled()); + settings()->SetEnabled(false); + EXPECT_EQ(false, settings()->GetEnabled()); FlushMojoMessages(); EXPECT_EQ(false, observer_.enabled); - nearby_share_settings_waiter_.GetEnabled(&enabled); + settings_waiter()->GetEnabled(&enabled); EXPECT_EQ(false, enabled); // Verify that setting the value to false again value doesn't trigger an // observer event. observer_.enabled = true; - nearby_share_settings_.SetEnabled(false); - EXPECT_EQ(false, nearby_share_settings_.GetEnabled()); + settings()->SetEnabled(false); + EXPECT_EQ(false, settings()->GetEnabled()); FlushMojoMessages(); // the observers's value should not have been updated. EXPECT_EQ(true, observer_.enabled); @@ -123,20 +134,20 @@ auto result = nearby_share::mojom::DeviceNameValidationResult::kValid; local_device_data_manager_.set_next_validation_result( nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty); - nearby_share_settings_waiter_.ValidateDeviceName("", &result); + settings_waiter()->ValidateDeviceName("", &result); EXPECT_EQ(result, nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty); local_device_data_manager_.set_next_validation_result( nearby_share::mojom::DeviceNameValidationResult::kValid); - nearby_share_settings_waiter_.ValidateDeviceName( - "this string is 32 bytes in UTF-8", &result); + settings_waiter()->ValidateDeviceName("this string is 32 bytes in UTF-8", + &result); EXPECT_EQ(result, nearby_share::mojom::DeviceNameValidationResult::kValid); } TEST_F(NearbyShareSettingsTest, GetAndSetDeviceName) { std::string name = "not_the_default"; - nearby_share_settings_waiter_.GetDeviceName(&name); + settings_waiter()->GetDeviceName(&name); EXPECT_EQ(kDefaultDeviceName, name); // When we get a validation error, setting the name should not succeed. @@ -144,51 +155,51 @@ auto result = nearby_share::mojom::DeviceNameValidationResult::kValid; local_device_data_manager_.set_next_validation_result( nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty); - nearby_share_settings_waiter_.SetDeviceName("", &result); + settings_waiter()->SetDeviceName("", &result); EXPECT_EQ(result, nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty); - EXPECT_EQ(kDefaultDeviceName, nearby_share_settings_.GetDeviceName()); + EXPECT_EQ(kDefaultDeviceName, settings()->GetDeviceName()); // When the name is valid, setting should succeed. EXPECT_EQ("uncalled", observer_.device_name); result = nearby_share::mojom::DeviceNameValidationResult::kValid; local_device_data_manager_.set_next_validation_result( nearby_share::mojom::DeviceNameValidationResult::kValid); - nearby_share_settings_waiter_.SetDeviceName("d", &result); + settings_waiter()->SetDeviceName("d", &result); EXPECT_EQ(result, nearby_share::mojom::DeviceNameValidationResult::kValid); - EXPECT_EQ("d", nearby_share_settings_.GetDeviceName()); + EXPECT_EQ("d", settings()->GetDeviceName()); EXPECT_EQ("uncalled", observer_.device_name); FlushMojoMessages(); EXPECT_EQ("d", observer_.device_name); - nearby_share_settings_waiter_.GetDeviceName(&name); + settings_waiter()->GetDeviceName(&name); EXPECT_EQ("d", name); } TEST_F(NearbyShareSettingsTest, GetAndSetDataUsage) { EXPECT_EQ(nearby_share::mojom::DataUsage::kUnknown, observer_.data_usage); - nearby_share_settings_.SetDataUsage(DataUsage::kOffline); - EXPECT_EQ(DataUsage::kOffline, nearby_share_settings_.GetDataUsage()); + settings()->SetDataUsage(DataUsage::kOffline); + EXPECT_EQ(DataUsage::kOffline, settings()->GetDataUsage()); FlushMojoMessages(); EXPECT_EQ(nearby_share::mojom::DataUsage::kOffline, observer_.data_usage); nearby_share::mojom::DataUsage data_usage = nearby_share::mojom::DataUsage::kUnknown; - nearby_share_settings_waiter_.GetDataUsage(&data_usage); + settings_waiter()->GetDataUsage(&data_usage); EXPECT_EQ(nearby_share::mojom::DataUsage::kOffline, data_usage); } TEST_F(NearbyShareSettingsTest, GetAndSetVisibility) { EXPECT_EQ(nearby_share::mojom::Visibility::kUnknown, observer_.visibility); - nearby_share_settings_.SetVisibility(Visibility::kNoOne); - EXPECT_EQ(Visibility::kNoOne, nearby_share_settings_.GetVisibility()); + settings()->SetVisibility(Visibility::kNoOne); + EXPECT_EQ(Visibility::kNoOne, settings()->GetVisibility()); FlushMojoMessages(); EXPECT_EQ(nearby_share::mojom::Visibility::kNoOne, observer_.visibility); nearby_share::mojom::Visibility visibility = nearby_share::mojom::Visibility::kUnknown; - nearby_share_settings_waiter_.GetVisibility(&visibility); + settings_waiter()->GetVisibility(&visibility); EXPECT_EQ(nearby_share::mojom::Visibility::kNoOne, visibility); } @@ -197,22 +208,22 @@ std::vector<std::string> allowed_contacts; - nearby_share_settings_waiter_.GetAllowedContacts(&allowed_contacts); + settings_waiter()->GetAllowedContacts(&allowed_contacts); EXPECT_EQ(0u, allowed_contacts.size()); - nearby_share_settings_.SetAllowedContacts({id1}); + settings()->SetAllowedContacts({id1}); FlushMojoMessages(); EXPECT_EQ(1u, observer_.allowed_contacts.size()); EXPECT_EQ(true, base::Contains(observer_.allowed_contacts, id1)); - nearby_share_settings_waiter_.GetAllowedContacts(&allowed_contacts); + settings_waiter()->GetAllowedContacts(&allowed_contacts); EXPECT_EQ(1u, allowed_contacts.size()); EXPECT_EQ(true, base::Contains(allowed_contacts, id1)); - nearby_share_settings_.SetAllowedContacts({}); + settings()->SetAllowedContacts({}); FlushMojoMessages(); EXPECT_EQ(0u, observer_.allowed_contacts.size()); - nearby_share_settings_waiter_.GetAllowedContacts(&allowed_contacts); + settings_waiter()->GetAllowedContacts(&allowed_contacts); EXPECT_EQ(0u, allowed_contacts.size()); }
diff --git a/chrome/browser/notifications/notification_permission_context_unittest.cc b/chrome/browser/notifications/notification_permission_context_unittest.cc index 122c106..101e56b 100644 --- a/chrome/browser/notifications/notification_permission_context_unittest.cc +++ b/chrome/browser/notifications/notification_permission_context_unittest.cc
@@ -325,8 +325,16 @@ .content_setting); } +#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) +// Bulk-disabled for arm64 bot stabilization: https://crbug.com/1154345 +#define MAYBE_TestDenyInIncognitoAfterDelay \ + DISABLED_TestDenyInIncognitoAfterDelay +#else +#define MAYBE_TestDenyInIncognitoAfterDelay TestDenyInIncognitoAfterDelay +#endif + // Tests auto-denial after a time delay in incognito. -TEST_F(NotificationPermissionContextTest, TestDenyInIncognitoAfterDelay) { +TEST_F(NotificationPermissionContextTest, MAYBE_TestDenyInIncognitoAfterDelay) { TestNotificationPermissionContext permission_context( profile()->GetPrimaryOTRProfile()); GURL url("https://www.example.com");
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc b/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc index 19aaa9a..25560f6 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc
@@ -12,15 +12,19 @@ #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/optimization_guide/optimization_guide_session_statistic.h" #include "chrome/browser/optimization_guide/prediction/prediction_manager.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_key.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h" +#include "components/download/public/background_service/download_service.h" +#include "components/download/public/background_service/logger.h" #include "components/metrics/content/subprocess_metrics_provider.h" #include "components/optimization_guide/optimization_guide_constants.h" #include "components/optimization_guide/optimization_guide_features.h" @@ -40,6 +44,9 @@ namespace { +const char kOptimizationGuidePredictionModelsClient[] = + "OptimizationGuidePredictionModels"; + // Fetch and calculate the total number of samples from all the bins for // |histogram_name|. Note: from some browertests run (such as chromeos) there // might be two profiles created, and this will return the total sample count @@ -181,7 +188,9 @@ kSuccessfulWithModelsAndFeatures = 0, kSuccessfulWithFeaturesAndNoModels = 1, kSuccessfulWithModelsAndNoFeatures = 2, - kUnsuccessful = 3, + kSuccessfulWithValidModelFile = 3, + kSuccessfulWithInvalidModelFile = 4, + kUnsuccessful = 5, }; // A WebContentsObserver that asks whether an optimization target can be @@ -241,7 +250,8 @@ models_server_ = std::make_unique<net::EmbeddedTestServer>( net::EmbeddedTestServer::TYPE_HTTPS); - models_server_->ServeFilesFromSourceDirectory("chrome/test/data/previews"); + models_server_->ServeFilesFromSourceDirectory( + "chrome/test/data/optimization_guide"); models_server_->RegisterRequestHandler(base::BindRepeating( &PredictionManagerBrowserTestBase::HandleGetModelsRequest, base::Unretained(this))); @@ -259,6 +269,7 @@ ASSERT_TRUE(https_server_->Start()); https_url_with_content_ = https_server_->GetURL("/english_page.html"); https_url_without_content_ = https_server_->GetURL("/empty.html"); + model_file_url_ = models_server_->GetURL("/unsignedmodel.crx3"); // Set up an OptimizationGuideKeyedService consumer. consumer_ = std::make_unique<OptimizationGuideConsumerWebContentsObserver>( @@ -355,6 +366,9 @@ private: std::unique_ptr<net::test_server::HttpResponse> HandleGetModelsRequest( const net::test_server::HttpRequest& request) { + if (request.GetURL() == model_file_url_) + return std::unique_ptr<net::test_server::HttpResponse>(); + std::unique_ptr<net::test_server::BasicHttpResponse> response; response = std::make_unique<net::test_server::BasicHttpResponse>(); @@ -388,6 +402,14 @@ } else if (response_type_ == PredictionModelsFetcherRemoteResponseType:: kSuccessfulWithModelsAndNoFeatures) { get_models_response->clear_host_model_features(); + } else if (response_type_ == PredictionModelsFetcherRemoteResponseType:: + kSuccessfulWithInvalidModelFile) { + get_models_response->mutable_models(0)->mutable_model()->set_download_url( + https_url_with_content_.spec()); + } else if (response_type_ == PredictionModelsFetcherRemoteResponseType:: + kSuccessfulWithValidModelFile) { + get_models_response->mutable_models(0)->mutable_model()->set_download_url( + model_file_url_.spec()); } else if (response_type_ == PredictionModelsFetcherRemoteResponseType::kUnsuccessful) { response->set_code(net::HTTP_NOT_FOUND); @@ -399,6 +421,7 @@ return std::move(response); } + GURL model_file_url_; GURL https_url_with_content_, https_url_without_content_; std::unique_ptr<net::EmbeddedTestServer> https_server_; std::unique_ptr<net::EmbeddedTestServer> models_server_; @@ -409,7 +432,6 @@ base::flat_set<uint32_t> expected_field_trial_name_hashes_; }; -// Parametrized on whether the ML Service path is enabled. class PredictionManagerBrowserTest : public PredictionManagerBrowserTestBase { public: PredictionManagerBrowserTest() = default; @@ -730,4 +752,187 @@ run_loop->Run(); } +// Implementation of a download system logger that provides the ability to wait +// for certain events to happen, notably added and progressing downloads. +class DownloadServiceObserver : public download::Logger::Observer { + public: + using DownloadCompletedCallback = base::OnceCallback<void()>; + + DownloadServiceObserver() = default; + ~DownloadServiceObserver() override = default; + + // Sets |callback| to be invoked when a download has completed. + void set_download_completed_callback(DownloadCompletedCallback callback) { + download_completed_callback_ = std::move(callback); + } + + // download::Logger::Observer implementation: + void OnServiceStatusChanged(const base::Value& service_status) override {} + void OnServiceDownloadsAvailable( + const base::Value& service_downloads) override {} + void OnServiceDownloadFailed(const base::Value& service_download) override {} + void OnServiceRequestMade(const base::Value& service_request) override {} + void OnServiceDownloadChanged(const base::Value& service_download) override { + const std::string& client = service_download.FindKey("client")->GetString(); + const std::string& state = service_download.FindKey("state")->GetString(); + + if (client != kOptimizationGuidePredictionModelsClient) + return; + + if (state == "COMPLETE" && download_completed_callback_) + std::move(download_completed_callback_).Run(); + } + + private: + DownloadCompletedCallback download_completed_callback_; +}; + +class ModelFileObserver : public OptimizationTargetModelObserver { + public: + using ModelFileReceivedCallback = + base::OnceCallback<void(proto::OptimizationTarget, + const base::FilePath&)>; + + ModelFileObserver() = default; + ~ModelFileObserver() override = default; + + void set_model_file_received_callback(ModelFileReceivedCallback callback) { + file_received_callback_ = std::move(callback); + } + + void OnModelFileUpdated(proto::OptimizationTarget optimization_target, + const base::FilePath& file_path) override { + if (file_received_callback_) + std::move(file_received_callback_).Run(optimization_target, file_path); + } + + private: + ModelFileReceivedCallback file_received_callback_; +}; + +class PredictionManagerModelDownloadingBrowserTest + : public PredictionManagerBrowserTest { + public: + PredictionManagerModelDownloadingBrowserTest() = default; + ~PredictionManagerModelDownloadingBrowserTest() override = default; + + void SetUpOnMainThread() override { + download_service_observer_ = std::make_unique<DownloadServiceObserver>(); + DownloadServiceFactory::GetForKey(browser()->profile()->GetProfileKey()) + ->GetLogger() + ->AddObserver(download_service_observer_.get()); + + model_file_observer_ = std::make_unique<ModelFileObserver>(); + + PredictionManagerBrowserTest::SetUpOnMainThread(); + } + + void TearDownOnMainThread() override { + PredictionManagerBrowserTest::TearDownOnMainThread(); + + DownloadServiceFactory::GetForKey(browser()->profile()->GetProfileKey()) + ->GetLogger() + ->RemoveObserver(download_service_observer_.get()); + } + + DownloadServiceObserver* download_observer() { + return download_service_observer_.get(); + } + + ModelFileObserver* model_file_observer() { + return model_file_observer_.get(); + } + + void RegisterModelFileObserverWithKeyedService() { + OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile()) + ->AddObserverForOptimizationTargetModel( + proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD, + model_file_observer_.get()); + } + + private: + void InitializeFeatureList() override { + scoped_feature_list_.InitWithFeaturesAndParameters( + { + {features::kOptimizationHints, {}}, + {features::kRemoteOptimizationGuideFetching, {}}, + {features::kOptimizationTargetPrediction, {}}, + {features::kOptimizationGuideModelDownloading, + {{"unrestricted_model_downloading", "true"}}}, + }, + {}); + } + + std::unique_ptr<DownloadServiceObserver> download_service_observer_; + std::unique_ptr<ModelFileObserver> model_file_observer_; +}; + +IN_PROC_BROWSER_TEST_F( + PredictionManagerModelDownloadingBrowserTest, + DISABLE_ON_WIN_MAC_CHROMEOS( + TestDownloadUrlAcceptedByDownloadServiceButInvalid)) { + base::HistogramTester histogram_tester; + + SetResponseType(PredictionModelsFetcherRemoteResponseType:: + kSuccessfulWithInvalidModelFile); + + std::unique_ptr<base::RunLoop> completed_run_loop = + std::make_unique<base::RunLoop>(); + download_observer()->set_download_completed_callback( + base::BindOnce([](base::RunLoop* run_loop) { run_loop->Quit(); }, + completed_run_loop.get())); + // Registering should initiate the fetch and receive a response with a model + // containing a download URL and then subsequently downloaded. + RegisterModelFileObserverWithKeyedService(); + + // Wait until the download has completed. + completed_run_loop->Run(); + + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.PredictionModelDownloadManager.DownloadStatus", + PredictionModelDownloadStatus::kFailedCrxVerification, 1); + // An unverified file should not notify us that it's ready. + histogram_tester.ExpectTotalCount( + "OptimizationGuide.PredictionModelUpdateVersion.PainfulPageLoad", 0); +} + +IN_PROC_BROWSER_TEST_F( + PredictionManagerModelDownloadingBrowserTest, + DISABLE_ON_WIN_MAC_CHROMEOS(TestSuccessfulModelFileFlow)) { + // TODO(crbug/1146151): Remove this switch once we can produce a signed model + // file. + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kDisableModelDownloadVerificationForTesting); + + base::HistogramTester histogram_tester; + + SetResponseType( + PredictionModelsFetcherRemoteResponseType::kSuccessfulWithValidModelFile); + + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + model_file_observer()->set_model_file_received_callback(base::BindOnce( + [](base::RunLoop* run_loop, proto::OptimizationTarget optimization_target, + const base::FilePath& file_path) { + EXPECT_EQ(optimization_target, + proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD); + run_loop->Quit(); + }, + run_loop.get())); + + // Registering should initiate the fetch and receive a response with a model + // containing a download URL and then subsequently downloaded. + RegisterModelFileObserverWithKeyedService(); + + // Wait until the observer receives the file. + run_loop->Run(); + + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.PredictionModelDownloadManager.DownloadStatus", + PredictionModelDownloadStatus::kSuccess, 1); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.PredictionModelUpdateVersion.PainfulPageLoad", 123, 1); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.PredictionModelLoadedVersion.PainfulPageLoad", 123, 1); +} + } // namespace optimization_guide
diff --git a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc index 65da14c..c7a34ac 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc
@@ -24,6 +24,7 @@ #include "components/download/public/background_service/download_service.h" #include "components/optimization_guide/optimization_guide_enums.h" #include "components/optimization_guide/optimization_guide_features.h" +#include "components/optimization_guide/optimization_guide_switches.h" #include "components/optimization_guide/optimization_guide_util.h" #include "components/services/unzip/content/unzip_service.h" #include "components/services/unzip/public/cpp/unzip.h" @@ -214,7 +215,7 @@ const base::FilePath& file_path) { DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); - if (should_verify_download_) { + if (!switches::ShouldSkipModelDownloadVerificationForTesting()) { // Verify that the |file_path| contains a file signed with a key we trust. crx_file::VerifierResult verifier_result = crx_file::Verify( file_path, crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF, @@ -269,7 +270,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // Clean up original download file when this function finishes. - base::SequencedTaskRunnerHandle::Get()->PostTask( + background_task_runner_->PostTask( FROM_HERE, base::BindOnce(base::GetDeleteFileCallback(), original_file_path)); @@ -351,8 +352,4 @@ observer.OnModelReady(*model); } -void PredictionModelDownloadManager::TurnOffVerificationForTesting() { - should_verify_download_ = false; -} - } // namespace optimization_guide
diff --git a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.h b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.h index ae3522df..e846615 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.h +++ b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager.h
@@ -116,9 +116,6 @@ // Must be invoked on the UI thread. void NotifyModelReady(const base::Optional<proto::PredictionModel>& model); - // Turns off CRX3 verification for testing. - void TurnOffVerificationForTesting(); - // The set of GUIDs that are still pending download. std::set<std::string> pending_download_guids_;
diff --git a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager_unittest.cc b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager_unittest.cc index dd952b7..51a379f 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_model_download_manager_unittest.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_model_download_manager_unittest.cc
@@ -21,6 +21,7 @@ #include "components/download/public/background_service/test/mock_download_service.h" #include "components/optimization_guide/optimization_guide_enums.h" #include "components/optimization_guide/optimization_guide_features.h" +#include "components/optimization_guide/optimization_guide_switches.h" #include "components/optimization_guide/optimization_guide_util.h" #include "components/services/unzip/content/unzip_service.h" #include "components/services/unzip/in_process_unzipper.h" @@ -158,7 +159,8 @@ } void TurnOffDownloadVerification() { - download_manager_->TurnOffVerificationForTesting(); + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kDisableModelDownloadVerificationForTesting); } private:
diff --git a/chrome/browser/password_manager/android/save_password_message_delegate.cc b/chrome/browser/password_manager/android/save_password_message_delegate.cc index eb83c72..9f54d6c3 100644 --- a/chrome/browser/password_manager/android/save_password_message_delegate.cc +++ b/chrome/browser/password_manager/android/save_password_message_delegate.cc
@@ -4,11 +4,11 @@ #include "chrome/browser/password_manager/android/save_password_message_delegate.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/android/android_theme_resources.h" #include "chrome/browser/android/resource_mapper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/grit/generated_resources.h" #include "components/messages/android/message_dispatcher_bridge.h" #include "components/password_manager/core/browser/password_bubble_experiment.h" @@ -63,18 +63,25 @@ base::BindOnce(&SavePasswordMessageDelegate::HandleDismissCallback, base::Unretained(this))); - PasswordTitleType type = - form_to_save_->GetPendingCredentials().federation_origin.opaque() - ? PasswordTitleType::SAVE_PASSWORD - : PasswordTitleType::SAVE_ACCOUNT; + const password_manager::PasswordForm& pending_credentials = + form_to_save_->GetPendingCredentials(); - message_->SetTitle(GetSavePasswordDialogTitleText( - web_contents_->GetVisibleURL(), - url::Origin::Create(form_to_save_->GetURL()), type)); - if (type == PasswordTitleType::SAVE_PASSWORD && is_saving_google_account) { - message_->SetDescription( - l10n_util::GetStringUTF16(IDS_SAVE_PASSWORD_FOOTER)); + int title_message_id = 0; + if (!pending_credentials.federation_origin.opaque()) { + title_message_id = is_saving_google_account ? IDS_SAVE_ACCOUNT_TO_GOOGLE + : IDS_SAVE_ACCOUNT; + } else { + title_message_id = is_saving_google_account ? IDS_SAVE_PASSWORD_TO_GOOGLE + : IDS_SAVE_PASSWORD; } + + message_->SetTitle(l10n_util::GetStringUTF16(title_message_id)); + + base::string16 description = pending_credentials.username_value; + description.append(base::ASCIIToUTF16(" ")) + .append(pending_credentials.password_value.size(), L'•'); + message_->SetDescription(description); + message_->SetPrimaryButtonText( l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON)); message_->SetIconResourceId(
diff --git a/chrome/browser/password_manager/android/save_password_message_delegate_unittest.cc b/chrome/browser/password_manager/android/save_password_message_delegate_unittest.cc index 297eb302..32c27b2 100644 --- a/chrome/browser/password_manager/android/save_password_message_delegate_unittest.cc +++ b/chrome/browser/password_manager/android/save_password_message_delegate_unittest.cc
@@ -28,8 +28,8 @@ namespace { constexpr char kDefaultUrl[] = "http://example.com"; -constexpr char kAlternativeUrl[] = "http://bar.com"; -constexpr char kAlternativeUrlHost[] = "bar.com"; +constexpr char kUsername[] = "username"; +constexpr char kPassword[] = "password"; constexpr char kDismissalReasonHistogramName[] = "PasswordManager.SaveUIDismissalReason"; } // namespace @@ -43,6 +43,7 @@ std::unique_ptr<MockPasswordFormManagerForUI> CreateFormManager( const GURL& url); + void SetUsernameAndPassword(base::string16 username, base::string16 password); void CreateMessage(std::unique_ptr<PasswordFormManagerForUI> form_to_save, bool is_saving_google_account); @@ -89,6 +90,13 @@ return form_manager; } +void SavePasswordMessageDelegateTest::SetUsernameAndPassword( + base::string16 username, + base::string16 password) { + form_.username_value = std::move(username); + form_.password_value = std::move(password); +} + void SavePasswordMessageDelegateTest::CreateMessage( std::unique_ptr<PasswordFormManagerForUI> form_to_save, bool is_saving_google_account) { @@ -134,12 +142,18 @@ // Tests that message properties (title, description, icon, button text) are // set correctly. TEST_F(SavePasswordMessageDelegateTest, MessagePropertyValues) { + SetUsernameAndPassword(base::ASCIIToUTF16(kUsername), + base::ASCIIToUTF16(kPassword)); auto form_manager = CreateFormManager(GURL(kDefaultUrl)); CreateMessage(std::move(form_manager), false /*is_saving_google_account*/); EXPECT_EQ(l10n_util::GetStringUTF16(IDS_SAVE_PASSWORD), GetMessageWrapper()->GetTitle()); - EXPECT_EQ(base::string16(), GetMessageWrapper()->GetDescription()); + EXPECT_NE(base::string16::npos, GetMessageWrapper()->GetDescription().find( + base::ASCIIToUTF16(kUsername))); + EXPECT_EQ(base::string16::npos, GetMessageWrapper()->GetDescription().find( + base::ASCIIToUTF16(kPassword))); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON), GetMessageWrapper()->GetPrimaryButtonText()); EXPECT_EQ( @@ -149,28 +163,14 @@ TriggerMessageDismissedCallback(); } -// Tests that the description is set correctly when user is syncing passwords to +// Tests that the title is set correctly when the user is syncing passwords to // their Google Account. -TEST_F(SavePasswordMessageDelegateTest, SaveToGoogleDescription) { +TEST_F(SavePasswordMessageDelegateTest, SaveToGoogleTitle) { auto form_manager = CreateFormManager(GURL(kDefaultUrl)); CreateMessage(std::move(form_manager), true /*is_saving_google_account*/); - EXPECT_EQ(l10n_util::GetStringUTF16(IDS_SAVE_PASSWORD_FOOTER), - GetMessageWrapper()->GetDescription()); - - TriggerMessageDismissedCallback(); -} - -// Tests that the title is set correctly when form domain differs from current -// page domain. -TEST_F(SavePasswordMessageDelegateTest, TitleForDifferentDomainPassword) { - auto form_manager = CreateFormManager(GURL(kAlternativeUrl)); - CreateMessage(std::move(form_manager), false /*is_saving_google_account*/); - - EXPECT_NE(l10n_util::GetStringUTF16(IDS_SAVE_PASSWORD), + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_SAVE_PASSWORD_TO_GOOGLE), GetMessageWrapper()->GetTitle()); - EXPECT_NE(base::string16::npos, GetMessageWrapper()->GetTitle().find( - base::ASCIIToUTF16(kAlternativeUrlHost))); TriggerMessageDismissedCallback(); }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index eca32675..c8b1a70 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -94,12 +94,12 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" -#include "content/public/common/origin_util.h" #include "extensions/buildflags/buildflags.h" #include "google_apis/gaia/gaia_urls.h" #include "net/base/url_util.h" #include "net/cert/cert_status_flags.h" #include "services/metrics/public/cpp/ukm_recorder.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" #include "third_party/re2/src/re2/re2.h" #include "url/url_constants.h" @@ -751,7 +751,7 @@ } bool ChromePasswordManagerClient::IsCommittedMainFrameSecure() const { - return content::IsPotentiallyTrustworthyOrigin( + return network::IsOriginPotentiallyTrustworthy( web_contents()->GetMainFrame()->GetLastCommittedOrigin()); }
diff --git a/chrome/browser/policy/extension_force_install_mixin.h b/chrome/browser/policy/extension_force_install_mixin.h index a3cea1cb..e884c7f0 100644 --- a/chrome/browser/policy/extension_force_install_mixin.h +++ b/chrome/browser/policy/extension_force_install_mixin.h
@@ -7,6 +7,7 @@ #include <string> +#include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/optional.h" @@ -117,7 +118,8 @@ bool ForceInstallFromCrx(const base::FilePath& crx_path, WaitMode wait_mode, extensions::ExtensionId* extension_id = nullptr, - base::Version* extension_version = nullptr); + base::Version* extension_version = nullptr) + WARN_UNUSED_RESULT; // Force-installs the extension from the given source directory (which should // contain the manifest.json file and all other files of the extension). // Under the hood, packs the directory into a CRX file and serves it like @@ -132,7 +134,7 @@ const base::Optional<base::FilePath>& pem_path, WaitMode wait_mode, extensions::ExtensionId* extension_id = nullptr, - base::Version* extension_version = nullptr); + base::Version* extension_version = nullptr) WARN_UNUSED_RESULT; // Returns the extension, or null if it's not installed yet. const extensions::Extension* GetInstalledExtension(
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 326a5aa..1a181d49 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -1077,6 +1077,9 @@ // This method should be periodically pruned of year+ old migrations. void MigrateObsoleteLocalStatePrefs(PrefService* local_state) { + // BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS + // Please don't delete the preceding line. It is used by PRESUBMIT.py. + // Added 1/2020 #if defined(OS_MAC) local_state->ClearPref(kKeyCreated); @@ -1094,10 +1097,16 @@ // Added 4/2020. local_state->ClearPref(kSupervisedUsersNextId); #endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Please don't delete the following line. It is used by PRESUBMIT.py. + // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS } // This method should be periodically pruned of year+ old migrations. void MigrateObsoleteProfilePrefs(Profile* profile) { + // BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS + // Please don't delete the preceding line. It is used by PRESUBMIT.py. + PrefService* profile_prefs = profile->GetPrefs(); // Check MigrateDeprecatedAutofillPrefs() to see if this is safe to remove. @@ -1188,4 +1197,7 @@ // Added 11/2020 profile_prefs->ClearPref(kDRMSalt); + + // Please don't delete the following line. It is used by PRESUBMIT.py. + // END_MIGRATE_OBSOLETE_PROFILE_PREFS }
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc index 3c6e795..f517bc21 100644 --- a/chrome/browser/printing/print_browsertest.cc +++ b/chrome/browser/printing/print_browsertest.cc
@@ -209,8 +209,8 @@ EXPECT_EQ(document_cookie, document_cookie_); ASSERT_TRUE(param->metafile_data_region.IsValid()); EXPECT_GT(param->metafile_data_region.GetSize(), 0U); - task_runner_->PostTask(FROM_HERE, msg_callback_); std::move(callback).Run(document_cookie, std::move(param)); + task_runner_->PostTask(FROM_HERE, msg_callback_); } void Bind(mojo::ScopedInterfaceEndpointHandle handle) { @@ -218,6 +218,17 @@ std::move(handle))); } + static mojom::DidPrintContentParamsPtr GetDefaultDidPrintContentParams() { + auto printed_frame_params = mojom::DidPrintContentParams::New(); + // Creates a small amount of region to avoid passing empty data to mojo. + constexpr size_t kSize = 10; + base::MappedReadOnlyRegion region_mapping = + base::ReadOnlySharedMemoryRegion::Create(kSize); + printed_frame_params->metafile_data_region = + std::move(region_mapping.region); + return printed_frame_params; + } + // mojom::PrintRenderFrameInterceptorForTesting mojom::PrintRenderFrame* GetForwardingInterface() override { NOTREACHED(); @@ -226,16 +237,8 @@ void PrintFrameContent(mojom::PrintFrameContentParamsPtr params, PrintFrameContentCallback callback) override { // Sends the printed result back. - mojom::DidPrintContentParamsPtr printed_frame_params = - mojom::DidPrintContentParams::New(); - // Creates a small amount of region to avoid passing empty data to mojo. - constexpr size_t kSize = 10; - base::MappedReadOnlyRegion region_mapping = - base::ReadOnlySharedMemoryRegion::Create(kSize); - printed_frame_params->metafile_data_region = - std::move(region_mapping.region); OnDidPrintFrameContent(params->document_cookie, - std::move(printed_frame_params), + GetDefaultDidPrintContentParams(), std::move(callback)); auto* client = PrintCompositeClient::FromWebContents(web_contents_); @@ -814,6 +817,70 @@ WaitUntilCallbackReceived(); } +// Printing frame content with a cross-site iframe before creating +// PrintCompositor by the main frame. +// This test passes if PrintCompositeClient queues subframes when +// it doesn't have PrintCompositor and clears them after PrintCompositor is +// created. +IN_PROC_BROWSER_TEST_F(PrintBrowserTest, + PrintSubframeContentBeforeCompositeClientCreation) { + ASSERT_TRUE(embedded_test_server()->Started()); + GURL url( + embedded_test_server()->GetURL("/printing/content_with_iframe.html")); + ui_test_utils::NavigateToURL(browser(), url); + + // When OOPIF is not enabled, CompositorClient is not used. + if (!IsOopifEnabled()) + return; + + content::WebContents* original_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_EQ(2u, original_contents->GetAllFrames().size()); + content::RenderFrameHost* main_frame = original_contents->GetMainFrame(); + ASSERT_TRUE(main_frame); + content::RenderFrameHost* test_frame = original_contents->GetAllFrames()[1]; + ASSERT_TRUE(test_frame); + ASSERT_NE(main_frame->GetProcess(), test_frame->GetProcess()); + + CreateTestPrintRenderFrame(main_frame, original_contents); + CreateTestPrintRenderFrame(test_frame, original_contents); + SetNumExpectedMessages(2); + + // Print on the main frame. + GetPrintRenderFrame(main_frame) + ->PrintFrameContent(GetDefaultPrintFrameParams(), base::DoNothing()); + + // The printed result will be received and checked in TestPrintRenderFrame. + WaitUntilCallbackReceived(); + + // As PrintFrameContent() with the main frame doesn't call + // PrintCompositeClient::DoCompositeDocumentToPdf() on this test, when + // PrintCompositeClient::OnDidPrintFrameContent() is called with the sub + // frame, it doesn't have mojom::PrintCompositor. + auto* client = PrintCompositeClient::FromWebContents(original_contents); + ASSERT_FALSE(client->compositor_); + + // When there is no mojom::PrintCompositor, PrintCompositeClient queues + // subframes and handles them when mojom::PrintCompositor is created. + // |requested_subframes_| should have the requested subframes. + ASSERT_EQ(1u, client->requested_subframes_.size()); + PrintCompositeClient::RequestedSubFrame* subframe_in_queue = + client->requested_subframes_.begin()->get(); + ASSERT_EQ(kDefaultDocumentCookie, subframe_in_queue->document_cookie_); + ASSERT_EQ(test_frame->GetProcess()->GetID(), + subframe_in_queue->render_process_id_); + ASSERT_EQ(test_frame->GetRoutingID(), subframe_in_queue->render_frame_id_); + + // Creates mojom::PrintCompositor. + client->DoCompositeDocumentToPdf( + kDefaultDocumentCookie, main_frame, + *TestPrintRenderFrame::GetDefaultDidPrintContentParams(), + base::DoNothing()); + ASSERT_TRUE(client->GetCompositeRequest(kDefaultDocumentCookie)); + // |requested_subframes_| should be empty. + ASSERT_TRUE(client->requested_subframes_.empty()); +} + // Printing preview a simple webpage when site per process is enabled. // Test that the basic oopif printing should succeed. The test should not crash // or timed out. There could be other reasons that cause the test fail, but the
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc index 99fe5a6..ea1e596 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
@@ -10,6 +10,45 @@ #include "chrome/common/chrome_features.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/prefs/pref_service.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace { + +bool HasNonDefaultBlockSetting(const ContentSettingsForOneType& cookie_settings, + const GURL& url, + const GURL& top_frame_origin) { + // APIs are allowed unless there is an effective non-default cookie content + // setting block exception. A default cookie content setting is one that has a + // wildcard pattern for both primary and secondary patterns. Content + // settings are listed in descending order of priority such that the first + // that matches is the effective content setting. A default setting can appear + // anywhere in the list. Content settings which appear after a default content + // setting are completely superseded by that content setting and are thus not + // consulted. Default settings which appear before other settings are applied + // from higher precedence sources, such as policy. The value of a default + // content setting applied by a higher precedence provider is not consulted + // here. For managed policies, the state will be reflected directly in the + // privacy sandbox preference. Other providers (such as extensions) will have + // been considered for the initial value of the privacy sandbox preference. + for (const auto& setting : cookie_settings) { + if (setting.primary_pattern == ContentSettingsPattern::Wildcard() && + setting.secondary_pattern == ContentSettingsPattern::Wildcard()) { + return false; + } + if (setting.primary_pattern.Matches(url) && + setting.secondary_pattern.Matches(top_frame_origin)) { + return setting.GetContentSetting() == + ContentSetting::CONTENT_SETTING_BLOCK; + } + } + // ContentSettingsForOneType should always end with a default content setting + // from the default provider. + NOTREACHED(); + return false; +} + +} // namespace PrivacySandboxSettings::PrivacySandboxSettings( content_settings::CookieSettings* cookie_settings, @@ -21,12 +60,26 @@ bool PrivacySandboxSettings::IsFlocAllowed( const GURL& url, - const GURL& site_for_cookies, const base::Optional<url::Origin>& top_frame_origin) const { - // Simply respect cookie settings. - // TODO(crbug.com/1152336): Respect privacy sandbox settings. - return cookie_settings_->IsCookieAccessAllowed(url, site_for_cookies, - top_frame_origin); + if (!base::FeatureList::IsEnabled(features::kPrivacySandboxSettings)) { + // Simply respect cookie settings if the UI is not available. An empty site + // for cookies is provided so the context is always as a third party. + return cookie_settings_->IsCookieAccessAllowed(url, GURL(), + top_frame_origin); + } + + if (!pref_service_->GetBoolean(prefs::kPrivacySandboxApisEnabled)) + return false; + + // TODO (crbug.com/1155504): Bypassing CookieSettings to access content + // settings directly ignores allowlisted schemes and the storage access API. + // These should be taken into account here. + ContentSettingsForOneType cookie_settings; + cookie_settings_->GetCookieSettings(&cookie_settings); + + return !HasNonDefaultBlockSetting( + cookie_settings, url, + top_frame_origin ? top_frame_origin->GetURL() : GURL()); } base::Time PrivacySandboxSettings::FlocDataAccessibleSince() const {
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h index ee4123c..2fea6908 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h
@@ -33,11 +33,9 @@ PrefService* prefs); // Determines whether FLoC is allowable in a particular context. - // |site_for_cookies| is used to determine whether a request is in a 3P - // context, while |top_frame_origin| if set, is used to check for content - // settings which could both affect 1P and 3P cookies. + // |top_frame_origin| is used to check for content settings which could both + // affect 1P and 3P contexts. bool IsFlocAllowed(const GURL& url, - const GURL& site_for_cookies, const base::Optional<url::Origin>& top_frame_origin) const; // Returns the point in time from which history is elligible to be used when
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc new file mode 100644 index 0000000..3b69924 --- /dev/null +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
@@ -0,0 +1,320 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h" + +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/content_settings/cookie_settings_factory.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/privacy_sandbox/privacy_sandbox_prefs.h" +#include "chrome/common/chrome_features.h" +#include "chrome/test/base/testing_profile.h" +#include "components/content_settings/core/browser/cookie_settings.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/pref_names.h" +#include "components/content_settings/core/test/content_settings_mock_provider.h" +#include "components/content_settings/core/test/content_settings_test_utils.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +// Define an additional content setting value to simulate an unmanaged default +// content setting. +const ContentSetting kNoSetting = static_cast<ContentSetting>(-1); + +struct CookieContentSettingException { + std::string primary_pattern; + std::string secondary_pattern; + ContentSetting content_setting; +}; + +} // namespace + +class PrivacySandboxSettingsTest : public testing::Test { + public: + PrivacySandboxSettingsTest() = default; + + void SetUp() override { + privacy_sandbox_settings_ = std::make_unique<PrivacySandboxSettings>( + CookieSettingsFactory::GetForProfile(profile()).get(), + profile()->GetPrefs()); + } + + // Sets up preferences and content settings based on provided parameters. + void SetupTestState( + bool privacy_sandbox_available, + bool privacy_sandbox_enabled, + ContentSetting default_cookie_setting, + std::vector<CookieContentSettingException> user_cookie_exceptions, + ContentSetting managed_cookie_setting, + std::vector<CookieContentSettingException> managed_cookie_exceptions) { + // Setup cookie content settings. + auto* map = HostContentSettingsMapFactory::GetForProfile(profile()); + auto user_provider = std::make_unique<content_settings::MockProvider>(); + auto managed_provider = std::make_unique<content_settings::MockProvider>(); + + if (default_cookie_setting != kNoSetting) { + user_provider->SetWebsiteSetting( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), ContentSettingsType::COOKIES, + std::make_unique<base::Value>(default_cookie_setting)); + } + + for (const auto& exception : user_cookie_exceptions) { + user_provider->SetWebsiteSetting( + ContentSettingsPattern::FromString(exception.primary_pattern), + ContentSettingsPattern::FromString(exception.secondary_pattern), + ContentSettingsType::COOKIES, + std::make_unique<base::Value>(exception.content_setting)); + } + + if (managed_cookie_setting != kNoSetting) { + managed_provider->SetWebsiteSetting( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), ContentSettingsType::COOKIES, + std::make_unique<base::Value>(managed_cookie_setting)); + } + + for (const auto& exception : managed_cookie_exceptions) { + managed_provider->SetWebsiteSetting( + ContentSettingsPattern::FromString(exception.primary_pattern), + ContentSettingsPattern::FromString(exception.secondary_pattern), + ContentSettingsType::COOKIES, + std::make_unique<base::Value>(exception.content_setting)); + } + + content_settings::TestUtils::OverrideProvider( + map, std::move(user_provider), + HostContentSettingsMap::DEFAULT_PROVIDER); + content_settings::TestUtils::OverrideProvider( + map, std::move(managed_provider), + HostContentSettingsMap::POLICY_PROVIDER); + + // Setup privacy sandbox feature & preference. + feature_list()->Reset(); + if (privacy_sandbox_available) + feature_list()->InitAndEnableFeature(features::kPrivacySandboxSettings); + else + feature_list()->InitAndDisableFeature(features::kPrivacySandboxSettings); + + profile()->GetTestingPrefService()->SetUserPref( + prefs::kPrivacySandboxApisEnabled, + std::make_unique<base::Value>(privacy_sandbox_enabled)); + } + + TestingProfile* profile() { return &profile_; } + PrivacySandboxSettings* privacy_sandbox_settings() { + return privacy_sandbox_settings_.get(); + } + base::test::ScopedFeatureList* feature_list() { return &feature_list_; } + + private: + content::BrowserTaskEnvironment browser_task_environment_; + TestingProfile profile_; + std::unique_ptr<PrivacySandboxSettings> privacy_sandbox_settings_; + base::test::ScopedFeatureList feature_list_; +}; + +TEST_F(PrivacySandboxSettingsTest, CookieSettingAppliesWhenUiDisabled) { + // When the Privacy Sandbox UI is unavailable, the cookie setting should + // apply directly. + SetupTestState( + /*privacy_sandbox_available=*/false, + /*privacy_sandbox_enabled=*/false, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + /*user_cookie_exceptions=*/{}, + /*managed_cookie_setting=*/kNoSetting, + /*managed_cookie_exceptions=*/{}); + EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); + + SetupTestState( + /*privacy_sandbox_available=*/false, + /*privacy_sandbox_enabled=*/false, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK, + /*user_cookie_exceptions=*/ + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_ALLOW}, + {"https://another-embedded.com", "*", + ContentSetting::CONTENT_SETTING_BLOCK}}, + /*managed_cookie_setting=*/kNoSetting, + /*managed_cookie_exceptions=*/{}); + EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); + EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://another-embedded.com"), base::nullopt)); + + SetupTestState( + /*privacy_sandbox_available=*/false, + /*privacy_sandbox_enabled=*/true, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + /*user_cookie_exceptions=*/ + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_ALLOW}}, + /*managed_cookie_setting=*/kNoSetting, + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_BLOCK}}); + EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), base::nullopt)); +} + +TEST_F(PrivacySandboxSettingsTest, PreferenceOverridesDefaultContentSetting) { + // When the Privacy Sandbox UI is available, the sandbox preference should + // override the default cookie content setting. + SetupTestState( + /*privacy_sandbox_available=*/true, + /*privacy_sandbox_enabled=*/true, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK, + /*user_cookie_exceptions=*/{}, + /*managed_cookie_setting=*/kNoSetting, + /*managed_cookie_exceptions=*/{}); + EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); + + // An allow exception should not override the preference value. + SetupTestState( + /*privacy_sandbox_available=*/true, + /*privacy_sandbox_enabled=*/false, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + /*user_cookie_exceptions=*/ + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_ALLOW}}, + /*managed_cookie_setting=*/kNoSetting, + /*managed_cookie_exceptions=*/{}); + EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); +} + +TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) { + // When the Privacy Sandbox UI & preference are both enabled, targeted cookie + // block exceptions should still apply. + SetupTestState( + /*privacy_sandbox_available=*/true, + /*privacy_sandbox_enabled=*/true, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + /*user_cookie_exceptions=*/ + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_BLOCK}}, + /*managed_cookie_setting=*/kNoSetting, + /*managed_cookie_exceptions=*/{}); + EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); + + // User created exceptions should not apply if a managed default coookie + // setting exists. What the managed default setting actually is should *not* + // affect whether APIs are enabled. The cookie managed state is reflected in + // the privacy sandbox preferences directly. + SetupTestState( + /*privacy_sandbox_available=*/true, + /*privacy_sandbox_enabled=*/true, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + /*user_cookie_exceptions=*/ + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_BLOCK}}, + /*managed_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK, + /*managed_cookie_exceptions=*/{}); + EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); + + // Managed content setting exceptions should override both the privacy + // sandbox pref and any user settings. + SetupTestState( + /*privacy_sandbox_available=*/true, + /*privacy_sandbox_enabled=*/true, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + /*user_cookie_exceptions=*/ + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_ALLOW}}, + /*managed_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_BLOCK}}); + EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://unrelated.com"), + url::Origin::Create(GURL("https://unrelated.com")))); + + // A less specific block exception should not override a more specific allow + // exception. The effective content setting in this scenario is still allow, + // even though a block exception exists. + SetupTestState( + /*privacy_sandbox_available=*/true, + /*privacy_sandbox_enabled=*/true, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + /*user_cookie_exceptions=*/ + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_ALLOW}, + {"https://[*.]embedded.com", "https://[*.]test.com", + ContentSetting::CONTENT_SETTING_BLOCK}}, + /*managed_cookie_setting=*/kNoSetting, + /*managed_cookie_exceptions=*/{}); + EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); + + // Exceptions which specify a top frame origin should not match against an + // empty top frame. + SetupTestState( + /*privacy_sandbox_available=*/true, + /*privacy_sandbox_enabled=*/true, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK, + /*user_cookie_exceptions=*/ + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_BLOCK}}, + /*managed_cookie_setting=*/kNoSetting, + /*managed_cookie_exceptions=*/ + {{"https://embedded.com", "https://test.com", + ContentSetting::CONTENT_SETTING_BLOCK}}); + EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), base::nullopt)); + + // Exceptions which specify a wildcard top frame origin should match both + // empty top frames and non empty top frames. + SetupTestState( + /*privacy_sandbox_available=*/true, + /*privacy_sandbox_enabled=*/true, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + /*user_cookie_exceptions=*/ + {{"https://embedded.com", "*", ContentSetting::CONTENT_SETTING_BLOCK}}, + /*managed_cookie_setting=*/kNoSetting, + /*managed_cookie_exceptions=*/{}); + EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), base::nullopt)); + EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://test.com")))); +} + +TEST_F(PrivacySandboxSettingsTest, FlocAlwaysThirdParty) { + // Check that when the UI is not enabled, all FLoC requests are considered + // as third party requests. + profile()->GetTestingPrefService()->SetUserPref( + prefs::kCookieControlsMode, + std::make_unique<base::Value>(static_cast<int>( + content_settings::CookieControlsMode::kBlockThirdParty))); + SetupTestState( + /*privacy_sandbox_available=*/false, + /*privacy_sandbox_enabled=*/false, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, + /*user_cookie_exceptions=*/{}, + /*managed_cookie_setting=*/kNoSetting, + /*managed_cookie_exceptions=*/{}); + EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), + url::Origin::Create(GURL("https://embedded.com")))); + EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed( + GURL("https://embedded.com"), base::nullopt)); +}
diff --git a/chrome/browser/resources/inline_login/BUILD.gn b/chrome/browser/resources/inline_login/BUILD.gn index 3028b89..3cd125f5 100644 --- a/chrome/browser/resources/inline_login/BUILD.gn +++ b/chrome/browser/resources/inline_login/BUILD.gn
@@ -15,6 +15,7 @@ deps = [ ":inline_login_app", ":inline_login_browser_proxy", + ":welcome_page_app", ] } @@ -24,12 +25,21 @@ "//chrome/browser/resources/gaia_auth_host:authenticator.m", "//third_party/polymer/v3_0/components-chromium/paper-spinner:paper-spinner-lite", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager.m", "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] externs_list = [ "$externs_path/webview_tag.js" ] } +js_library("welcome_page_app") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:load_time_data.m", + ] +} + js_library("inline_login_browser_proxy") { deps = [ "//chrome/browser/resources/gaia_auth_host:authenticator.m", @@ -39,5 +49,8 @@ } html_to_js("web_components") { - js_files = [ "inline_login_app.js" ] + js_files = [ + "inline_login_app.js", + "welcome_page_app.js", + ] }
diff --git a/chrome/browser/resources/inline_login/inline_login.html b/chrome/browser/resources/inline_login/inline_login.html index dfc66c3..3ce70ca 100644 --- a/chrome/browser/resources/inline_login/inline_login.html +++ b/chrome/browser/resources/inline_login/inline_login.html
@@ -10,6 +10,7 @@ body { height: 100%; margin: 0; + overflow: hidden; padding: 0; } </style>
diff --git a/chrome/browser/resources/inline_login/inline_login_app.html b/chrome/browser/resources/inline_login/inline_login_app.html index 7e86592..12f6399e 100644 --- a/chrome/browser/resources/inline_login/inline_login_app.html +++ b/chrome/browser/resources/inline_login/inline_login_app.html
@@ -13,7 +13,8 @@ width: 100%; } - .container { + .container, + #addAccount.active { align-items: center; display: flex; flex-grow: 1; @@ -21,9 +22,15 @@ } <if expr="chromeos"> - .container { + /* Content of the webview already has 64px border, add negative margin to make + * distance to the top 64px. */ + #addAccount { margin-top: calc(-1 * var(--dialog-top-border-size)); } + /* Make distance to the top 64px. */ + #welcome { + margin-top: calc(64px - var(--dialog-top-border-size)); + } </if> .signin-frame { @@ -36,7 +43,8 @@ padding: 0 32px 32px; } - .action-buttons { + .action-buttons, + .next-button { margin-inline-start: auto; } @@ -53,24 +61,48 @@ </style> <div class="container"> - <webview id="signinFrame" name="signin-frame" class="signin-frame" - hidden$="[[loading_]]" allowscaling></webview> - <paper-spinner-lite active="[[loading_]]"> - </paper-spinner-lite> + <cr-view-manager id="viewManager"> + <!-- Show welcome screen on Chrome OS to clarify that account will be + available in ARC. --> + <if expr="chromeos"> + <div id="[[View.welcome]]" slot="view"> + <welcome-page-app on-opened-new-window="closeDialog_"> + </welcome-page-app> + </div> + </if> + + <div id="[[View.addAccount]]" slot="view"> + <paper-spinner-lite active="[[loading_]]"> + </paper-spinner-lite> + + <webview id="signinFrame" name="signin-frame" class="signin-frame" + hidden$="[[loading_]]" allowscaling> + </webview> + </div> + </cr-view-manager> </div> <if expr="chromeos"> <div class="buttons" hidden$="[[loading_]]"> <cr-button class="back-button" aria-label="$i18n{accessibleBackButtonLabel}" - on-click="handleGoBack_"> + on-click="handleGoBack_" + hidden$="[[!shouldShowBackButton_(currentView_)]]"> <iron-icon icon="[[getBackButtonIcon_()]]"></iron-icon> $i18n{accessibleBackButtonLabel} </cr-button> - <div class="action-buttons" hidden$="[[!enableGaiaActionButtons_]]"> + <div class="action-buttons" + hidden$="[[!shouldShowGaiaButtons_(currentView_)]]"> <gaia-action-buttons authenticator="[[authExtHost_]]"> </gaia-action-buttons> </div> + + <cr-button class="next-button action-button" + aria-label="$i18n{ok}" + on-tap="onOkButtonClick_" + hidden$="[[!shouldShowOkButton_(currentView_)]]"> + $i18n{ok} + </cr-button> </div> </if>
diff --git a/chrome/browser/resources/inline_login/inline_login_app.js b/chrome/browser/resources/inline_login/inline_login_app.js index 29dae27..cc96f0c 100644 --- a/chrome/browser/resources/inline_login/inline_login_app.js +++ b/chrome/browser/resources/inline_login/inline_login_app.js
@@ -6,15 +6,21 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/icons.m.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.m.js'; -// <if expr="chromeos"> -import './gaia_action_buttons.js'; -// </if> +import {isChromeOS} from '//resources/js/cr.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {isRTL} from 'chrome://resources/js/util.m.js'; import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// <if expr="chromeos"> +import './gaia_action_buttons.js'; +import './welcome_page_app.js'; +import './strings.m.js'; +// </if> + import {AuthCompletedCredentials, Authenticator, AuthParams} from '../gaia_auth_host/authenticator.m.js'; import {InlineLoginBrowserProxy, InlineLoginBrowserProxyImpl} from './inline_login_browser_proxy.js'; @@ -23,6 +29,12 @@ * Chrome desktop (Windows only). */ +/** @enum {string} */ +const View = { + addAccount: 'addAccount', + welcome: 'welcome', +}; + Polymer({ is: 'inline-login-app', @@ -31,6 +43,12 @@ behaviors: [WebUIListenerBehavior], properties: { + /** Mirroring the enum so that it can be used from HTML bindings. */ + View: { + type: Object, + value: View, + }, + /** * Indicates whether the page is loading. * @private {boolean} @@ -48,6 +66,28 @@ type: Object, value: null, }, + + /** + * True if redesign of account management flows is enabled. + * @private + */ + isAccountManagementFlowsV2Enabled_: { + type: Boolean, + value() { + return isChromeOS && + loadTimeData.getBoolean('isAccountManagementFlowsV2Enabled'); + }, + readOnly: true, + }, + + /** + * Id of the screen that is currently displayed. + * @private {View} + */ + currentView_: { + type: String, + value: '', + }, }, /** @private {?InlineLoginBrowserProxy} */ @@ -69,6 +109,7 @@ /** @override */ ready() { + this.switchView_(this.getDefaultView_()); this.authExtHost_ = new Authenticator( /** @type {!WebView} */ (this.$.signinFrame)); this.addAuthExtHostListeners_(); @@ -125,6 +166,11 @@ onNewWindow_(e) { window.open(e.detail.targetUrl, '_blank'); e.detail.window.discard(); + if (this.isAccountManagementFlowsV2Enabled_) { + // On Chrome OS this dialog is always-on-top, so we have to close it if + // user opens a link in a new window. + this.closeDialog_(); + } }, /** @private */ @@ -219,6 +265,61 @@ return isRTL() ? 'cr:chevron-right' : 'cr:chevron-left'; }, + /** + * @return {boolean} + * @private + */ + shouldShowBackButton_() { + return this.currentView_ === View.addAccount; + }, + + /** + * @return {boolean} + * @private + */ + shouldShowOkButton_() { + return this.currentView_ === View.welcome; + }, + + /** + * @return {boolean} + * @private + */ + shouldShowGaiaButtons_() { + return this.enableGaiaActionButtons_ && + this.currentView_ === View.addAccount; + }, + + /** + * @return {View} + * @private + */ + getDefaultView_() { + return this.isWelcomePageEnabled_() ? View.welcome : View.addAccount; + }, + + /** + * @param {View} id identifier of the view that should be shown. + * @private + */ + switchView_(id) { + this.currentView_ = id; + /** @type {CrViewManagerElement} */ (this.$.viewManager).switchView(id); + }, + + /** + * @return {boolean} + * @private + */ + isWelcomePageEnabled_() { + return this.isAccountManagementFlowsV2Enabled_; + }, + + /** @private */ + onOkButtonClick_() { + this.switchView_(View.addAccount); + }, + /** @param {Object} authExtHost */ setAuthExtHostForTest(authExtHost) { this.authExtHost_ = /** @type {!Authenticator} */ (authExtHost);
diff --git a/chrome/browser/resources/inline_login/welcome_page_app.html b/chrome/browser/resources/inline_login/welcome_page_app.html new file mode 100644 index 0000000..0aa4f4e --- /dev/null +++ b/chrome/browser/resources/inline_login/welcome_page_app.html
@@ -0,0 +1,30 @@ +<style include="shared-css"> + .image-container { + margin-top: 40px; + } + .welcome-image { + width: 338px; + } + .google-full-logo { + width: 74px; + } + .secondary { + color: var(--cr-secondary-text-color); + } +</style> + +<div class="main-container"> + <if expr="_google_chrome"> + <img class="google-full-logo" + src="chrome://theme/IDR_LOGO_GOOGLE_COLOR_90" alt=""> + </if> + <h1>[[getWelcomeTitle_()]]</h1> + <p class="secondary" inner-h-t-m-l="[[getWelcomeBody_()]]"></p> + <if expr="_google_chrome"> + <div class="image-container"> + <img class="welcome-image" alt="" + srcset="account_manager_welcome_1x.png 1x, + account_manager_welcome_2x.png 2x"> + </div> + </if> +</div>
diff --git a/chrome/browser/resources/inline_login/welcome_page_app.js b/chrome/browser/resources/inline_login/welcome_page_app.js new file mode 100644 index 0000000..0b14987 --- /dev/null +++ b/chrome/browser/resources/inline_login/welcome_page_app.js
@@ -0,0 +1,42 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import './account_manager_shared_css.js'; + +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +Polymer({ + is: 'welcome-page-app', + + _template: html`{__html_template__}`, + + /** @override */ + ready() { + this.$$('#osSettingsLink') + .addEventListener( + 'click', + () => this.dispatchEvent(new CustomEvent('opened-new-window'))); + }, + + /** + * @return {string} + * @private + */ + getWelcomeBody_() { + return loadTimeData.getStringF( + 'accountManagerDialogWelcomeBody', loadTimeData.getString('userName'), + loadTimeData.getString('accountManagerOsSettingsUrl')); + }, + + /** + * @return {string} + * @private + */ + getWelcomeTitle_() { + return loadTimeData.getStringF( + 'accountManagerDialogWelcomeTitle', loadTimeData.getString('userName')); + }, +});
diff --git a/chrome/browser/resources/nearby_share/nearby_confirmation_page.html b/chrome/browser/resources/nearby_share/nearby_confirmation_page.html index 6309c97b..ca372ef 100644 --- a/chrome/browser/resources/nearby_share/nearby_confirmation_page.html +++ b/chrome/browser/resources/nearby_share/nearby_confirmation_page.html
@@ -1,6 +1,6 @@ <style> #addContacts { - margin-top: 32px; + padding: 8px; } #addContactsLabel { @@ -93,7 +93,7 @@ <nearby-preview send-preview="[[sendPreview]]" disabled="[[errorTitle_]]"> </nearby-preview> - <div id="confirmationToken"> + <div id="confirmationToken" aria-live="polite"> <template is="dom-if" if="[[confirmationToken_]]"> [[i18n('nearbyShareSecureConnectionId', confirmationToken_)]] </template> @@ -104,12 +104,13 @@ </div> </div> - <template is="dom-if" if="[[contactName_(shareTarget)]]"> - <cr-checkbox id="addContacts"> - <div id="addContactsLabel"> + <template is="dom-if" if="[[contactName_(shareTarget, errorTitle_)]]"> + <cr-checkbox id="addContacts" aria-labelledby="addContactsLabel" + aria-describedby="addContactsLabelSecondary"> + <div id="addContactsLabel" aria-hidden="true"> [[contactName_(shareTarget)]] </div> - <div id="addContactsLabelSecondary"> + <div id="addContactsLabelSecondary" aria-hidden="true"> [[i18n('nearbyShareConfirmationPageAddContactSubtitle')]] </div> </cr-checkbox> @@ -119,9 +120,12 @@ <template is="dom-if" if="[[errorTitle_]]"> <div id="errorSection"> <iron-icon id="errorIcon" icon="nearby20:info"></iron-icon> - <div id="error"> - <div id="errorTitle">[[errorTitle_]]</div> - <div id="errorDescription">[[errorDescription_]]</div> + <div id="error" role="alert" aria-labelledby="errorTitle" + aria-describedby="errorDescription"> + <div id="errorTitle" aria-hidden="true">[[errorTitle_]]</div> + <div id="errorDescription" aria-hidden="true"> + [[errorDescription_]] + </div> </div> </div> </template>
diff --git a/chrome/browser/resources/nearby_share/nearby_confirmation_page.js b/chrome/browser/resources/nearby_share/nearby_confirmation_page.js index 84a56dc..cdc1df5 100644 --- a/chrome/browser/resources/nearby_share/nearby_confirmation_page.js +++ b/chrome/browser/resources/nearby_share/nearby_confirmation_page.js
@@ -213,7 +213,7 @@ contactName_() { // TODO(crbug.com/1123943): Get contact name from ShareTarget. const contactName = null; - if (!contactName) { + if (!contactName || this.errorTitle_) { return ''; } return this.i18n('nearbyShareConfirmationPageAddContactTitle', contactName);
diff --git a/chrome/browser/resources/nearby_share/nearby_discovery_page.html b/chrome/browser/resources/nearby_share/nearby_discovery_page.html index ea38a7e3..fb3b52d 100644 --- a/chrome/browser/resources/nearby_share/nearby_discovery_page.html +++ b/chrome/browser/resources/nearby_share/nearby_discovery_page.html
@@ -160,9 +160,12 @@ <template is="dom-if" if="[[errorTitle_]]"> <div id="errorSection"> <iron-icon id="errorIcon" icon="nearby20:info"></iron-icon> - <div id="error"> - <div id="errorTitle">[[errorTitle_]]</div> - <div id="errorDescription">[[errorDescription_]]</div> + <div id="error" role="alert" aria-labelledby="errorTitle" + aria-describedby="errorDescription"> + <div id="errorTitle" aria-hidden="true">[[errorTitle_]]</div> + <div id="errorDescription" aria-hidden="true"> + [[errorDescription_]] + </div> </div> </div> </template>
diff --git a/chrome/browser/resources/nearby_share/nearby_progress.html b/chrome/browser/resources/nearby_share/nearby_progress.html index ea1ff0e..6119bd9f 100644 --- a/chrome/browser/resources/nearby_share/nearby_progress.html +++ b/chrome/browser/resources/nearby_share/nearby_progress.html
@@ -89,7 +89,9 @@ } </style> -<div id="progress-container" +<div id="progress-container" role="progressbar" aria-valuemin="0" + aria-valuemax="100" aria-valuenow$="[[progress]]" + tabindex$="[[getProgressBarTabIndex_(progress)]]" class$="[[getProgressWheelClass_(progress, hasError)]]"> <!-- This svg is inlined so that it can be styled with css; otherwise, it would be better to put it in an iron-icon. --> @@ -101,4 +103,6 @@ <nearby-device-icon id="icon" share-target="[[shareTarget]]"> </nearby-device-icon> </div> -<div id="device-name">[[shareTarget.name]]</div> +<div id="device-name" aria-label="$i18n{nearbyShareOnboardingPageDeviceName}"> + [[shareTarget.name]] +</div>
diff --git a/chrome/browser/resources/nearby_share/nearby_progress.js b/chrome/browser/resources/nearby_share/nearby_progress.js index 0053a38..43481a8 100644 --- a/chrome/browser/resources/nearby_share/nearby_progress.js +++ b/chrome/browser/resources/nearby_share/nearby_progress.js
@@ -78,4 +78,15 @@ this.updateStyles({'--progress-percentage': value}); } }, + + /** + * Allow focusing on the progress bar. Ignored by Chromevox otherwise. + * @return {number} The tabindex to be applied to the progress wheel. + */ + getProgressBarTabIndex_() { + if (this.progress && !this.hasError) { + return 0; + } + return -1; + }, });
diff --git a/chrome/browser/resources/print_preview/data/printer_status_cros.js b/chrome/browser/resources/print_preview/data/printer_status_cros.js index 09d00a0b..6c9c5bc4 100644 --- a/chrome/browser/resources/print_preview/data/printer_status_cros.js +++ b/chrome/browser/resources/print_preview/data/printer_status_cros.js
@@ -134,16 +134,22 @@ /** * @param {?PrinterStatusReason} printerStatusReason + * @param {boolean} isEnterprisePrinter * @return {string} */ -export function getPrinterStatusIcon(printerStatusReason) { +export function getPrinterStatusIcon(printerStatusReason, isEnterprisePrinter) { switch (computePrinterState(printerStatusReason)) { case PrinterState.GOOD: - return 'print-preview:printer-status-green'; + return isEnterprisePrinter ? + 'print-preview:business-printer-status-green' : + 'print-preview:printer-status-green'; case PrinterState.ERROR: - return 'print-preview:printer-status-red'; + return isEnterprisePrinter ? 'print-preview:business-printer-status-red' : + 'print-preview:printer-status-red'; case PrinterState.UNKNOWN: - return 'print-preview:printer-status-grey'; + return isEnterprisePrinter ? + 'print-preview:business-printer-status-grey' : + 'print-preview:printer-status-grey'; default: assertNotReached(); }
diff --git a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html index 64b1c1d5..c2e4298 100644 --- a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html +++ b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html
@@ -125,7 +125,7 @@ aria-description$="[[getPrinterStatusErrorString_( item.printerStatusReason)]]"> <iron-icon icon="[[getPrinterStatusIcon_( - item.printerStatusReason)]]"> + item.printerStatusReason, item.isEnterprisePrinter)]]"> </iron-icon> <span class="printer-display-name">[[item.displayName]]</span> </button>
diff --git a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js index bdd1551..7eeb19b 100644 --- a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js +++ b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js
@@ -327,10 +327,11 @@ /** * @param {!PrinterStatusReason} printerStatusReason + * @param {boolean} isEnterprisePrinter * @return {string} * @private */ - getPrinterStatusIcon_(printerStatusReason) { - return getPrinterStatusIcon(printerStatusReason); + getPrinterStatusIcon_(printerStatusReason, isEnterprisePrinter) { + return getPrinterStatusIcon(printerStatusReason, isEnterprisePrinter); } });
diff --git a/chrome/browser/resources/print_preview/ui/destination_list_item.js b/chrome/browser/resources/print_preview/ui/destination_list_item.js index 203fe7e3..5f3c5dbf 100644 --- a/chrome/browser/resources/print_preview/ui/destination_list_item.js +++ b/chrome/browser/resources/print_preview/ui/destination_list_item.js
@@ -246,7 +246,9 @@ // <if expr="chromeos"> if (this.printerStatusFlagEnabled_ && this.destination.origin === DestinationOrigin.CROS) { - return getPrinterStatusIcon(this.destination.printerStatusReason); + return getPrinterStatusIcon( + this.destination.printerStatusReason, + this.destination.isEnterprisePrinter); } // </if>
diff --git a/chrome/browser/resources/print_preview/ui/destination_select_cros.js b/chrome/browser/resources/print_preview/ui/destination_select_cros.js index 6751f5b..47161af 100644 --- a/chrome/browser/resources/print_preview/ui/destination_select_cros.js +++ b/chrome/browser/resources/print_preview/ui/destination_select_cros.js
@@ -146,7 +146,9 @@ if (this.destination && this.destination.key === this.selectedValue) { if (this.printerStatusFlagEnabled_ && this.isCurrentDestinationCrosLocal_) { - return getPrinterStatusIcon(this.destination.printerStatusReason); + return getPrinterStatusIcon( + this.destination.printerStatusReason, + this.destination.isEnterprisePrinter); } return this.destination.icon;
diff --git a/chrome/browser/resources/print_preview/ui/icons.html b/chrome/browser/resources/print_preview/ui/icons.html index 58c3fdb..0c6615bc 100644 --- a/chrome/browser/resources/print_preview/ui/icons.html +++ b/chrome/browser/resources/print_preview/ui/icons.html
@@ -34,6 +34,18 @@ <path d="M19,8 C20.66,8 22,9.34 22,11 L22,11 L22.0008411,12.1834702 C20.9260374,10.5660653 19.0875152,9.5 17,9.5 C14.2041481,9.5 11.8549346,11.412286 11.1889599,14.0002575 L8,14 L8,19 L12.1267078,19.0009178 C12.7530956,19.8713157 13.6069102,20.5670952 14.6011413,21.0012461 L6,21 L6,17 L2,17 L2,11 C2,9.34 3.34,8 5,8 L5,8 Z M18,3 L18,7 L6,7 L6,3 L18,3 Z"></path> <circle fill="#d93025" cx="17" cy="15.5" r="3.5"></circle> </g> + <g id="business-printer-status-green"> + <path d="M12,3 L12,7 L22,7 L22.0008411,12.1834702 C21.4889261,11.4131214 20.8037622,10.7678435 20.000963,10.3032504 L20,9 L12,9 L12,11 L13.0312427,11.0000183 C11.7856236,12.0994345 11,13.7079712 11,15.5 C11,16.7266262 11.3680857,17.8672813 11.9998276,18.8175358 L12,19 L12.1267078,19.0009178 C12.7530956,19.8713157 13.6069102,20.5670952 14.6011413,21.0012461 L2,21 L2,3 L12,3 Z M6,17 L4,17 L4,19 L6,19 L6,17 Z M10,17 L8,17 L8,19 L10,19 L10,17 Z M6,13 L4,13 L4,15 L6,15 L6,13 Z M10,13 L8,13 L8,15 L10,15 L10,13 Z M6,9 L4,9 L4,11 L6,11 L6,9 Z M10,9 L8,9 L8,11 L10,11 L10,9 Z M6,5 L4,5 L4,7 L6,7 L6,5 Z M10,5 L8,5 L8,7 L10,7 L10,5 Z"></path> + <circle fill="#188038" cx="17" cy="15.5" r="3.5"></circle> + </g> + <g id="business-printer-status-grey"> + <path d="M12,3 L12,7 L22,7 L22.0008411,12.1834702 C21.4889261,11.4131214 20.8037622,10.7678435 20.000963,10.3032504 L20,9 L12,9 L12,11 L13.0312427,11.0000183 C11.7856236,12.0994345 11,13.7079712 11,15.5 C11,16.7266262 11.3680857,17.8672813 11.9998276,18.8175358 L12,19 L12.1267078,19.0009178 C12.7530956,19.8713157 13.6069102,20.5670952 14.6011413,21.0012461 L2,21 L2,3 L12,3 Z M6,17 L4,17 L4,19 L6,19 L6,17 Z M10,17 L8,17 L8,19 L10,19 L10,17 Z M6,13 L4,13 L4,15 L6,15 L6,13 Z M10,13 L8,13 L8,15 L10,15 L10,13 Z M6,9 L4,9 L4,11 L6,11 L6,9 Z M10,9 L8,9 L8,11 L10,11 L10,9 Z M6,5 L4,5 L4,7 L6,7 L6,5 Z M10,5 L8,5 L8,7 L10,7 L10,5 Z"></path> + <circle fill="#9aa0a6" cx="17" cy="15.5" r="3.5"></circle> + </g> + <g id="business-printer-status-red"> + <path d="M12,3 L12,7 L22,7 L22.0008411,12.1834702 C21.4889261,11.4131214 20.8037622,10.7678435 20.000963,10.3032504 L20,9 L12,9 L12,11 L13.0312427,11.0000183 C11.7856236,12.0994345 11,13.7079712 11,15.5 C11,16.7266262 11.3680857,17.8672813 11.9998276,18.8175358 L12,19 L12.1267078,19.0009178 C12.7530956,19.8713157 13.6069102,20.5670952 14.6011413,21.0012461 L2,21 L2,3 L12,3 Z M6,17 L4,17 L4,19 L6,19 L6,17 Z M10,17 L8,17 L8,19 L10,19 L10,17 Z M6,13 L4,13 L4,15 L6,15 L6,13 Z M10,13 L8,13 L8,15 L10,15 L10,13 Z M6,9 L4,9 L4,11 L6,11 L6,9 Z M10,9 L8,9 L8,11 L10,11 L10,9 Z M6,5 L4,5 L4,7 L6,7 L6,5 Z M10,5 L8,5 L8,7 L10,7 L10,5 Z"></path> + <circle fill="#d93025" cx="17" cy="15.5" r="3.5"></circle> + </g> </if> <!--
diff --git a/chrome/browser/resources/print_preview/ui/plugin_proxy.js b/chrome/browser/resources/print_preview/ui/plugin_proxy.js index bc1e07d..b360a8f 100644 --- a/chrome/browser/resources/print_preview/ui/plugin_proxy.js +++ b/chrome/browser/resources/print_preview/ui/plugin_proxy.js
@@ -115,8 +115,6 @@ this.plugin_ = /** @type {PDFPlugin} */ ( PDFCreateOutOfProcessPlugin(srcUrl, 'chrome://print/pdf')); this.plugin_.classList.add('preview-area-plugin'); - this.plugin_.setAttribute('aria-live', 'polite'); - this.plugin_.setAttribute('aria-atomic', 'true'); // NOTE: The plugin's 'id' field must be set to 'pdf-viewer' since // chrome/renderer/printing/print_render_frame_helper.cc actually // references it.
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.js b/chrome/browser/resources/settings/autofill_page/password_check.js index c8c52b1..7bc580f 100644 --- a/chrome/browser/resources/settings/autofill_page/password_check.js +++ b/chrome/browser/resources/settings/autofill_page/password_check.js
@@ -434,7 +434,7 @@ * @private */ computeIconHaloClass_() { - return !this.isCheckInProgress_() && this.hasInsecureCredentials_() ? + return !this.isCheckInProgress_() && this.hasLeakedCredentials_() ? 'warning-halo' : ''; }, @@ -448,7 +448,7 @@ if (!this.hasInsecureCredentialsOrErrors_()) { return 'settings:check-circle'; } - if (this.hasInsecureCredentials_()) { + if (this.hasLeakedCredentials_()) { return 'cr:warning'; } return 'cr:info'; @@ -463,7 +463,7 @@ if (!this.hasInsecureCredentialsOrErrors_()) { return this.waitsForFirstCheck_() ? 'hidden' : 'no-security-issues'; } - if (this.hasInsecureCredentials_()) { + if (this.hasLeakedCredentials_()) { return 'has-security-issues'; } return '';
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc index 4f7fd86..3a03204 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc
@@ -224,7 +224,9 @@ if (settings.has_value()) { UploadBinary(reason, std::move(settings.value())); } else { - std::move(callback_).Run(result); + // Post a task to avoid reentrance issue. http://crbug.com//1152451. + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback_), result)); } UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckDownloadStats", reason,
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc index 50cf7f0..67b97e5 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -2414,9 +2414,13 @@ // notification. } + // Result won't be immediately available as it is being posted. + EXPECT_FALSE(has_result_); + base::RunLoop().RunUntilIdle(); + // When download is destroyed, no need to check for client download request // result. - EXPECT_TRUE(has_result_); + EXPECT_TRUE(IsResult(DownloadCheckResult::UNKNOWN)); EXPECT_FALSE(HasClientDownloadRequest()); } @@ -3430,6 +3434,10 @@ std::move(item), base::BindOnce(&DownloadProtectionServiceTest::SyncCheckDoneCallback, base::Unretained(this))); + // Result won't be immediately available, wait for the response to + // be posted. + EXPECT_FALSE(has_result_); + base::RunLoop().RunUntilIdle(); ASSERT_TRUE(IsResult(DownloadCheckResult::WHITELISTED_BY_POLICY)); }
diff --git a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc index 094969580..734ac6b 100644 --- a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc +++ b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -97,7 +97,7 @@ void UrlCheckerDelegateImpl::MaybeDestroyPrerenderContents( content::WebContents::OnceGetter web_contents_getter) { - // Destroy the prefetch with FINAL_STATUS_SAFEBROSWING. + // Destroy the prefetch with FINAL_STATUS_SAFE_BROWSING. content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&DestroyPrerenderContents, std::move(web_contents_getter)));
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.cc b/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.cc index 728221f..8a9acd0 100644 --- a/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.cc +++ b/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.cc
@@ -47,7 +47,7 @@ return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::DeleteResource( +google_apis::CancelCallbackOnce DriveServiceOnWorker::DeleteResource( const std::string& resource_id, const std::string& etag, google_apis::EntryActionCallback callback) { @@ -60,7 +60,7 @@ RelayCallbackToTaskRunner(worker_task_runner_.get(), FROM_HERE, std::move(callback)))); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } google_apis::CancelCallbackOnce DriveServiceOnWorker::DownloadFile( @@ -86,7 +86,7 @@ return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::GetAboutResource( +google_apis::CancelCallbackOnce DriveServiceOnWorker::GetAboutResource( google_apis::AboutResourceCallback callback) { DCHECK(sequence_checker_.CalledOnValidSequence()); @@ -97,10 +97,10 @@ RelayCallbackToTaskRunner(worker_task_runner_.get(), FROM_HERE, std::move(callback)))); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::GetStartPageToken( +google_apis::CancelCallbackOnce DriveServiceOnWorker::GetStartPageToken( const std::string& team_drive_id, google_apis::StartPageTokenCallback callback) { DCHECK(sequence_checker_.CalledOnValidSequence()); @@ -112,10 +112,10 @@ RelayCallbackToTaskRunner(worker_task_runner_.get(), FROM_HERE, std::move(callback)))); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::GetChangeList( +google_apis::CancelCallbackOnce DriveServiceOnWorker::GetChangeList( int64_t start_changestamp, google_apis::ChangeListCallback callback) { DCHECK(sequence_checker_.CalledOnValidSequence()); @@ -127,10 +127,10 @@ RelayCallbackToTaskRunner(worker_task_runner_.get(), FROM_HERE, std::move(callback)))); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::GetChangeListByToken( +google_apis::CancelCallbackOnce DriveServiceOnWorker::GetChangeListByToken( const std::string& team_drive_id, const std::string& start_page_token, google_apis::ChangeListCallback callback) { @@ -143,7 +143,7 @@ worker_task_runner_.get(), FROM_HERE, std::move(callback)))); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } google_apis::CancelCallbackOnce DriveServiceOnWorker::GetRemainingChangeList( @@ -167,7 +167,7 @@ return "root"; } -google_apis::CancelCallback DriveServiceOnWorker::GetRemainingTeamDriveList( +google_apis::CancelCallbackOnce DriveServiceOnWorker::GetRemainingTeamDriveList( const std::string& page_token, google_apis::TeamDriveListCallback callback) { DCHECK(sequence_checker_.CalledOnValidSequence()); @@ -179,7 +179,7 @@ RelayCallbackToTaskRunner(worker_task_runner_.get(), FROM_HERE, std::move(callback)))); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } google_apis::CancelCallbackOnce DriveServiceOnWorker::GetRemainingFileList( @@ -197,7 +197,7 @@ return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::GetFileResource( +google_apis::CancelCallbackOnce DriveServiceOnWorker::GetFileResource( const std::string& resource_id, google_apis::FileResourceCallback callback) { DCHECK(sequence_checker_.CalledOnValidSequence()); @@ -209,7 +209,7 @@ RelayCallbackToTaskRunner(worker_task_runner_.get(), FROM_HERE, std::move(callback)))); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } google_apis::CancelCallbackOnce DriveServiceOnWorker::GetFileListInDirectory( @@ -319,27 +319,27 @@ const std::string& search_query, google_apis::FileListCallback callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::TrashResource( +google_apis::CancelCallbackOnce DriveServiceOnWorker::TrashResource( const std::string& resource_id, google_apis::EntryActionCallback callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::CopyResource( +google_apis::CancelCallbackOnce DriveServiceOnWorker::CopyResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, const base::Time& last_modified, google_apis::FileResourceCallback callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::UpdateResource( +google_apis::CancelCallbackOnce DriveServiceOnWorker::UpdateResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -348,18 +348,18 @@ const google_apis::drive::Properties& properties, google_apis::FileResourceCallback callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::AddResourceToDirectory( +google_apis::CancelCallbackOnce DriveServiceOnWorker::AddResourceToDirectory( const std::string& parent_resource_id, const std::string& resource_id, google_apis::EntryActionCallback callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::InitiateUploadNewFile( +google_apis::CancelCallbackOnce DriveServiceOnWorker::InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -367,20 +367,21 @@ const drive::UploadNewFileOptions& options, google_apis::InitiateUploadCallback callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::InitiateUploadExistingFile( +google_apis::CancelCallbackOnce +DriveServiceOnWorker::InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, const drive::UploadExistingFileOptions& options, google_apis::InitiateUploadCallback callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::ResumeUpload( +google_apis::CancelCallbackOnce DriveServiceOnWorker::ResumeUpload( const GURL& upload_url, int64_t start_position, int64_t end_position, @@ -390,19 +391,18 @@ google_apis::drive::UploadRangeCallback callback, google_apis::ProgressCallback progress_callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::GetUploadStatus( +google_apis::CancelCallbackOnce DriveServiceOnWorker::GetUploadStatus( const GURL& upload_url, int64_t content_length, google_apis::drive::UploadRangeCallback callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallbackRepeating -DriveServiceOnWorker::MultipartUploadNewFile( +google_apis::CancelCallbackOnce DriveServiceOnWorker::MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -412,10 +412,11 @@ google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) { NOTREACHED(); - return google_apis::CancelCallbackRepeating(); + return google_apis::CancelCallbackOnce(); } -google_apis::CancelCallback DriveServiceOnWorker::MultipartUploadExistingFile( +google_apis::CancelCallbackOnce +DriveServiceOnWorker::MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -424,7 +425,7 @@ google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } std::unique_ptr<drive::BatchRequestConfiguratorInterface> @@ -433,13 +434,13 @@ return std::unique_ptr<drive::BatchRequestConfiguratorInterface>(); } -google_apis::CancelCallback DriveServiceOnWorker::AddPermission( +google_apis::CancelCallbackOnce DriveServiceOnWorker::AddPermission( const std::string& resource_id, const std::string& email, google_apis::drive::PermissionRole role, google_apis::EntryActionCallback callback) { NOTREACHED(); - return google_apis::CancelCallback(); + return google_apis::CancelCallbackOnce(); } } // namespace drive_backend
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.h b/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.h index d1b9d18f6..62ca59d 100644 --- a/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.h +++ b/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.h
@@ -44,7 +44,7 @@ const drive::AddNewDirectoryOptions& options, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback DeleteResource( + google_apis::CancelCallbackOnce DeleteResource( const std::string& resource_id, const std::string& etag, google_apis::EntryActionCallback callback) override; @@ -56,18 +56,18 @@ const google_apis::GetContentCallback& get_content_callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback GetAboutResource( + google_apis::CancelCallbackOnce GetAboutResource( google_apis::AboutResourceCallback callback) override; - google_apis::CancelCallback GetStartPageToken( + google_apis::CancelCallbackOnce GetStartPageToken( const std::string& team_drive_id, google_apis::StartPageTokenCallback callback) override; - google_apis::CancelCallback GetChangeList( + google_apis::CancelCallbackOnce GetChangeList( int64_t start_changestamp, google_apis::ChangeListCallback callback) override; - google_apis::CancelCallback GetChangeListByToken( + google_apis::CancelCallbackOnce GetChangeListByToken( const std::string& team_drive_id, const std::string& start_page_token, google_apis::ChangeListCallback callback) override; @@ -78,7 +78,7 @@ std::string GetRootResourceId() const override; - google_apis::CancelCallback GetRemainingTeamDriveList( + google_apis::CancelCallbackOnce GetRemainingTeamDriveList( const std::string& page_token, google_apis::TeamDriveListCallback callback) override; @@ -86,7 +86,7 @@ const GURL& next_link, google_apis::FileListCallback callback) override; - google_apis::CancelCallback GetFileResource( + google_apis::CancelCallbackOnce GetFileResource( const std::string& resource_id, google_apis::FileResourceCallback callback) override; @@ -123,16 +123,16 @@ google_apis::CancelCallbackOnce Search( const std::string& search_query, google_apis::FileListCallback callback) override; - google_apis::CancelCallback TrashResource( + google_apis::CancelCallbackOnce TrashResource( const std::string& resource_id, google_apis::EntryActionCallback callback) override; - google_apis::CancelCallback CopyResource( + google_apis::CancelCallbackOnce CopyResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, const base::Time& last_modified, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback UpdateResource( + google_apis::CancelCallbackOnce UpdateResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -140,24 +140,24 @@ const base::Time& last_viewed_by_me, const google_apis::drive::Properties& properties, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback AddResourceToDirectory( + google_apis::CancelCallbackOnce AddResourceToDirectory( const std::string& parent_resource_id, const std::string& resource_id, google_apis::EntryActionCallback callback) override; - google_apis::CancelCallback InitiateUploadNewFile( + google_apis::CancelCallbackOnce InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, const std::string& title, const drive::UploadNewFileOptions& options, google_apis::InitiateUploadCallback callback) override; - google_apis::CancelCallback InitiateUploadExistingFile( + google_apis::CancelCallbackOnce InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, const drive::UploadExistingFileOptions& options, google_apis::InitiateUploadCallback callback) override; - google_apis::CancelCallback ResumeUpload( + google_apis::CancelCallbackOnce ResumeUpload( const GURL& upload_url, int64_t start_position, int64_t end_position, @@ -166,11 +166,11 @@ const base::FilePath& local_file_path, google_apis::drive::UploadRangeCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback GetUploadStatus( + google_apis::CancelCallbackOnce GetUploadStatus( const GURL& upload_url, int64_t content_length, google_apis::drive::UploadRangeCallback callback) override; - google_apis::CancelCallbackRepeating MultipartUploadNewFile( + google_apis::CancelCallbackOnce MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -179,7 +179,7 @@ const drive::UploadNewFileOptions& options, google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallbackRepeating MultipartUploadExistingFile( + google_apis::CancelCallbackOnce MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -189,7 +189,7 @@ google_apis::ProgressCallback progress_callback) override; std::unique_ptr<drive::BatchRequestConfiguratorInterface> StartBatchRequest() override; - google_apis::CancelCallback AddPermission( + google_apis::CancelCallbackOnce AddPermission( const std::string& resource_id, const std::string& email, google_apis::drive::PermissionRole role,
diff --git a/chrome/browser/sync_file_system/drive_backend/fake_drive_uploader.cc b/chrome/browser/sync_file_system/drive_backend/fake_drive_uploader.cc index e1ed068..4e37b8c 100644 --- a/chrome/browser/sync_file_system/drive_backend/fake_drive_uploader.cc +++ b/chrome/browser/sync_file_system/drive_backend/fake_drive_uploader.cc
@@ -16,7 +16,6 @@ using drive::FakeDriveService; using drive::UploadCompletionCallback; -using google_apis::CancelCallback; using google_apis::CancelCallbackOnce; using google_apis::DriveApiErrorCode; using google_apis::FileResource;
diff --git a/chrome/browser/ui/ash/clipboard_history_browsertest.cc b/chrome/browser/ui/ash/clipboard_history_browsertest.cc index 6c676c2c..9e8583d 100644 --- a/chrome/browser/ui/ash/clipboard_history_browsertest.cc +++ b/chrome/browser/ui/ash/clipboard_history_browsertest.cc
@@ -866,26 +866,9 @@ GetContextMenu()->GetMenuItemViewAtForTest(/*index=*/0); GetEventGenerator()->MoveMouseTo( inaccessible_menu_item_view->GetBoundsInScreen().CenterPoint()); - - // Verify that `inaccessible_menu_item_view` cannot be selected by mouse - // hovering. It does not respond to mouse click either. - EXPECT_FALSE(inaccessible_menu_item_view->IsSelected()); GetEventGenerator()->ClickLeftButton(); + + // Verify that the text is not pasted and menu is closed after click. EXPECT_EQ("", base::UTF16ToUTF8(textfield_->GetText())); - - // Move the selection through the arrow key. Then delete the item by the - // backspace key. After deletion, `inaccessible_menu_item_view` is left. - PressAndRelease(ui::KeyboardCode::VKEY_DOWN, ui::EF_NONE); - PressAndRelease(ui::KeyboardCode::VKEY_BACK, ui::EF_NONE); - EXPECT_TRUE(VerifyClipboardTextData({"B"})); - EXPECT_EQ(1, GetContextMenu()->GetMenuItemsCount()); - - // Move the selection through the arrow key again. Verify that - // `inaccessible_menu_item_view` cannot be selected. Pressing the backspace - // key does not delete the item. - PressAndRelease(ui::KeyboardCode::VKEY_DOWN, ui::EF_NONE); - PressAndRelease(ui::KeyboardCode::VKEY_BACK, ui::EF_NONE); - EXPECT_FALSE(inaccessible_menu_item_view->IsSelected()); - EXPECT_TRUE(VerifyClipboardTextData({"B"})); - EXPECT_EQ(1, GetContextMenu()->GetMenuItemsCount()); + EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing()); }
diff --git a/chrome/browser/ui/cocoa/notifications/unnotification_builder_mac_unittest.mm b/chrome/browser/ui/cocoa/notifications/unnotification_builder_mac_unittest.mm index 021c0bb8..26430bf1 100644 --- a/chrome/browser/ui/cocoa/notifications/unnotification_builder_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/notifications/unnotification_builder_mac_unittest.mm
@@ -10,6 +10,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_path_override.h" #include "base/test/task_environment.h" +#include "build/build_config.h" #include "chrome/browser/notifications/notification_handler.h" #include "chrome/browser/notifications/notification_image_retainer.h" #include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h" @@ -511,7 +512,14 @@ } } -TEST(UNNotificationBuilderMacTest, TestIconWrongPath) { +#if defined(ARCH_CPU_ARM64) +// Bulk-disabled for arm64 bot stabilization: https://crbug.com/1154345 +#define MAYBE_TestIconWrongPath DISABLED_TestIconWrongPath +#else +#define MAYBE_TestIconWrongPath TestIconWrongPath +#endif + +TEST(UNNotificationBuilderMacTest, MAYBE_TestIconWrongPath) { if (@available(macOS 10.14, *)) { base::scoped_nsobject<UNNotificationBuilder> builder = NewTestBuilder(NotificationHandler::Type::WEB_PERSISTENT);
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc index b8d8c0f..2f1b067 100644 --- a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc +++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
@@ -11,7 +11,6 @@ #include "base/bind.h" #include "base/metrics/histogram_functions.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/global_media_controls/media_notification_service.h" #include "chrome/browser/ui/global_media_controls/overlay_media_notification.h" @@ -23,6 +22,7 @@ #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/sync_preferences/pref_service_syncable.h" +#include "components/vector_icons/vector_icons.h" #include "media/base/media_switches.h" #include "services/media_session/public/mojom/media_session.mojom.h" #include "ui/base/l10n/l10n_util.h" @@ -254,9 +254,9 @@ } auto live_caption_image = std::make_unique<views::ImageView>(); - live_caption_image->SetImage( - gfx::CreateVectorIcon(kLiveCaptionIcon, kLiveCaptionImageWidthDip, - SkColor(gfx::kGoogleGrey700))); + live_caption_image->SetImage(gfx::CreateVectorIcon( + vector_icons::kLiveCaptionOnIcon, kLiveCaptionImageWidthDip, + SkColor(gfx::kGoogleGrey700))); live_caption_container->AddChildView(std::move(live_caption_image)); auto live_caption_title = std::make_unique<views::Label>( @@ -281,9 +281,9 @@ live_caption_title_->SetVisible(false); } - auto live_caption_button = - std::make_unique<views::ToggleButton>(base::BindRepeating( - &MediaDialogView::LiveCaptionButtonPressed, base::Unretained(this))); + auto live_caption_button = std::make_unique<views::ToggleButton>( + base::BindRepeating(&MediaDialogView::OnLiveCaptionButtonPressed, + base::Unretained(this))); live_caption_button->SetIsOn( profile_->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled)); live_caption_button->SetAccessibleName(live_caption_title_->GetText()); @@ -305,7 +305,7 @@ } } -void MediaDialogView::LiveCaptionButtonPressed(const ui::Event& event) { +void MediaDialogView::OnLiveCaptionButtonPressed() { bool enabled = !profile_->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled); ToggleLiveCaption(enabled); base::UmaHistogramBoolean(
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view.h b/chrome/browser/ui/views/global_media_controls/media_dialog_view.h index 14eccb3..5e49e175 100644 --- a/chrome/browser/ui/views/global_media_controls/media_dialog_view.h +++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view.h
@@ -92,7 +92,7 @@ void WindowClosing() override; // views::Button::PressedCallback - void LiveCaptionButtonPressed(const ui::Event& event); + void OnLiveCaptionButtonPressed(); void ToggleLiveCaption(bool enabled); void UpdateBubbleSize();
diff --git a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc index a7732fa..0541b2e 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc
@@ -99,10 +99,27 @@ } ax::mojom::Role LocationBarBubbleDelegateView::GetAccessibleWindowRole() { - if (display_reason_ == USER_GESTURE) + if (display_reason_ == USER_GESTURE) { + // crbug.com/1132318: The bubble appears as a direct result of a user + // action and will get focused. If we used an alert-like role, it would + // produce an event that would cause double-speaking the bubble. return ax::mojom::Role::kDialog; + } + // crbug.com/1079320, crbug.com/1119367, crbug.com/1119734: The bubble + // appears spontaneously over the course of the user's interaction with + // Chrome and doesn't get focused. We need an alert-like role so the + // corresponding event is triggered and ATs announce the bubble. +#if defined(OS_WIN) + // crbug.com/1125118: Windows ATs only announce these bubbles if the alert + // role is used, despite it not being the most appropriate choice. + // TODO(accessibility): review the role mappings for alerts and dialogs, + // making sure they are translated to the best candidate in each flatform + // without resorting to hacks like this. + return ax::mojom::Role::kAlert; +#else return ax::mojom::Role::kAlertDialog; +#endif } void LocationBarBubbleDelegateView::OnFullscreenStateChanged() {
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc index 39cb0c2..82f17c1b 100644 --- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc +++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc
@@ -39,6 +39,8 @@ #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/layout/layout_provider.h" +#include "ui/views/style/platform_style.h" #include "ui/views/widget/widget.h" PermissionPromptBubbleView::PermissionPromptBubbleView( @@ -60,41 +62,65 @@ SetDefaultButton(ui::DIALOG_BUTTON_NONE); if (ShouldShowAllowThisTimeButton()) { + // Host every button in the extra_view to have full control over the width + // of the dialog. + SetButtons(ui::DIALOG_BUTTON_NONE); + + views::LayoutProvider* const layout_provider = views::LayoutProvider::Get(); + const int button_spacing = layout_provider->GetDistanceMetric( + views::DISTANCE_RELATED_BUTTON_HORIZONTAL); + auto buttons_container = std::make_unique<views::View>(); + buttons_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + button_spacing)); + + auto allow_once_button = std::make_unique<views::MdTextButton>( + base::BindRepeating( + &PermissionPromptBubbleView::AcceptPermissionThisTime, + base::Unretained(this)), + l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW_ONCE)); + + auto allow_always_button = std::make_unique<views::MdTextButton>( + base::BindRepeating(&PermissionPromptBubbleView::AcceptPermission, + base::Unretained(this)), + l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW_ALWAYS)); + + auto block_button = std::make_unique<views::MdTextButton>( + base::BindRepeating(&PermissionPromptBubbleView::DenyPermission, + base::Unretained(this)), + l10n_util::GetStringUTF16(IDS_PERMISSION_DENY)); + if (permissions::feature_params::kOkButtonBehavesAsAllowAlways.Get()) { - SetButtonLabel(ui::DIALOG_BUTTON_OK, - l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW_ALWAYS)); - SetAcceptCallback( - base::BindOnce(&PermissionPromptBubbleView::AcceptPermission, - base::Unretained(this))); - - SetExtraView(std::make_unique<views::MdTextButton>( - base::BindRepeating( - &PermissionPromptBubbleView::AcceptPermissionThisTime, - base::Unretained(this)), - l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW_ONCE))); + buttons_container->AddChildView(std::move(allow_once_button)); + if (views::PlatformStyle::kIsOkButtonLeading) { + buttons_container->AddChildView(std::move(allow_always_button)); + buttons_container->AddChildView(std::move(block_button)); + } else { + buttons_container->AddChildView(std::move(block_button)); + buttons_container->AddChildView(std::move(allow_always_button)); + } } else { - SetButtonLabel(ui::DIALOG_BUTTON_OK, - l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW_ONCE)); - SetAcceptCallback( - base::BindOnce(&PermissionPromptBubbleView::AcceptPermissionThisTime, - base::Unretained(this))); - - SetExtraView(std::make_unique<views::MdTextButton>( - base::BindRepeating(&PermissionPromptBubbleView::AcceptPermission, - base::Unretained(this)), - l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW_ALWAYS))); + buttons_container->AddChildView(std::move(allow_always_button)); + if (views::PlatformStyle::kIsOkButtonLeading) { + buttons_container->AddChildView(std::move(allow_once_button)); + buttons_container->AddChildView(std::move(block_button)); + } else { + buttons_container->AddChildView(std::move(block_button)); + buttons_container->AddChildView(std::move(allow_once_button)); + } } + SetExtraView(std::move(buttons_container)); } else { SetButtonLabel(ui::DIALOG_BUTTON_OK, l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW)); SetAcceptCallback(base::BindOnce( &PermissionPromptBubbleView::AcceptPermission, base::Unretained(this))); - } - SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, - l10n_util::GetStringUTF16(IDS_PERMISSION_DENY)); - SetCancelCallback(base::BindOnce(&PermissionPromptBubbleView::DenyPermission, - base::Unretained(this))); + SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, + l10n_util::GetStringUTF16(IDS_PERMISSION_DENY)); + SetCancelCallback(base::BindOnce( + &PermissionPromptBubbleView::DenyPermission, base::Unretained(this))); + } SetPromptStyle(prompt_style);
diff --git a/chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom b/chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom index a6498d1..f0ac5fe 100644 --- a/chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom +++ b/chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom
@@ -19,7 +19,9 @@ }; // TODO(crbug.com/1110098): Remove kUnknown. -// Represents who the user has chosen to be visible to. +// Represents who the user has chosen to be visible to. Note: These values are +// persisted to logs. Entries should not be renumbered and numeric values +// should never be reused. enum Visibility { kUnknown = 0, // The user is not advertising to anyone.
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc index 157ccab..18a237e 100644 --- a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -286,17 +286,17 @@ } namespace { -base::ListValue UsbDevicesToListValue( - const std::vector<CrosUsbDeviceInfo> shared_usbs) { +base::ListValue GetSharableUsbDevices(CrosUsbDetector* detector) { base::ListValue usb_devices_list; - for (auto& device : shared_usbs) { + for (const auto& device : detector->GetDevicesSharableWithCrostini()) { base::Value device_info(base::Value::Type::DICTIONARY); device_info.SetStringKey("guid", device.guid); device_info.SetStringKey("label", device.label); bool shared = device.shared_vm_name == crostini::kCrostiniDefaultVmName; device_info.SetBoolKey("shared", shared); - device_info.SetBoolKey("shareWillReassign", - device.shared_vm_name && !shared); + device_info.SetBoolKey( + "shareWillReassign", + !shared && detector->SharingRequiresReassignPrompt(device)); usb_devices_list.Append(std::move(device_info)); } return usb_devices_list; @@ -357,9 +357,8 @@ void CrostiniHandler::OnUsbDevicesChanged() { chromeos::CrosUsbDetector* detector = chromeos::CrosUsbDetector::Get(); DCHECK(detector); // This callback is called by the detector. - FireWebUIListener( - "crostini-shared-usb-devices-changed", - UsbDevicesToListValue(detector->GetDevicesSharableWithCrostini())); + FireWebUIListener("crostini-shared-usb-devices-changed", + GetSharableUsbDevices(detector)); } void CrostiniHandler::HandleExportCrostiniContainer(
diff --git a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc index c0517aa..b53e6c3 100644 --- a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
@@ -20,17 +20,17 @@ namespace { -base::ListValue UsbDevicesToListValue( - const std::vector<CrosUsbDeviceInfo>& shared_usbs) { +base::ListValue GetSharableUsbDevices(CrosUsbDetector* detector) { base::ListValue usb_devices_list; - for (const auto& device : shared_usbs) { + for (const auto& device : detector->GetDevicesSharableWithCrostini()) { base::Value device_info(base::Value::Type::DICTIONARY); device_info.SetStringKey("guid", device.guid); device_info.SetStringKey("label", device.label); bool shared = device.shared_vm_name == plugin_vm::kPluginVmName; device_info.SetBoolKey("shared", shared); - device_info.SetBoolKey("shareWillReassign", - device.shared_vm_name && !shared); + device_info.SetBoolKey( + "shareWillReassign", + !shared && detector->SharingRequiresReassignPrompt(device)); usb_devices_list.Append(std::move(device_info)); } return usb_devices_list; @@ -151,12 +151,9 @@ void PluginVmHandler::OnUsbDevicesChanged() { chromeos::CrosUsbDetector* detector = chromeos::CrosUsbDetector::Get(); - if (!detector) - return; - - FireWebUIListener( - "plugin-vm-shared-usb-devices-changed", - UsbDevicesToListValue(detector->GetDevicesSharableWithCrostini())); + DCHECK(detector); // This callback is called by the detector. + FireWebUIListener("plugin-vm-shared-usb-devices-changed", + GetSharableUsbDevices(detector)); } void PluginVmHandler::HandleIsRelaunchNeededForNewPermissions(
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc index 1d50fec..3263ef9f 100644 --- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc +++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
@@ -583,7 +583,7 @@ identity_manager_->GetPrimaryAccountMutator(); DCHECK(primary_account_mutator); primary_account_mutator->ClearPrimaryAccount( - signin::PrimaryAccountMutator::ClearAccountsAction::kKeepAll, + signin::PrimaryAccountMutator::ClearAccountsAction::kDefault, signin_metrics::ABORT_SIGNIN, signin_metrics::SignoutDelete::IGNORE_METRIC); AbortAndDelete();
diff --git a/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.cc index d6d60f1..6f0b711 100644 --- a/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.cc +++ b/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/supervised_user/supervised_user_service_factory.h" #include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h" #include "chrome/common/webui_url_constants.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_pref_names.h" #include "components/prefs/pref_service.h" #include "components/session_manager/core/session_manager.h" @@ -194,6 +195,12 @@ std::min(kSigninDialogHeight, display.work_area().height())); } +ui::ModalType InlineLoginDialogChromeOS::GetDialogModalType() const { + return chromeos::features::IsAccountManagementFlowsV2Enabled() + ? ui::MODAL_TYPE_SYSTEM + : ui::MODAL_TYPE_NONE; +} + std::string InlineLoginDialogChromeOS::GetDialogArgs() const { if (url_.GetWithEmptyPath() != GURL(chrome::kChromeUIAccountManagerErrorURL)) {
diff --git a/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.h b/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.h index 638ab47..94270cd 100644 --- a/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.h +++ b/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.h
@@ -103,6 +103,7 @@ // ui::WebDialogDelegate overrides void GetDialogSize(gfx::Size* size) const override; + ui::ModalType GetDialogModalType() const override; std::string GetDialogArgs() const override; bool ShouldShowDialogTitle() const override; void OnDialogShown(content::WebUI* webui) override;
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui.cc b/chrome/browser/ui/webui/signin/inline_login_ui.cc index 64b912f..dfdc0528 100644 --- a/chrome/browser/ui/webui/signin/inline_login_ui.cc +++ b/chrome/browser/ui/webui/signin/inline_login_ui.cc
@@ -31,14 +31,18 @@ #include "content/public/browser/web_ui_data_source.h" #include "content/public/common/content_switches.h" #include "services/network/public/mojom/content_security_policy.mojom.h" +#include "ui/base/webui/web_ui_util.h" #include "ui/resources/grit/webui_resources.h" #if BUILDFLAG(IS_CHROMEOS_ASH) #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/supervised_user/supervised_user_features.h" +#include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.h" #include "chrome/browser/ui/webui/chromeos/edu_coexistence_login_handler_chromeos.h" +#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/base/l10n/l10n_util.h" #include "ui/strings/grit/ui_strings.h" #else @@ -105,7 +109,7 @@ } #endif // BUILDFLAG(IS_CHROMEOS_ASH) -content::WebUIDataSource* CreateWebUIDataSource() { +content::WebUIDataSource* CreateWebUIDataSource(Profile* profile) { content::WebUIDataSource* source = content::WebUIDataSource::Create(chrome::kChromeUIChromeSigninHost); webui::SetupWebUIDataSource( @@ -126,6 +130,8 @@ {"inline_login_app.js", IDR_INLINE_LOGIN_APP_JS}, {"inline_login_browser_proxy.js", IDR_INLINE_LOGIN_BROWSER_PROXY_JS}, #if BUILDFLAG(IS_CHROMEOS_ASH) + {"welcome_page_app.js", IDR_INLINE_LOGIN_WELCOME_PAGE_APP_JS}, + {"account_manager_shared_css.js", IDR_ACCOUNT_MANAGER_SHARED_CSS_JS}, {"gaia_action_buttons.js", IDR_GAIA_ACTION_BUTTONS_JS}, {"error_screen.js", IDR_ACCOUNT_MANAGER_COMPONENTS_ERROR_SCREEN_JS}, {"edu", IDR_EDU_LOGIN_EDU_LOGIN_HTML}, @@ -163,30 +169,51 @@ {"edu_coexistence_css.js", IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_CSS_JS}, #if BUILDFLAG(GOOGLE_CHROME_BRANDING) + {"account_manager_welcome_1x.png", IDR_ACCOUNT_MANAGER_WELCOME_1X_PNG}, + {"account_manager_welcome_2x.png", IDR_ACCOUNT_MANAGER_WELCOME_2X_PNG}, {"googleg.svg", IDR_ACCOUNT_MANAGER_WELCOME_GOOGLE_LOGO_SVG}, #endif {"family_link_logo.svg", IDR_FAMILY_LINK_LOGO_SVG}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) }; - webui::AddResourcePathsBulk(source, kResources); - source->AddLocalizedString("title", IDS_CHROME_SIGNIN_TITLE); - source->AddLocalizedString( - "accessibleCloseButtonLabel", IDS_SIGNIN_ACCESSIBLE_CLOSE_BUTTON); - source->AddLocalizedString( - "accessibleBackButtonLabel", IDS_SIGNIN_ACCESSIBLE_BACK_BUTTON); -#if BUILDFLAG(IS_CHROMEOS_ASH) - source->AddLocalizedString("accountManagerErrorNoInternetTitle", - IDS_ACCOUNT_MANAGER_ERROR_NO_INTERNET_TITLE); - source->AddLocalizedString("accountManagerErrorNoInternetBody", - IDS_ACCOUNT_MANAGER_ERROR_NO_INTERNET_BODY); - source->AddLocalizedString( - "accountManagerErrorCannotAddAccountTitle", - IDS_ACCOUNT_MANAGER_ERROR_CANNOT_ADD_ACCOUNT_TITLE); - source->AddLocalizedString("accountManagerErrorCannotAddAccountBody", - IDS_ACCOUNT_MANAGER_ERROR_CANNOT_ADD_ACCOUNT_BODY); + static constexpr webui::LocalizedString kLocalizedStrings[] = { + {"title", IDS_CHROME_SIGNIN_TITLE}, + {"accessibleCloseButtonLabel", IDS_SIGNIN_ACCESSIBLE_CLOSE_BUTTON}, + {"accessibleBackButtonLabel", IDS_SIGNIN_ACCESSIBLE_BACK_BUTTON}, +#if defined(OS_CHROMEOS) + {"ok", IDS_APP_OK}, + {"accountManagerDialogWelcomeTitle", + IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_TITLE}, + {"accountManagerDialogWelcomeBody", + IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_BODY}, + {"accountManagerErrorNoInternetTitle", + IDS_ACCOUNT_MANAGER_ERROR_NO_INTERNET_TITLE}, + {"accountManagerErrorNoInternetBody", + IDS_ACCOUNT_MANAGER_ERROR_NO_INTERNET_BODY}, + {"accountManagerErrorCannotAddAccountTitle", + IDS_ACCOUNT_MANAGER_ERROR_CANNOT_ADD_ACCOUNT_TITLE}, + {"accountManagerErrorCannotAddAccountBody", + IDS_ACCOUNT_MANAGER_ERROR_CANNOT_ADD_ACCOUNT_BODY}, #endif + }; + AddLocalizedStringsBulk(source, kLocalizedStrings); + +#if defined(OS_CHROMEOS) + source->AddBoolean("isAccountManagementFlowsV2Enabled", + chromeos::features::IsAccountManagementFlowsV2Enabled()); + + user_manager::User* user = + chromeos::ProfileHelper::Get()->GetUserByProfile(profile); + DCHECK(user); + source->AddString("userName", user->GetGivenName()); + source->AddString("accountManagerOsSettingsUrl", + chrome::GetOSSettingsUrl( + chromeos::settings::mojom::kMyAccountsSubpagePath) + .spec()); +#endif + return source; } @@ -231,7 +258,7 @@ return; Profile* profile = Profile::FromWebUI(web_ui); - content::WebUIDataSource* source = CreateWebUIDataSource(); + content::WebUIDataSource* source = CreateWebUIDataSource(profile); #if BUILDFLAG(IS_CHROMEOS_ASH) base::string16 username = chromeos::ProfileHelper::Get()->GetUserByProfile(profile)->GetGivenName();
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 5222e7d..cdf9198 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1607039886-9857a5090b09116b4b309953eec41db8862dfe90.profdata +chrome-linux-master-1607082643-9d7584569e97498303bfc8f363e6d14838d94e40.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index e2b48f38..aa65cb2 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1607039886-1ddd5c45cae9e9c7a03307d574bbe9f5985fa593.profdata +chrome-mac-master-1607082643-ec3aa91ed6cc9a4e56961da34010bfe7d1bfcfad.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 57c29529..bf88bb32 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1606996231-fb1aa25fe6cd29fd31733f8199da138cbb1f5caf.profdata +chrome-win32-master-1607061555-42057a46d6898e28766e44cc3eff7a0d211d34f4.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index d056c96..7242510c2 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1607018334-2342e7b4fc523afed7119425e6663fe86ee0646f.profdata +chrome-win64-master-1607061555-9d7880873554417bd44ed300f865acac635c5256.profdata
diff --git a/chrome/common/chrome_content_client_unittest.cc b/chrome/common/chrome_content_client_unittest.cc index b95f4612..43c9ba0d 100644 --- a/chrome/common/chrome_content_client_unittest.cc +++ b/chrome/common/chrome_content_client_unittest.cc
@@ -16,6 +16,7 @@ #include "content/public/test/test_utils.h" #include "extensions/common/constants.h" #include "ppapi/buildflags/buildflags.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/loader/network_utils.h" #include "url/gurl.h" @@ -110,7 +111,7 @@ EXPECT_TRUE(blink::network_utils::IsOriginSecure(chrome_url)); EXPECT_FALSE(content::OriginCanAccessServiceWorkers(chrome_url)); EXPECT_TRUE( - content::IsPotentiallyTrustworthyOrigin(url::Origin::Create(chrome_url))); + network::IsOriginPotentiallyTrustworthy(url::Origin::Create(chrome_url))); } class OriginTrialInitializationTestThread
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc index 959979b..2baba49 100644 --- a/chrome/common/chrome_paths.cc +++ b/chrome/common/chrome_paths.cc
@@ -565,6 +565,7 @@ if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur)) return false; cur = cur.Append(FILE_PATH_LITERAL("OptimizationGuidePredictionModels")); + create_dir = true; break; default:
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 491d91d..6fec07ee 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -990,13 +990,13 @@ "../browser/browsing_data/navigation_entry_remover_browsertest.cc", "../browser/chrome_back_forward_cache_browsertest.cc", "../browser/chrome_content_browser_client_browsertest.cc", - "../browser/chrome_cross_origin_opener_policy_browsertest.cc", "../browser/chrome_do_not_track_browsertest.cc", "../browser/chrome_find_request_manager_browsertest.cc", "../browser/chrome_navigation_browsertest.cc", "../browser/chrome_origin_trials_browsertest.cc", "../browser/chrome_security_exploit_browsertest.cc", "../browser/chrome_service_worker_browsertest.cc", + "../browser/chrome_web_platform_security_metrics_browsertest.cc", "../browser/chrome_worker_browsertest.cc", "../browser/client_hints/client_hints_browsertest.cc", "../browser/component_updater/component_patcher_operation_browsertest.cc", @@ -3672,6 +3672,7 @@ "../browser/previews/previews_service_render_view_unittest.cc", "../browser/previews/previews_service_unittest.cc", "../browser/previews/previews_ui_tab_helper_unittest.cc", + "../browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc", "../browser/profiles/gaia_info_update_service_unittest.cc", "../browser/profiles/guest_mode_policy_handler_unittest.cc", "../browser/profiles/incognito_mode_policy_handler_unittest.cc",
diff --git a/chrome/test/data/extensions/api_test/enterprise_platform_keys/background.js b/chrome/test/data/extensions/api_test/enterprise_platform_keys/background.js index be4e015..31c4dda 100644 --- a/chrome/test/data/extensions/api_test/enterprise_platform_keys/background.js +++ b/chrome/test/data/extensions/api_test/enterprise_platform_keys/background.js
@@ -4,12 +4,17 @@ 'use strict'; -// The message sent from a browsertest to the background script in case the -// system token is enabled. -const SYSTEM_TOKEN_ENABLED_MESSAGE = 'System token enabled.'; -// The message sent from a browsertest to the background script in case the -// system token is disabled. -const SYSTEM_TOKEN_DISABLED_MESSAGE = 'System token disabled.'; +// TODO(crbug.com/1148294): Add LOGIN_SCREEN_MODE. +// This message sent from a browsertest to the background script to test the API +// behavior for an extension running in a user session with system token +// enabled. +const USER_SESSION_WITH_SYSTEM_TOKEN_ENABLED_MODE = + 'User session with system token enabled mode.'; +// This message sent from a browsertest to the background script to test the API +// behavior for an extension running in a user session with system token +// disabled. +const USER_SESSION_WITH_SYSTEM_TOKEN_DISABLED_MODE = + 'User session with system token disabled mode.'; var assertEq = chrome.test.assertEq; var assertTrue = chrome.test.assertTrue; @@ -881,20 +886,17 @@ chrome.test.runTests(testsIndependentOfKeys.concat(testsNotParameterized)); } -// |waitForSystemTokenStateMessage()| waits for the browser test to send a -// message with the state of the system token to run tests accordingly. The -// browser test logic can be found at: +// This function is executed when the C++ side of the test sends the test mode. +// The browser test logic can be found at: // c/b/e/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc -function waitForSystemTokenStateMessage(systemTokenStateMessage) { - if (systemTokenStateMessage == SYSTEM_TOKEN_ENABLED_MESSAGE) { +function testModeListener(message) { + if (message.data === USER_SESSION_WITH_SYSTEM_TOKEN_ENABLED_MODE) { beforeTests(/*systemTokenEnabled=*/ true, runTests); - } else if (systemTokenStateMessage == SYSTEM_TOKEN_DISABLED_MESSAGE) { + } else if (message.data === USER_SESSION_WITH_SYSTEM_TOKEN_DISABLED_MODE) { beforeTests(/*systemTokenEnabled=*/ false, runTests); } else { - // No background script tests should run. - succeed(); + fail(); } } -chrome.test.sendMessage( - 'Waiting for system token state message', waitForSystemTokenStateMessage); +chrome.test.onMessage.addListener(testModeListener);
diff --git a/chrome/test/data/media/media_history.html b/chrome/test/data/media/media_history.html index 223618ea..4a6f79c 100644 --- a/chrome/test/data/media/media_history.html +++ b/chrome/test/data/media/media_history.html
@@ -80,5 +80,15 @@ const video = document.querySelector('video'); video.currentTime = video.duration; } + +function enterPictureInPicture() { + const video = document.querySelector('video'); + video.requestPictureInPicture().then(() => { + window.domAutomationController.send(true); + }).catch(() => { + window.domAutomationController.send(false); + }); +} + </script> </html>
diff --git a/chrome/test/data/optimization_guide/unsignedmodel.crx3 b/chrome/test/data/optimization_guide/unsignedmodel.crx3 new file mode 100644 index 0000000..6c09929 --- /dev/null +++ b/chrome/test/data/optimization_guide/unsignedmodel.crx3 Binary files differ
diff --git a/chrome/test/data/webui/nearby_share/nearby_confirmation_page_test.js b/chrome/test/data/webui/nearby_share/nearby_confirmation_page_test.js index 6f22fe2..6798243 100644 --- a/chrome/test/data/webui/nearby_share/nearby_confirmation_page_test.js +++ b/chrome/test/data/webui/nearby_share/nearby_confirmation_page_test.js
@@ -95,7 +95,7 @@ }; const renderedName = confirmationPageElement.$$('nearby-progress') .$$('#device-name') - .textContent; + .innerText; assertEquals(name, renderedName); });
diff --git a/chrome/test/data/webui/nearby_share/nearby_progress_test.js b/chrome/test/data/webui/nearby_share/nearby_progress_test.js index afef1f9..4d18741 100644 --- a/chrome/test/data/webui/nearby_share/nearby_progress_test.js +++ b/chrome/test/data/webui/nearby_share/nearby_progress_test.js
@@ -38,7 +38,7 @@ }); progressElement.shareTarget = shareTarget; - const renderedName = progressElement.$$('#device-name').textContent; + const renderedName = progressElement.$$('#device-name').innerText; assertEquals(name, renderedName); }); });
diff --git a/chrome/test/data/webui/print_preview/destination_select_test_cros.js b/chrome/test/data/webui/print_preview/destination_select_test_cros.js index 4f4c41b..7e80273 100644 --- a/chrome/test/data/webui/print_preview/destination_select_test_cros.js +++ b/chrome/test/data/webui/print_preview/destination_select_test_cros.js
@@ -359,7 +359,8 @@ destinationSelect.destination = crosEnterprisePrinter; destinationSelect.updateDestination(); assertEquals( - 'print-preview:printer-status-grey', dropdown.destinationIcon); + 'print-preview:business-printer-status-grey', + dropdown.destinationIcon); destinationSelect.destination = mobilePrinter; destinationSelect.updateDestination();
diff --git a/chrome/test/data/webui/settings/password_check_test.js b/chrome/test/data/webui/settings/password_check_test.js index a530a8b..1fd5acb9 100644 --- a/chrome/test/data/webui/settings/password_check_test.js +++ b/chrome/test/data/webui/settings/password_check_test.js
@@ -653,6 +653,27 @@ expectFalse(icon.classList.contains('no-security-issues')); }); + // Tests that the spinner is replaced with an info icon if only weak passwords + // were found. + test('showsInfoIconWhenFinishedWithWeakPasswords', async function() { + loadTimeData.overrideValues({passwordsWeaknessCheck: true}); + const data = passwordManager.data; + assertEquals(PasswordCheckState.IDLE, data.checkStatus.state); + data.weakCredentials = [ + makeInsecureCredential('one.com', 'test5'), + ]; + + const checkPasswordSection = createCheckPasswordSection(); + await passwordManager.whenCalled('getPasswordCheckStatus'); + flush(); + const icon = checkPasswordSection.$$('iron-icon'); + const spinner = checkPasswordSection.$$('paper-spinner-lite'); + expectFalse(isElementVisible(spinner)); + assertTrue(isElementVisible(icon)); + expectFalse(icon.classList.contains('has-security-issues')); + expectFalse(icon.classList.contains('no-security-issues')); + }); + // Tests that the spinner is replaced with a warning on errors. test('showsInfoIconWhenFinishedWithErrors', async function() { passwordManager.data.checkStatus = makePasswordCheckStatus(
diff --git a/chromecast/media/cma/backend/android/volume_control_android.cc b/chromecast/media/cma/backend/android/volume_control_android.cc index ae3175c..d22658e 100644 --- a/chromecast/media/cma/backend/android/volume_control_android.cc +++ b/chromecast/media/cma/backend/android/volume_control_android.cc
@@ -133,7 +133,8 @@ thread_.task_runner()->PostTask( FROM_HERE, base::BindOnce(&VolumeControlAndroid::ReportVolumeChangeOnThread, - base::Unretained(this), (AudioContentType)type, level)); + base::Unretained(this), + static_cast<AudioContentType>(type), level)); } void VolumeControlAndroid::OnMuteChange( @@ -142,9 +143,9 @@ jint type, jboolean muted) { thread_.task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&VolumeControlAndroid::ReportMuteChangeOnThread, - base::Unretained(this), (AudioContentType)type, muted)); + FROM_HERE, base::BindOnce(&VolumeControlAndroid::ReportMuteChangeOnThread, + base::Unretained(this), + static_cast<AudioContentType>(type), muted)); } #if BUILDFLAG(ENABLE_VOLUME_TABLES_ACCESS) @@ -335,7 +336,7 @@ // static void VolumeControl::Initialize(const std::vector<std::string>& argv) { - // Nothing to do. + GetVolumeControl(); } // static
diff --git a/chromeos/components/sensors/mojom/sensor.mojom b/chromeos/components/sensors/mojom/sensor.mojom index ee18e46..121deb0 100644 --- a/chromeos/components/sensors/mojom/sensor.mojom +++ b/chromeos/components/sensors/mojom/sensor.mojom
@@ -44,8 +44,8 @@ COUNT = 4, MAGN = 5, ANGL = 6, - ACPI_ALS = 7, - BARO = 8, + BARO = 7, + MAX = 8, }; enum ObserverErrorType {
diff --git a/chromeos/disks/mock_disk_mount_manager.cc b/chromeos/disks/mock_disk_mount_manager.cc index 38094f8..c3e7392 100644 --- a/chromeos/disks/mock_disk_mount_manager.cc +++ b/chromeos/disks/mock_disk_mount_manager.cc
@@ -147,6 +147,11 @@ } void MockDiskMountManager::CreateDiskEntryForMountDevice( + std::unique_ptr<Disk> disk) { + disks_[disk->device_path()] = std::move(disk); +} + +void MockDiskMountManager::CreateDiskEntryForMountDevice( const DiskMountManager::MountPointInfo& mount_info, const std::string& device_id, const std::string& device_label, @@ -176,7 +181,7 @@ .SetOnRemovableDevice(on_removable_device) .SetFileSystemType(file_system_type) .Build(); - disks_[std::string(mount_info.source_path)] = std::move(disk_ptr); + CreateDiskEntryForMountDevice(std::move(disk_ptr)); } void MockDiskMountManager::RemoveDiskEntryForMountDevice(
diff --git a/chromeos/disks/mock_disk_mount_manager.h b/chromeos/disks/mock_disk_mount_manager.h index bb27744..25778a6 100644 --- a/chromeos/disks/mock_disk_mount_manager.h +++ b/chromeos/disks/mock_disk_mount_manager.h
@@ -74,8 +74,10 @@ // Sets up default results for mock methods. void SetupDefaultReplies(); - // Creates a fake disk entry for the mounted device. This function is - // primarily for StorageMonitorTest. + // Creates a fake disk entry for the mounted device. + void CreateDiskEntryForMountDevice(std::unique_ptr<Disk> disk); + + // Creates a fake disk entry for the mounted device. void CreateDiskEntryForMountDevice( const DiskMountManager::MountPointInfo& mount_info, const std::string& device_id,
diff --git a/chromeos/network/network_connection_handler_impl.cc b/chromeos/network/network_connection_handler_impl.cc index e7648d0..c6171cf 100644 --- a/chromeos/network/network_connection_handler_impl.cc +++ b/chromeos/network/network_connection_handler_impl.cc
@@ -14,6 +14,7 @@ #include "base/time/time.h" #include "chromeos/dbus/shill/shill_manager_client.h" #include "chromeos/dbus/shill/shill_service_client.h" +#include "chromeos/login/login_state/login_state.h" #include "chromeos/network/client_cert_resolver.h" #include "chromeos/network/client_cert_util.h" #include "chromeos/network/device_state.h" @@ -36,6 +37,12 @@ namespace { +// If connection to a network that may require a client certificate is requested +// when client certificates are not loaded yet, wait this long until +// certificates have been loaded. +constexpr base::TimeDelta kMaxCertLoadTimeSeconds = + base::TimeDelta::FromSeconds(15); + bool IsAuthenticationError(const std::string& error) { return (error == shill::kErrorBadWEPKey || error == shill::kErrorPppAuthFailed || @@ -169,7 +176,6 @@ : network_cert_loader_(nullptr), network_state_handler_(nullptr), configuration_handler_(nullptr), - logged_in_(false), certificates_loaded_(false) {} NetworkConnectionHandlerImpl::~NetworkConnectionHandlerImpl() { @@ -177,17 +183,12 @@ network_state_handler_->RemoveObserver(this, FROM_HERE); if (network_cert_loader_) network_cert_loader_->RemoveObserver(this); - if (LoginState::IsInitialized()) - LoginState::Get()->RemoveObserver(this); } void NetworkConnectionHandlerImpl::Init( NetworkStateHandler* network_state_handler, NetworkConfigurationHandler* network_configuration_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler) { - if (LoginState::IsInitialized()) - LoginState::Get()->AddObserver(this); - if (NetworkCertLoader::IsInitialized()) { network_cert_loader_ = NetworkCertLoader::Get(); network_cert_loader_->AddObserver(this); @@ -210,18 +211,6 @@ // After this point, the NetworkConnectionHandlerImpl is fully initialized // (all handler references set, observers registered, ...). - - if (LoginState::IsInitialized()) - LoggedInStateChanged(); -} - -void NetworkConnectionHandlerImpl::LoggedInStateChanged() { - LoginState* login_state = LoginState::Get(); - if (logged_in_ || !login_state->IsUserLoggedIn()) - return; - - logged_in_ = true; - logged_in_time_ = base::TimeTicks::Now(); } void NetworkConnectionHandlerImpl::OnCertificatesLoaded() { @@ -561,13 +550,6 @@ NET_LOG(DEBUG) << "Client cert type for: " << NetworkPathId(service_path) << ": " << client_cert_type; - // User must be logged in to connect to a network requiring a certificate. - if (!logged_in_ || !network_cert_loader_) { - NET_LOG(ERROR) << "User not logged in for: " - << NetworkPathId(service_path); - ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired); - return; - } // If certificates have not been loaded yet, queue the connect request. if (!certificates_loaded_) { NET_LOG(EVENT) << "Certificates not loaded for: " @@ -650,16 +632,6 @@ return; } - const int kMaxCertLoadTimeSeconds = 15; - base::TimeDelta dtime = base::TimeTicks::Now() - logged_in_time_; - if (dtime > base::TimeDelta::FromSeconds(kMaxCertLoadTimeSeconds)) { - NET_LOG(ERROR) << "Certificate load timeout: " - << NetworkPathId(service_path); - InvokeConnectErrorCallback(service_path, std::move(request->error_callback), - kErrorCertLoadTimeout); - return; - } - NET_LOG(EVENT) << "Connect Request Queued: " << NetworkPathId(service_path); queued_connect_.reset(new ConnectRequest(request->mode, service_path, request->profile_path, @@ -674,7 +646,7 @@ FROM_HERE, base::BindOnce(&NetworkConnectionHandlerImpl::CheckCertificatesLoaded, AsWeakPtr()), - base::TimeDelta::FromSeconds(kMaxCertLoadTimeSeconds) - dtime); + kMaxCertLoadTimeSeconds); } // Called after a delay to check whether certificates loaded. If they did not
diff --git a/chromeos/network/network_connection_handler_impl.h b/chromeos/network/network_connection_handler_impl.h index 5d04cbf3..4a5eeaa 100644 --- a/chromeos/network/network_connection_handler_impl.h +++ b/chromeos/network/network_connection_handler_impl.h
@@ -7,7 +7,6 @@ #include "base/component_export.h" #include "chromeos/dbus/dbus_method_call_status.h" -#include "chromeos/login/login_state/login_state.h" #include "chromeos/network/network_cert_loader.h" #include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_state_handler_observer.h" @@ -17,7 +16,6 @@ // Implementation of NetworkConnectionHandler. class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkConnectionHandlerImpl : public NetworkConnectionHandler, - public LoginState::Observer, public NetworkCertLoader::Observer, public NetworkStateHandlerObserver, public base::SupportsWeakPtr<NetworkConnectionHandlerImpl> { @@ -40,9 +38,6 @@ void NetworkListChanged() override; void NetworkPropertiesUpdated(const NetworkState* network) override; - // LoginState::Observer - void LoggedInStateChanged() override; - // NetworkCertLoader::Observer void OnCertificatesLoaded() override; @@ -148,9 +143,7 @@ std::unique_ptr<ConnectRequest> queued_connect_; // Track certificate loading state. - bool logged_in_; bool certificates_loaded_; - base::TimeTicks logged_in_time_; DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerImpl); };
diff --git a/chromeos/network/network_connection_handler_impl_unittest.cc b/chromeos/network/network_connection_handler_impl_unittest.cc index 797e8cf..9f11e841 100644 --- a/chromeos/network/network_connection_handler_impl_unittest.cc +++ b/chromeos/network/network_connection_handler_impl_unittest.cc
@@ -501,9 +501,8 @@ EXPECT_EQ(kSuccessResult, GetResultAndReset()); } -// Disabled, see http://crbug.com/396729. TEST_F(NetworkConnectionHandlerImplTest, - DISABLED_ConnectWithCertificateRequestedBeforeCertsAreLoaded) { + ConnectWithCertificateRequestedBeforeCertsAreLoaded) { scoped_refptr<net::X509Certificate> cert = ImportTestClientCert(); ASSERT_TRUE(cert.get());
diff --git a/components/autofill/core/browser/autofill_handler.cc b/components/autofill/core/browser/autofill_handler.cc index 183277e..c715d0d12 100644 --- a/components/autofill/core/browser/autofill_handler.cc +++ b/components/autofill/core/browser/autofill_handler.cc
@@ -432,7 +432,52 @@ void AutofillHandler::OnLoadedServerPredictions( std::string response, - const std::vector<FormSignature>& queried_form_signatures) {} + const std::vector<FormSignature>& queried_form_signatures) { + // Get the current valid FormStructures represented by + // |queried_form_signatures|. + std::vector<FormStructure*> queried_forms; + queried_forms.reserve(queried_form_signatures.size()); + for (const auto& form_signature : queried_form_signatures) { + FindCachedFormsBySignature(form_signature, &queried_forms); + } + + // Each form signature in |queried_form_signatures| is supposed to be unique, + // and therefore appear only once. This ensures that + // FindCachedFormsBySignature() produces an output without duplicates in the + // forms. + // TODO(crbug/1064709): |queried_forms| could be a set data structure; their + // order should be irrelevant. + DCHECK_EQ(queried_forms.size(), + std::set<FormStructure*>(queried_forms.begin(), queried_forms.end()) + .size()); + + // If there are no current forms corresponding to the queried signatures, drop + // the query response. + if (queried_forms.empty()) + return; + + // Parse and store the server predictions. + FormStructure::ParseApiQueryResponse(std::move(response), queried_forms, + queried_form_signatures, + form_interactions_ukm_logger()); + + // Will log quality metrics for each FormStructure based on the presence of + // autocomplete attributes, if available. + for (FormStructure* cur_form : queried_forms) { + cur_form->LogQualityMetricsBasedOnAutocomplete( + form_interactions_ukm_logger()); + } + + // Send field type predictions to the renderer so that it can possibly + // annotate forms with the predicted types or add console warnings. + driver()->SendAutofillTypePredictionsToRenderer(queried_forms); + + LogAutofillTypePredictionsAvailable(log_manager_, queried_forms); + + // Forward form structures to the password generation manager to detect + // account creation forms. + driver()->PropagateAutofillPredictions(queried_forms); +} void AutofillHandler::OnServerRequestError( FormSignature form_signature,
diff --git a/components/autofill/core/browser/autofill_handler.h b/components/autofill/core/browser/autofill_handler.h index be55b48..1abb9fa 100644 --- a/components/autofill/core/browser/autofill_handler.h +++ b/components/autofill/core/browser/autofill_handler.h
@@ -176,6 +176,14 @@ FormStructure* ParseFormForTest(const FormData& form) { return ParseForm(form, nullptr); } + + // A public wrapper that calls |OnLoadedServerPredictions| for testing + // purposes only. + void OnLoadedServerPredictionsForTest( + std::string response, + const std::vector<FormSignature>& queried_form_signatures) { + OnLoadedServerPredictions(response, queried_form_signatures); + } #endif // UNIT_TEST protected:
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 248fb1e..3446e002 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -1388,55 +1388,6 @@ TriggerRefill(form); } -void AutofillManager::OnLoadedServerPredictions( - std::string response, - const std::vector<FormSignature>& queried_form_signatures) { - // Get the current valid FormStructures represented by - // |queried_form_signatures|. - std::vector<FormStructure*> queried_forms; - queried_forms.reserve(queried_form_signatures.size()); - for (const auto& form_signature : queried_form_signatures) { - FindCachedFormsBySignature(form_signature, &queried_forms); - } - - // Each form signature in |queried_form_signatures| is supposed to be unique, - // and therefore appear only once. This ensures that - // FindCachedFormsBySignature() produces an output without duplicates in the - // forms. - // TODO(crbug/1064709): |queried_forms| could be a set data structure; their - // order should be irrelevant. - DCHECK_EQ(queried_forms.size(), - std::set<FormStructure*>(queried_forms.begin(), queried_forms.end()) - .size()); - - // If there are no current forms corresponding to the queried signatures, drop - // the query response. - if (queried_forms.empty()) - return; - - // Parse and store the server predictions. - FormStructure::ParseApiQueryResponse(std::move(response), queried_forms, - queried_form_signatures, - form_interactions_ukm_logger()); - - // Will log quality metrics for each FormStructure based on the presence of - // autocomplete attributes, if available. - for (FormStructure* cur_form : queried_forms) { - cur_form->LogQualityMetricsBasedOnAutocomplete( - form_interactions_ukm_logger()); - } - - // Send field type predictions to the renderer so that it can possibly - // annotate forms with the predicted types or add console warnings. - driver()->SendAutofillTypePredictionsToRenderer(queried_forms); - - LogAutofillTypePredictionsAvailable(log_manager_, queried_forms); - - // Forward form structures to the password generation manager to detect - // account creation forms. - driver()->PropagateAutofillPredictions(queried_forms); -} - void AutofillManager::OnCreditCardFetched(bool did_succeed, const CreditCard* credit_card, const base::string16& cvc) {
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 8d4f461..a0ca353 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -47,7 +47,6 @@ namespace autofill { class AutofillDataModel; -class AutofillDownloadManager; class AutofillExternalDelegate; class AutofillField; class AutofillClient; @@ -270,14 +269,6 @@ app_locale, submitted_form); } - // A public wrapper that calls |OnLoadedServerPredictions| for testing - // purposes only. - void OnLoadedServerPredictionsForTest( - std::string response, - const std::vector<FormSignature>& queried_form_signatures) { - OnLoadedServerPredictions(response, queried_form_signatures); - } - // A public wrapper that calls |MakeFrontendID| for testing purposes only. int MakeFrontendIDForTest(const std::string& cc_backend_id, const std::string& profile_backend_id) const { @@ -424,11 +415,6 @@ SuppressReason suppress_reason = SuppressReason::kNotSuppressed; }; - // AutofillDownloadManager::Observer: - void OnLoadedServerPredictions( - std::string response, - const std::vector<FormSignature>& queried_form_signatures) override; - // CreditCardAccessManager::Accessor void OnCreditCardFetched( bool did_succeed,
diff --git a/components/autofill/core/browser/payments/credit_card_cvc_authenticator.cc b/components/autofill/core/browser/payments/credit_card_cvc_authenticator.cc index c5ce8b4..1f3916f 100644 --- a/components/autofill/core/browser/payments/credit_card_cvc_authenticator.cc +++ b/components/autofill/core/browser/payments/credit_card_cvc_authenticator.cc
@@ -4,6 +4,8 @@ #include "components/autofill/core/browser/payments/credit_card_cvc_authenticator.h" +#include <memory> + #include "base/strings/string16.h" #include "build/build_config.h" #include "components/autofill/core/browser/autofill_client.h" @@ -28,11 +30,13 @@ PersonalDataManager* personal_data_manager, const base::TimeTicks& form_parsed_timestamp) { requester_ = requester; - if (!card) - return OnFullCardRequestFailed(); - full_card_request_.reset(new payments::FullCardRequest( + if (!card) { + return OnFullCardRequestFailed( + payments::FullCardRequest::FailureType::GENERIC_FAILURE); + } + full_card_request_ = std::make_unique<payments::FullCardRequest>( client_, client_->GetPaymentsClient(), personal_data_manager, - form_parsed_timestamp)); + form_parsed_timestamp); full_card_request_->GetFullCard(*card, AutofillClient::UNMASK_FOR_AUTOFILL, weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr()); @@ -54,7 +58,8 @@ .with_card_authorization_token(response.card_authorization_token)); } -void CreditCardCVCAuthenticator::OnFullCardRequestFailed() { +void CreditCardCVCAuthenticator::OnFullCardRequestFailed( + payments::FullCardRequest::FailureType failure_type) { requester_->OnCVCAuthenticationComplete( CVCAuthenticationResponse().with_did_succeed(false)); }
diff --git a/components/autofill/core/browser/payments/credit_card_cvc_authenticator.h b/components/autofill/core/browser/payments/credit_card_cvc_authenticator.h index fee486e..20fe78c 100644 --- a/components/autofill/core/browser/payments/credit_card_cvc_authenticator.h +++ b/components/autofill/core/browser/payments/credit_card_cvc_authenticator.h
@@ -95,7 +95,8 @@ const payments::FullCardRequest& full_card_request, const CreditCard& card, const base::string16& cvc) override; - void OnFullCardRequestFailed() override; + void OnFullCardRequestFailed( + payments::FullCardRequest::FailureType failure_type) override; // payments::FullCardRequest::UIDelegate void ShowUnmaskPrompt(const CreditCard& card,
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc index d7b17fdd..62cea32b 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
@@ -520,7 +520,8 @@ requester_->OnFIDOAuthenticationComplete(/*did_succeed=*/true, &card, cvc); } -void CreditCardFIDOAuthenticator::OnFullCardRequestFailed() { +void CreditCardFIDOAuthenticator::OnFullCardRequestFailed( + payments::FullCardRequest::FailureType failure_type) { DCHECK_EQ(AUTHENTICATION_FLOW, current_flow_); current_flow_ = NONE_FLOW; requester_->OnFIDOAuthenticationComplete(/*did_succeed=*/false);
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.h b/components/autofill/core/browser/payments/credit_card_fido_authenticator.h index 93b1135..c857d84 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.h +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.h
@@ -194,7 +194,8 @@ const payments::FullCardRequest& full_card_request, const CreditCard& card, const base::string16& cvc) override; - void OnFullCardRequestFailed() override; + void OnFullCardRequestFailed( + payments::FullCardRequest::FailureType failure_type) override; // Converts |request_options| from JSON to mojom pointer. PublicKeyCredentialRequestOptionsPtr ParseRequestOptions(
diff --git a/components/autofill/core/browser/payments/full_card_request.cc b/components/autofill/core/browser/payments/full_card_request.cc index a09cde2f..16acda8 100644 --- a/components/autofill/core/browser/payments/full_card_request.cc +++ b/components/autofill/core/browser/payments/full_card_request.cc
@@ -82,7 +82,7 @@ // |result_delegate_| is already set, then immediately reject the new request // through the method parameter |result_delegate_|. if (result_delegate_) { - result_delegate_->OnFullCardRequestFailed(); + result_delegate_->OnFullCardRequestFailed(FailureType::GENERIC_FAILURE); return; } @@ -160,7 +160,7 @@ void FullCardRequest::OnUnmaskPromptClosed() { if (result_delegate_) - result_delegate_->OnFullCardRequestFailed(); + result_delegate_->OnFullCardRequestFailed(FailureType::PROMPT_CLOSED); Reset(); } @@ -216,10 +216,15 @@ // Neither PERMANENT_FAILURE nor NETWORK_ERROR allow retry. case AutofillClient::PERMANENT_FAILURE: - // Intentional fall through. + if (result_delegate_) { + result_delegate_->OnFullCardRequestFailed( + FailureType::VERIFICATION_DECLINED); + } + Reset(); + break; case AutofillClient::NETWORK_ERROR: { if (result_delegate_) - result_delegate_->OnFullCardRequestFailed(); + result_delegate_->OnFullCardRequestFailed(FailureType::GENERIC_FAILURE); Reset(); break; }
diff --git a/components/autofill/core/browser/payments/full_card_request.h b/components/autofill/core/browser/payments/full_card_request.h index 20c9408..b09fbb8 100644 --- a/components/autofill/core/browser/payments/full_card_request.h +++ b/components/autofill/core/browser/payments/full_card_request.h
@@ -32,6 +32,24 @@ // TODO(crbug/1061638): Refactor to use base::WaitableEvent where possible. class FullCardRequest final : public CardUnmaskDelegate { public: + // The type of failure. + enum FailureType { + // The user closed the prompt. The following scenarios are possible: + // 1) The user declined to enter their CVC and closed the prompt. + // 2) The user provided their CVC, got auth declined and then closed the + // prompt without attempting a second time. + // 3) The user provided their CVC and closed the prompt before waiting for + // the result. + PROMPT_CLOSED, + + // The card could not be looked up due to card auth declined or failed. + VERIFICATION_DECLINED, + + // The request failed for technical reasons, such as a closing page or lack + // of network connection. + GENERIC_FAILURE + }; + // The interface for receiving the full card details. class ResultDelegate { public: @@ -40,7 +58,7 @@ const payments::FullCardRequest& full_card_request, const CreditCard& card, const base::string16& cvc) = 0; - virtual void OnFullCardRequestFailed() = 0; + virtual void OnFullCardRequestFailed(FailureType failure_type) = 0; }; // The delegate responsible for displaying the unmask prompt UI.
diff --git a/components/autofill/core/browser/payments/full_card_request_unittest.cc b/components/autofill/core/browser/payments/full_card_request_unittest.cc index 909a356..8602bf04 100644 --- a/components/autofill/core/browser/payments/full_card_request_unittest.cc +++ b/components/autofill/core/browser/payments/full_card_request_unittest.cc
@@ -42,7 +42,8 @@ void(const payments::FullCardRequest&, const CreditCard&, const base::string16&)); - MOCK_METHOD0(OnFullCardRequestFailed, void()); + MOCK_METHOD1(OnFullCardRequestFailed, + void(payments::FullCardRequest::FailureType)); }; // The delegate responsible for displaying the unmask prompt UI. @@ -402,7 +403,9 @@ // Only one request at a time should be allowed. TEST_F(FullCardRequestTest, OneRequestAtATime) { - EXPECT_CALL(*result_delegate(), OnFullCardRequestFailed()); + EXPECT_CALL( + *result_delegate(), + OnFullCardRequestFailed(FullCardRequest::FailureType::GENERIC_FAILURE)); EXPECT_CALL(*ui_delegate(), ShowUnmaskPrompt(_, _, _)); EXPECT_CALL(*ui_delegate(), OnUnmaskVerificationResult(_)).Times(0); @@ -418,7 +421,7 @@ // After the first request completes, it's OK to start the second request. TEST_F(FullCardRequestTest, SecondRequestOkAfterFirstFinished) { - EXPECT_CALL(*result_delegate(), OnFullCardRequestFailed()).Times(0); + EXPECT_CALL(*result_delegate(), OnFullCardRequestFailed(_)).Times(0); EXPECT_CALL( *result_delegate(), OnFullCardRequestSucceeded(testing::Ref(*request()), @@ -450,7 +453,9 @@ // If the user cancels the CVC prompt, // FullCardRequest::Delegate::OnFullCardRequestFailed() should be invoked. TEST_F(FullCardRequestTest, ClosePromptWithoutUserInput) { - EXPECT_CALL(*result_delegate(), OnFullCardRequestFailed()); + EXPECT_CALL( + *result_delegate(), + OnFullCardRequestFailed(FullCardRequest::FailureType::PROMPT_CLOSED)); EXPECT_CALL(*ui_delegate(), ShowUnmaskPrompt(_, _, _)); EXPECT_CALL(*ui_delegate(), OnUnmaskVerificationResult(_)).Times(0); @@ -464,7 +469,9 @@ // If the server provides an empty PAN with PERMANENT_FAILURE error, // FullCardRequest::Delegate::OnFullCardRequestFailed() should be invoked. TEST_F(FullCardRequestTest, PermanentFailure) { - EXPECT_CALL(*result_delegate(), OnFullCardRequestFailed()); + EXPECT_CALL(*result_delegate(), + OnFullCardRequestFailed( + FullCardRequest::FailureType::VERIFICATION_DECLINED)); EXPECT_CALL(*ui_delegate(), ShowUnmaskPrompt(_, _, _)); EXPECT_CALL(*ui_delegate(), OnUnmaskVerificationResult(AutofillClient::PERMANENT_FAILURE)); @@ -483,7 +490,9 @@ // If the server provides an empty PAN with NETWORK_ERROR error, // FullCardRequest::Delegate::OnFullCardRequestFailed() should be invoked. TEST_F(FullCardRequestTest, NetworkError) { - EXPECT_CALL(*result_delegate(), OnFullCardRequestFailed()); + EXPECT_CALL( + *result_delegate(), + OnFullCardRequestFailed(FullCardRequest::FailureType::GENERIC_FAILURE)); EXPECT_CALL(*ui_delegate(), ShowUnmaskPrompt(_, _, _)); EXPECT_CALL(*ui_delegate(), OnUnmaskVerificationResult(AutofillClient::NETWORK_ERROR)); @@ -502,7 +511,9 @@ // If the server provides an empty PAN with TRY_AGAIN_FAILURE, the user can // manually cancel out of the dialog. TEST_F(FullCardRequestTest, TryAgainFailureGiveUp) { - EXPECT_CALL(*result_delegate(), OnFullCardRequestFailed()); + EXPECT_CALL( + *result_delegate(), + OnFullCardRequestFailed(FullCardRequest::FailureType::PROMPT_CLOSED)); EXPECT_CALL(*ui_delegate(), ShowUnmaskPrompt(_, _, _)); EXPECT_CALL(*ui_delegate(), OnUnmaskVerificationResult(AutofillClient::TRY_AGAIN_FAILURE)); @@ -521,7 +532,7 @@ // If the server provides an empty PAN with TRY_AGAIN_FAILURE, the user can // correct their mistake and resubmit. TEST_F(FullCardRequestTest, TryAgainFailureRetry) { - EXPECT_CALL(*result_delegate(), OnFullCardRequestFailed()).Times(0); + EXPECT_CALL(*result_delegate(), OnFullCardRequestFailed(_)).Times(0); EXPECT_CALL(*result_delegate(), OnFullCardRequestSucceeded( testing::Ref(*request()),
diff --git a/components/autofill_assistant/browser/actions/action_delegate_util.cc b/components/autofill_assistant/browser/actions/action_delegate_util.cc index b5c8868..4f8283d 100644 --- a/components/autofill_assistant/browser/actions/action_delegate_util.cc +++ b/components/autofill_assistant/browser/actions/action_delegate_util.cc
@@ -47,11 +47,12 @@ return; } - std::move((*perform_actions)[action_index]) - .Run(element, - base::BindOnce(&PerformActionsSequentially, - std::move(perform_actions), std::move(status_details), - action_index + 1, element, std::move(done))); + ElementActionCallback action = std::move((*perform_actions)[action_index]); + std::move(action).Run( + element, + base::BindOnce(&PerformActionsSequentially, std::move(perform_actions), + std::move(status_details), action_index + 1, element, + std::move(done))); } void OnFindElement(ElementActionCallback perform, @@ -64,8 +65,9 @@ return; } + const ElementFinder::Result* element_result_ptr = element_result.get(); std::move(perform).Run( - *element_result, + *element_result_ptr, base::BindOnce(&RetainElementAndExecuteCallback, std::move(element_result), std::move(done))); }
diff --git a/components/autofill_assistant/browser/actions/action_delegate_util.h b/components/autofill_assistant/browser/actions/action_delegate_util.h index 1c1a916..681979f 100644 --- a/components/autofill_assistant/browser/actions/action_delegate_util.h +++ b/components/autofill_assistant/browser/actions/action_delegate_util.h
@@ -72,8 +72,9 @@ return; } + const ElementFinder::Result* element_result_ptr = element_result.get(); std::move(perform_and_get) - .Run(*element_result, + .Run(*element_result_ptr, base::BindOnce(&RetainElementAndExecuteGetCallback<R>, std::move(element_result), std::move(done))); }
diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action.cc b/components/autofill_assistant/browser/actions/collect_user_data_action.cc index 87910d2..34f34bd 100644 --- a/components/autofill_assistant/browser/actions/collect_user_data_action.cc +++ b/components/autofill_assistant/browser/actions/collect_user_data_action.cc
@@ -797,9 +797,10 @@ collect_user_data.login_details().login_options()) { switch (login_option.type_case()) { case LoginDetailsProto::LoginOptionProto::kCustom: { + const std::string identifier = base::NumberToString( + collect_user_data_options_->login_choices.size()); LoginChoice choice = { - base::NumberToString( - collect_user_data_options_->login_choices.size()), + identifier, login_option.custom().label(), login_option.sublabel(), login_option.has_sublabel_accessibility_hint() @@ -819,7 +820,7 @@ collect_user_data_options_->login_choices.emplace_back( std::move(choice)); login_details_map_.emplace( - choice.identifier, + identifier, std::make_unique<LoginDetails>( login_option.choose_automatically_if_no_stored_login(), login_option.payload()));
diff --git a/components/autofill_assistant/browser/actions/fallback_handler/required_fields_fallback_handler.cc b/components/autofill_assistant/browser/actions/fallback_handler/required_fields_fallback_handler.cc index df37384..24596df 100644 --- a/components/autofill_assistant/browser/actions/fallback_handler/required_fields_fallback_handler.cc +++ b/components/autofill_assistant/browser/actions/fallback_handler/required_fields_fallback_handler.cc
@@ -284,8 +284,9 @@ return; } + const ElementFinder::Result* element_result_ptr = element_result.get(); action_delegate_->GetWebController()->GetElementTag( - *element_result, + *element_result_ptr, base::BindOnce( &RequiredFieldsFallbackHandler::OnGetFallbackFieldElementTag, weak_ptr_factory_.GetWeakPtr(), value, required_fields_index, @@ -326,17 +327,20 @@ break; } + const ElementFinder::Result* element_ptr = element.get(); action_delegate_->SelectOption( - re2, /* case_sensitive= */ false, option_comparison_attribute, *element, + re2, /* case_sensitive= */ false, option_comparison_attribute, + *element_ptr, base::BindOnce(&RequiredFieldsFallbackHandler::OnSetFallbackFieldValue, weak_ptr_factory_.GetWeakPtr(), required_fields_index, std::move(element))); return; } + const ElementFinder::Result* element_ptr = element.get(); action_delegate_util::PerformSetFieldValue( action_delegate_, value, required_field.fill_strategy, - required_field.delay_in_millisecond, *element, + required_field.delay_in_millisecond, *element_ptr, base::BindOnce(&RequiredFieldsFallbackHandler::OnSetFallbackFieldValue, weak_ptr_factory_.GetWeakPtr(), required_fields_index, std::move(element)));
diff --git a/components/autofill_assistant/browser/controller_unittest.cc b/components/autofill_assistant/browser/controller_unittest.cc index 390ade9..4c0b419 100644 --- a/components/autofill_assistant/browser/controller_unittest.cc +++ b/components/autofill_assistant/browser/controller_unittest.cc
@@ -1563,6 +1563,13 @@ // AA. SimulateNavigateToUrl(GURL("http://other-example.com/")); EXPECT_EQ(AutofillAssistantState::BROWSE, controller_->GetState()); + + // Navigation to different domain should stop AA. + EXPECT_CALL( + mock_client_, + RecordDropOut(Metrics::DropOutReason::DOMAIN_CHANGE_DURING_BROWSE_MODE)); + SimulateNavigateToUrl(GURL("http://unknown.com")); + EXPECT_EQ(AutofillAssistantState::STOPPED, controller_->GetState()); } TEST_F(ControllerTest, BrowseStateWithDomainAllowlistCleanup) {
diff --git a/components/autofill_assistant/browser/self_delete_full_card_requester.cc b/components/autofill_assistant/browser/self_delete_full_card_requester.cc index b2b6573..f0848b3 100644 --- a/components/autofill_assistant/browser/self_delete_full_card_requester.cc +++ b/components/autofill_assistant/browser/self_delete_full_card_requester.cc
@@ -18,6 +18,8 @@ namespace autofill_assistant { +using autofill::payments::FullCardRequest; + SelfDeleteFullCardRequester::SelfDeleteFullCardRequester() {} void SelfDeleteFullCardRequester::GetFullCard( @@ -30,14 +32,14 @@ autofill::ContentAutofillDriverFactory* factory = autofill::ContentAutofillDriverFactory::FromWebContents(web_contents); if (!factory) { - OnFullCardRequestFailed(); + OnFullCardRequestFailed(FullCardRequest::FailureType::GENERIC_FAILURE); return; } autofill::ContentAutofillDriver* driver = factory->DriverForFrame(web_contents->GetMainFrame()); if (!driver) { - OnFullCardRequestFailed(); + OnFullCardRequestFailed(FullCardRequest::FailureType::GENERIC_FAILURE); return; } @@ -50,14 +52,15 @@ SelfDeleteFullCardRequester::~SelfDeleteFullCardRequester() = default; void SelfDeleteFullCardRequester::OnFullCardRequestSucceeded( - const autofill::payments::FullCardRequest& /* full_card_request */, + const FullCardRequest& /* full_card_request */, const autofill::CreditCard& card, const base::string16& cvc) { std::move(callback_).Run(std::make_unique<autofill::CreditCard>(card), cvc); delete this; } -void SelfDeleteFullCardRequester::OnFullCardRequestFailed() { +void SelfDeleteFullCardRequester::OnFullCardRequestFailed( + FullCardRequest::FailureType failure_type) { // Failed might because of cancel, so return nullptr to notice caller. // // TODO(crbug.com/806868): Split the fail notification so that "cancel" and
diff --git a/components/autofill_assistant/browser/self_delete_full_card_requester.h b/components/autofill_assistant/browser/self_delete_full_card_requester.h index 4c01bcf..9861b96 100644 --- a/components/autofill_assistant/browser/self_delete_full_card_requester.h +++ b/components/autofill_assistant/browser/self_delete_full_card_requester.h
@@ -27,14 +27,14 @@ private: ~SelfDeleteFullCardRequester() override; - // payments::FullCardRequest::ResultDelegate: + // autofill::payments::FullCardRequest::ResultDelegate: void OnFullCardRequestSucceeded( const autofill::payments::FullCardRequest& /* full_card_request */, const autofill::CreditCard& card, const base::string16& cvc) override; - - // payments::FullCardRequest::ResultDelegate: - void OnFullCardRequestFailed() override; + void OnFullCardRequestFailed( + autofill::payments::FullCardRequest::FailureType /* failure_type */) + override; ActionDelegate::GetFullCardCallback callback_;
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 9e85239..84771bb0 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -281,8 +281,12 @@ // Show the UI if it's not shown yet. Setting this to false is useful for // scripts started by direct actions. optional bool needs_ui = 15 [default = true]; + + reserved 1, 2, 6, 7, 10, 11, 16 to 18; } optional PresentationProto presentation = 2; + + reserved 3; } enum ScriptStatusProto {
diff --git a/components/drive/drive_uploader.cc b/components/drive/drive_uploader.cc index 97ba2d32..25bd00c8 100644 --- a/components/drive/drive_uploader.cc +++ b/components/drive/drive_uploader.cc
@@ -20,7 +20,6 @@ #include "services/device/public/mojom/wake_lock.mojom.h" using google_apis::CancelCallbackOnce; -using google_apis::CancelCallbackRepeating; using google_apis::DRIVE_CANCELLED; using google_apis::DRIVE_NO_SPACE; using google_apis::DriveApiErrorCode; @@ -156,7 +155,7 @@ // once Cancel() is called. DriveUploader will check this field before after // an async task other than HTTP requests and cancels the subsequent requests // if this is flagged to true. - CancelCallbackRepeating cancel_callback; + CancelCallbackOnce cancel_callback; bool cancelled; private:
diff --git a/components/drive/drive_uploader_unittest.cc b/components/drive/drive_uploader_unittest.cc index f25fdef..6e819c9 100644 --- a/components/drive/drive_uploader_unittest.cc +++ b/components/drive/drive_uploader_unittest.cc
@@ -24,8 +24,7 @@ #include "google_apis/drive/test_util.h" #include "testing/gtest/include/gtest/gtest.h" -using google_apis::CancelCallback; -using google_apis::CancelCallbackRepeating; +using google_apis::CancelCallbackOnce; using google_apis::DRIVE_NO_CONNECTION; using google_apis::DRIVE_OTHER_ERROR; using google_apis::DriveApiErrorCode; @@ -57,7 +56,7 @@ const int64_t kUploadChunkSize = 1024 * 1024 * 1024; const char kTestETag[] = "test_etag"; -CancelCallbackRepeating SendMultipartUploadResult( +CancelCallbackOnce SendMultipartUploadResult( DriveApiErrorCode response_code, int64_t content_length, google_apis::FileResourceCallback callback, @@ -79,7 +78,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), response_code, std::move(entry))); - return CancelCallbackRepeating(); + return CancelCallbackOnce(); } // Mock DriveService that verifies if the uploaded content matches the preset @@ -110,7 +109,7 @@ private: // DriveServiceInterface overrides. // Handles a request for obtaining an upload location URL. - CancelCallback InitiateUploadNewFile( + CancelCallbackOnce InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -127,10 +126,10 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS, GURL(kTestUploadNewFileURL))); - return CancelCallback(); + return CancelCallbackOnce(); } - CancelCallback InitiateUploadExistingFile( + CancelCallbackOnce InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -144,7 +143,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_PRECONDITION, GURL())); - return CancelCallback(); + return CancelCallbackOnce(); } // Calls back the upload URL for subsequent ResumeUpload requests. @@ -152,18 +151,18 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS, GURL(kTestUploadExistingFileURL))); - return CancelCallback(); + return CancelCallbackOnce(); } // Handles a request for uploading a chunk of bytes. - CancelCallback ResumeUpload(const GURL& upload_location, - int64_t start_position, - int64_t end_position, - int64_t content_length, - const std::string& content_type, - const base::FilePath& local_file_path, - UploadRangeCallback callback, - ProgressCallback progress_callback) override { + CancelCallbackOnce ResumeUpload(const GURL& upload_location, + int64_t start_position, + int64_t end_position, + int64_t content_length, + const std::string& content_type, + const base::FilePath& local_file_path, + UploadRangeCallback callback, + ProgressCallback progress_callback) override { // The upload range should start from the current first unreceived byte. EXPECT_EQ(received_bytes_, start_position); EXPECT_EQ(expected_upload_file_, local_file_path); @@ -195,20 +194,20 @@ } SendUploadRangeResponse(upload_location, std::move(callback)); - return CancelCallback(); + return CancelCallbackOnce(); } // Handles a request to fetch the current upload status. - CancelCallback GetUploadStatus(const GURL& upload_location, - int64_t content_length, - UploadRangeCallback callback) override { + CancelCallbackOnce GetUploadStatus(const GURL& upload_location, + int64_t content_length, + UploadRangeCallback callback) override { EXPECT_EQ(expected_content_length_, content_length); // The upload URL returned by InitiateUpload() must be used. EXPECT_TRUE(upload_location == kTestUploadNewFileURL || upload_location == kTestUploadExistingFileURL); SendUploadRangeResponse(upload_location, std::move(callback)); - return CancelCallback(); + return CancelCallbackOnce(); } // Runs |callback| with the current upload status. @@ -235,7 +234,7 @@ base::BindOnce(std::move(callback), response, std::move(entry))); } - CancelCallbackRepeating MultipartUploadNewFile( + CancelCallbackOnce MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -256,7 +255,7 @@ std::move(callback), progress_callback); } - CancelCallbackRepeating MultipartUploadExistingFile( + CancelCallbackOnce MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -273,7 +272,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_PRECONDITION, nullptr)); - return CancelCallbackRepeating(); + return CancelCallbackOnce(); } received_bytes_ = content_length; @@ -292,7 +291,7 @@ // Mock DriveService that returns a failure at InitiateUpload(). class MockDriveServiceNoConnectionAtInitiate : public DummyDriveService { // Returns error. - CancelCallback InitiateUploadNewFile( + CancelCallbackOnce InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -302,10 +301,10 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, GURL())); - return CancelCallback(); + return CancelCallbackOnce(); } - CancelCallback InitiateUploadExistingFile( + CancelCallbackOnce InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -314,23 +313,23 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, GURL())); - return CancelCallback(); + return CancelCallbackOnce(); } // Should not be used. - CancelCallback ResumeUpload(const GURL& upload_url, - int64_t start_position, - int64_t end_position, - int64_t content_length, - const std::string& content_type, - const base::FilePath& local_file_path, - UploadRangeCallback callback, - ProgressCallback progress_callback) override { + CancelCallbackOnce ResumeUpload(const GURL& upload_url, + int64_t start_position, + int64_t end_position, + int64_t content_length, + const std::string& content_type, + const base::FilePath& local_file_path, + UploadRangeCallback callback, + ProgressCallback progress_callback) override { NOTREACHED(); - return CancelCallback(); + return CancelCallbackOnce(); } - CancelCallbackRepeating MultipartUploadNewFile( + CancelCallbackOnce MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -342,10 +341,10 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, nullptr)); - return CancelCallbackRepeating(); + return CancelCallbackOnce(); } - CancelCallbackRepeating MultipartUploadExistingFile( + CancelCallbackOnce MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -356,14 +355,14 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, nullptr)); - return CancelCallbackRepeating(); + return CancelCallbackOnce(); } }; // Mock DriveService that returns a failure at ResumeUpload(). class MockDriveServiceNoConnectionAtResume : public DummyDriveService { // Succeeds and returns an upload location URL. - CancelCallback InitiateUploadNewFile( + CancelCallbackOnce InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -373,10 +372,10 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS, GURL(kTestUploadNewFileURL))); - return CancelCallback(); + return CancelCallbackOnce(); } - CancelCallback InitiateUploadExistingFile( + CancelCallbackOnce InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -385,39 +384,39 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS, GURL(kTestUploadExistingFileURL))); - return CancelCallback(); + return CancelCallbackOnce(); } // Returns error. - CancelCallback ResumeUpload(const GURL& upload_url, - int64_t start_position, - int64_t end_position, - int64_t content_length, - const std::string& content_type, - const base::FilePath& local_file_path, - UploadRangeCallback callback, - ProgressCallback progress_callback) override { + CancelCallbackOnce ResumeUpload(const GURL& upload_url, + int64_t start_position, + int64_t end_position, + int64_t content_length, + const std::string& content_type, + const base::FilePath& local_file_path, + UploadRangeCallback callback, + ProgressCallback progress_callback) override { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), UploadRangeResponse(DRIVE_NO_CONNECTION, -1, -1), nullptr)); - return CancelCallback(); + return CancelCallbackOnce(); } }; // Mock DriveService that returns a failure at GetUploadStatus(). class MockDriveServiceNoConnectionAtGetUploadStatus : public DummyDriveService { // Returns error. - CancelCallback GetUploadStatus(const GURL& upload_url, - int64_t content_length, - UploadRangeCallback callback) override { + CancelCallbackOnce GetUploadStatus(const GURL& upload_url, + int64_t content_length, + UploadRangeCallback callback) override { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), UploadRangeResponse(DRIVE_NO_CONNECTION, -1, -1), nullptr)); - return CancelCallback(); + return CancelCallbackOnce(); } }; @@ -805,7 +804,7 @@ MockDriveServiceForBatchProcessing* service) : service(service) {} - CancelCallback MultipartUploadNewFile( + CancelCallbackOnce MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -824,10 +823,10 @@ info.callback = std::move(callback); info.progress_callback = progress_callback; service->files.push_back(std::move(info)); - return CancelCallback(); + return CancelCallbackOnce(); } - CancelCallback MultipartUploadExistingFile( + CancelCallbackOnce MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -844,7 +843,7 @@ info.callback = std::move(callback); info.progress_callback = progress_callback; service->files.push_back(std::move(info)); - return CancelCallback(); + return CancelCallbackOnce(); } void Commit() override {
diff --git a/components/drive/service/drive_api_service.cc b/components/drive/service/drive_api_service.cc index 9f46cc3..e41f255 100644 --- a/components/drive/service/drive_api_service.cc +++ b/components/drive/service/drive_api_service.cc
@@ -24,7 +24,6 @@ using google_apis::AboutResourceCallback; using google_apis::AuthStatusCallback; -using google_apis::CancelCallback; using google_apis::CancelCallbackOnce; using google_apis::CancelCallbackRepeating; using google_apis::ChangeList; @@ -147,12 +146,11 @@ const base::WeakPtr<google_apis::drive::BatchUploadRequest>& batch_request, base::SequencedTaskRunner* task_runner, const google_apis::DriveApiUrlGenerator& url_generator, - const google_apis::CancelCallback& cancel_callback) + const google_apis::CancelCallbackRepeating& cancel_callback) : batch_request_(batch_request), task_runner_(task_runner), url_generator_(url_generator), - cancel_callback_(cancel_callback) { -} + cancel_callback_(cancel_callback) {} BatchRequestConfigurator::~BatchRequestConfigurator() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -161,7 +159,7 @@ cancel_callback_.Run(); } -google_apis::CancelCallbackRepeating +google_apis::CancelCallbackOnce BatchRequestConfigurator::MultipartUploadNewFile( const std::string& content_type, int64_t content_length, @@ -189,7 +187,7 @@ return cancel_callback_; } -google_apis::CancelCallback +google_apis::CancelCallbackOnce BatchRequestConfigurator::MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, @@ -389,8 +387,8 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::GetChangeList(int64_t start_changestamp, - ChangeListCallback callback) { +CancelCallbackOnce DriveAPIService::GetChangeList(int64_t start_changestamp, + ChangeListCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(callback); @@ -403,7 +401,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::GetChangeListByToken( +CancelCallbackOnce DriveAPIService::GetChangeListByToken( const std::string& team_drive_id, const std::string& start_page_token, ChangeListCallback callback) { @@ -435,7 +433,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::GetRemainingTeamDriveList( +CancelCallbackOnce DriveAPIService::GetRemainingTeamDriveList( const std::string& page_token, TeamDriveListCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -466,8 +464,9 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::GetFileResource(const std::string& resource_id, - FileResourceCallback callback) { +CancelCallbackOnce DriveAPIService::GetFileResource( + const std::string& resource_id, + FileResourceCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!callback.is_null()); @@ -478,7 +477,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::GetAboutResource( +CancelCallbackOnce DriveAPIService::GetAboutResource( AboutResourceCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(callback); @@ -489,7 +488,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::GetStartPageToken( +CancelCallbackOnce DriveAPIService::GetStartPageToken( const std::string& team_drive_id, StartPageTokenCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -519,9 +518,10 @@ progress_callback)); } -CancelCallback DriveAPIService::DeleteResource(const std::string& resource_id, - const std::string& etag, - EntryActionCallback callback) { +CancelCallbackOnce DriveAPIService::DeleteResource( + const std::string& resource_id, + const std::string& etag, + EntryActionCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(callback); @@ -533,8 +533,9 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::TrashResource(const std::string& resource_id, - EntryActionCallback callback) { +CancelCallbackOnce DriveAPIService::TrashResource( + const std::string& resource_id, + EntryActionCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(callback); @@ -569,7 +570,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::CopyResource( +CancelCallbackOnce DriveAPIService::CopyResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -589,7 +590,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::UpdateResource( +CancelCallbackOnce DriveAPIService::UpdateResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -623,7 +624,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::AddResourceToDirectory( +CancelCallbackOnce DriveAPIService::AddResourceToDirectory( const std::string& parent_resource_id, const std::string& resource_id, EntryActionCallback callback) { @@ -653,7 +654,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::InitiateUploadNewFile( +CancelCallbackOnce DriveAPIService::InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -673,7 +674,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::InitiateUploadExistingFile( +CancelCallbackOnce DriveAPIService::InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -694,7 +695,7 @@ return sender_->StartRequestWithAuthRetry(std::move(request)); } -CancelCallback DriveAPIService::ResumeUpload( +CancelCallbackOnce DriveAPIService::ResumeUpload( const GURL& upload_url, int64_t start_position, int64_t end_position, @@ -713,9 +714,10 @@ progress_callback)); } -CancelCallback DriveAPIService::GetUploadStatus(const GURL& upload_url, - int64_t content_length, - UploadRangeCallback callback) { +CancelCallbackOnce DriveAPIService::GetUploadStatus( + const GURL& upload_url, + int64_t content_length, + UploadRangeCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!callback.is_null()); @@ -724,7 +726,7 @@ sender_.get(), upload_url, content_length, std::move(callback))); } -CancelCallbackRepeating DriveAPIService::MultipartUploadNewFile( +CancelCallbackOnce DriveAPIService::MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -747,7 +749,7 @@ progress_callback))); } -CancelCallbackRepeating DriveAPIService::MultipartUploadExistingFile( +CancelCallbackOnce DriveAPIService::MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -770,7 +772,7 @@ std::move(callback), progress_callback))); } -google_apis::CancelCallback DriveAPIService::AddPermission( +google_apis::CancelCallbackOnce DriveAPIService::AddPermission( const std::string& resource_id, const std::string& email, google_apis::drive::PermissionRole role, @@ -845,7 +847,7 @@ // RequestSender before the request is committed because the request has a // reference to RequestSender and we should ensure to delete the request when // the sender is deleted. Resolve the circulating dependency and fix it. - const google_apis::CancelCallback callback = + const google_apis::CancelCallbackRepeating callback = sender_->StartRequestWithAuthRetry(std::move(request)); return std::make_unique<BatchRequestConfigurator>( weak_ref, sender_->blocking_task_runner(), url_generator_, callback);
diff --git a/components/drive/service/drive_api_service.h b/components/drive/service/drive_api_service.h index 9cd57e3..e12b8d31 100644 --- a/components/drive/service/drive_api_service.h +++ b/components/drive/service/drive_api_service.h
@@ -55,11 +55,11 @@ batch_request, base::SequencedTaskRunner* task_runner, const google_apis::DriveApiUrlGenerator& url_generator, - const google_apis::CancelCallback& cancel_callback); + const google_apis::CancelCallbackRepeating& cancel_callback); ~BatchRequestConfigurator() override; // BatchRequestConfiguratorInterface overrides. - google_apis::CancelCallbackRepeating MultipartUploadNewFile( + google_apis::CancelCallbackOnce MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -68,7 +68,7 @@ const UploadNewFileOptions& options, google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallbackRepeating MultipartUploadExistingFile( + google_apis::CancelCallbackOnce MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -144,14 +144,14 @@ const std::string& title, const std::string& directory_resource_id, google_apis::FileListCallback callback) override; - google_apis::CancelCallback GetChangeList( + google_apis::CancelCallbackOnce GetChangeList( int64_t start_changestamp, google_apis::ChangeListCallback callback) override; - google_apis::CancelCallback GetChangeListByToken( + google_apis::CancelCallbackOnce GetChangeListByToken( const std::string& team_drive_id, const std::string& start_page_token, google_apis::ChangeListCallback callback) override; - google_apis::CancelCallback GetRemainingTeamDriveList( + google_apis::CancelCallbackOnce GetRemainingTeamDriveList( const std::string& page_token, google_apis::TeamDriveListCallback callback) override; google_apis::CancelCallbackOnce GetRemainingChangeList( @@ -160,19 +160,19 @@ google_apis::CancelCallbackOnce GetRemainingFileList( const GURL& next_link, google_apis::FileListCallback callback) override; - google_apis::CancelCallback GetFileResource( + google_apis::CancelCallbackOnce GetFileResource( const std::string& resource_id, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback GetAboutResource( + google_apis::CancelCallbackOnce GetAboutResource( google_apis::AboutResourceCallback callback) override; - google_apis::CancelCallback GetStartPageToken( + google_apis::CancelCallbackOnce GetStartPageToken( const std::string& team_drive_id, google_apis::StartPageTokenCallback callback) override; - google_apis::CancelCallback DeleteResource( + google_apis::CancelCallbackOnce DeleteResource( const std::string& resource_id, const std::string& etag, google_apis::EntryActionCallback callback) override; - google_apis::CancelCallback TrashResource( + google_apis::CancelCallbackOnce TrashResource( const std::string& resource_id, google_apis::EntryActionCallback callback) override; google_apis::CancelCallbackOnce DownloadFile( @@ -181,13 +181,13 @@ google_apis::DownloadActionCallback download_action_callback, const google_apis::GetContentCallback& get_content_callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback CopyResource( + google_apis::CancelCallbackOnce CopyResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, const base::Time& last_modified, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback UpdateResource( + google_apis::CancelCallbackOnce UpdateResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -195,7 +195,7 @@ const base::Time& last_viewed_by_me, const google_apis::drive::Properties& properties, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback AddResourceToDirectory( + google_apis::CancelCallbackOnce AddResourceToDirectory( const std::string& parent_resource_id, const std::string& resource_id, google_apis::EntryActionCallback callback) override; @@ -208,20 +208,20 @@ const std::string& directory_title, const AddNewDirectoryOptions& options, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback InitiateUploadNewFile( + google_apis::CancelCallbackOnce InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, const std::string& title, const UploadNewFileOptions& options, google_apis::InitiateUploadCallback callback) override; - google_apis::CancelCallback InitiateUploadExistingFile( + google_apis::CancelCallbackOnce InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, const UploadExistingFileOptions& options, google_apis::InitiateUploadCallback callback) override; - google_apis::CancelCallback ResumeUpload( + google_apis::CancelCallbackOnce ResumeUpload( const GURL& upload_url, int64_t start_position, int64_t end_position, @@ -230,11 +230,11 @@ const base::FilePath& local_file_path, google_apis::drive::UploadRangeCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback GetUploadStatus( + google_apis::CancelCallbackOnce GetUploadStatus( const GURL& upload_url, int64_t content_length, google_apis::drive::UploadRangeCallback callback) override; - google_apis::CancelCallbackRepeating MultipartUploadNewFile( + google_apis::CancelCallbackOnce MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -243,7 +243,7 @@ const drive::UploadNewFileOptions& options, google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallbackRepeating MultipartUploadExistingFile( + google_apis::CancelCallbackOnce MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -251,7 +251,7 @@ const drive::UploadExistingFileOptions& options, google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback AddPermission( + google_apis::CancelCallbackOnce AddPermission( const std::string& resource_id, const std::string& email, google_apis::drive::PermissionRole role,
diff --git a/components/drive/service/drive_api_service_unittest.cc b/components/drive/service/drive_api_service_unittest.cc index 1492169..580c047 100644 --- a/components/drive/service/drive_api_service_unittest.cc +++ b/components/drive/service/drive_api_service_unittest.cc
@@ -57,7 +57,7 @@ sender.StartRequestWithAuthRetry(std::move(request)); BatchRequestConfigurator configurator( request_ptr->GetWeakPtrAsBatchUploadRequest(), task_runner.get(), - url_generator, google_apis::CancelCallback()); + url_generator, google_apis::CancelCallbackRepeating()); static_cast<TestAuthService*>(sender.auth_service())->SendHttpError(); {
diff --git a/components/drive/service/drive_service_interface.h b/components/drive/service/drive_service_interface.h index 7e7feec9..0620ce2 100644 --- a/components/drive/service/drive_service_interface.h +++ b/components/drive/service/drive_service_interface.h
@@ -118,7 +118,7 @@ // for small files than using |InitiateUploadNewFile| and |ResumeUpload|. // |content_type| and |content_length| should be the ones of the file to be // uploaded. |callback| must not be null. |progress_callback| may be null. - virtual google_apis::CancelCallbackRepeating MultipartUploadNewFile( + virtual google_apis::CancelCallbackOnce MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -132,7 +132,7 @@ // for small files than using |InitiateUploadExistingFile| and |ResumeUpload|. // |content_type| and |content_length| should be the ones of the file to be // uploaded. |callback| must not be null. |progress_callback| may be null. - virtual google_apis::CancelCallbackRepeating MultipartUploadExistingFile( + virtual google_apis::CancelCallbackOnce MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -266,7 +266,7 @@ // GetRemainingChangeList. // // |callback| must not be null. - virtual google_apis::CancelCallback GetChangeList( + virtual google_apis::CancelCallbackOnce GetChangeList( int64_t start_changestamp, google_apis::ChangeListCallback callback) = 0; @@ -279,7 +279,7 @@ // GetRemainingChangeList. // // |callback| must not be null. - virtual google_apis::CancelCallback GetChangeListByToken( + virtual google_apis::CancelCallbackOnce GetChangeListByToken( const std::string& team_drive_id, const std::string& start_page_token, google_apis::ChangeListCallback callback) = 0; @@ -299,7 +299,7 @@ // method. |callback| will be called upon completion. // // |next_link| must not be empty. |callback| must not be null. - virtual google_apis::CancelCallback GetRemainingTeamDriveList( + virtual google_apis::CancelCallbackOnce GetRemainingTeamDriveList( const std::string& page_token, google_apis::TeamDriveListCallback callback) = 0; @@ -317,14 +317,14 @@ // |resource_id|. // Upon completion, invokes |callback| with results on the calling thread. // |callback| must not be null. - virtual google_apis::CancelCallback GetFileResource( + virtual google_apis::CancelCallbackOnce GetFileResource( const std::string& resource_id, google_apis::FileResourceCallback callback) = 0; // Gets the about resource information from the server. // Upon completion, invokes |callback| with results on the calling thread. // |callback| must not be null. - virtual google_apis::CancelCallback GetAboutResource( + virtual google_apis::CancelCallbackOnce GetAboutResource( google_apis::AboutResourceCallback callback) = 0; // Gets the start page token information from the server. @@ -332,7 +332,7 @@ // the users changelog. // Upon completion, invokes |callback| with results on the calling thread. // |callback| must not be null. - virtual google_apis::CancelCallback GetStartPageToken( + virtual google_apis::CancelCallbackOnce GetStartPageToken( const std::string& team_drive_id, google_apis::StartPageTokenCallback callback) = 0; @@ -341,7 +341,7 @@ // HTTP_PRECONDITION error. // Upon completion, invokes |callback| with results on the calling thread. // |callback| must not be null. - virtual google_apis::CancelCallback DeleteResource( + virtual google_apis::CancelCallbackOnce DeleteResource( const std::string& resource_id, const std::string& etag, google_apis::EntryActionCallback callback) = 0; @@ -349,7 +349,7 @@ // Trashes a resource identified by its |resource_id|. // Upon completion, invokes |callback| with results on the calling thread. // |callback| must not be null. - virtual google_apis::CancelCallback TrashResource( + virtual google_apis::CancelCallbackOnce TrashResource( const std::string& resource_id, google_apis::EntryActionCallback callback) = 0; @@ -360,7 +360,7 @@ // server will be set to the date. // Upon completion, invokes |callback| with results on the calling thread. // |callback| must not be null. - virtual google_apis::CancelCallback CopyResource( + virtual google_apis::CancelCallbackOnce CopyResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -374,7 +374,7 @@ // If |properties| are specified, then they will be set on |resource_id|. // Upon completion, invokes |callback| with results on the calling thread. // |callback| must not be null. - virtual google_apis::CancelCallback UpdateResource( + virtual google_apis::CancelCallbackOnce UpdateResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -387,7 +387,7 @@ // |resource_id| to a collection represented by the |parent_resource_id|. // Upon completion, invokes |callback| with results on the calling thread. // |callback| must not be null. - virtual google_apis::CancelCallback AddResourceToDirectory( + virtual google_apis::CancelCallbackOnce AddResourceToDirectory( const std::string& parent_resource_id, const std::string& resource_id, google_apis::EntryActionCallback callback) = 0; @@ -437,7 +437,7 @@ // |content_type| and |content_length| should be the ones of the file to be // uploaded. // |callback| must not be null. - virtual google_apis::CancelCallback InitiateUploadNewFile( + virtual google_apis::CancelCallbackOnce InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -449,7 +449,7 @@ // |content_type| and |content_length| should be the ones of the file to be // uploaded. // |callback| must not be null. - virtual google_apis::CancelCallback InitiateUploadExistingFile( + virtual google_apis::CancelCallbackOnce InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -458,7 +458,7 @@ // Resumes uploading of a document/file on the calling thread. // |callback| must not be null. |progress_callback| may be null. - virtual google_apis::CancelCallback ResumeUpload( + virtual google_apis::CancelCallbackOnce ResumeUpload( const GURL& upload_url, int64_t start_position, int64_t end_position, @@ -472,14 +472,14 @@ // |drive_file_path| and |content_length| should be set to the same value // which is used for ResumeUpload. // |callback| must not be null. - virtual google_apis::CancelCallback GetUploadStatus( + virtual google_apis::CancelCallbackOnce GetUploadStatus( const GURL& upload_url, int64_t content_length, google_apis::drive::UploadRangeCallback callback) = 0; // Authorizes the account |email| to access |resource_id| as a |role|. // |callback| must not be null. - virtual google_apis::CancelCallback AddPermission( + virtual google_apis::CancelCallbackOnce AddPermission( const std::string& resource_id, const std::string& email, google_apis::drive::PermissionRole role,
diff --git a/components/drive/service/dummy_drive_service.cc b/components/drive/service/dummy_drive_service.cc index 18d7f4e..4ab390f 100644 --- a/components/drive/service/dummy_drive_service.cc +++ b/components/drive/service/dummy_drive_service.cc
@@ -10,7 +10,6 @@ using google_apis::AboutResourceCallback; using google_apis::AuthStatusCallback; -using google_apis::CancelCallback; using google_apis::CancelCallbackOnce; using google_apis::ChangeListCallback; using google_apis::DownloadActionCallback; @@ -72,7 +71,7 @@ CancelCallbackOnce DummyDriveService::Search(const std::string& search_query, FileListCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce DummyDriveService::SearchByTitle( @@ -82,16 +81,17 @@ return CancelCallbackOnce(); } -CancelCallback DummyDriveService::GetChangeList(int64_t start_changestamp, - ChangeListCallback callback) { - return CancelCallback(); +CancelCallbackOnce DummyDriveService::GetChangeList( + int64_t start_changestamp, + ChangeListCallback callback) { + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::GetChangeListByToken( +CancelCallbackOnce DummyDriveService::GetChangeListByToken( const std::string& team_drive_id, const std::string& start_page_token, ChangeListCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce DummyDriveService::GetRemainingChangeList( @@ -100,44 +100,46 @@ return CancelCallbackOnce(); } -CancelCallback DummyDriveService::GetRemainingTeamDriveList( +CancelCallbackOnce DummyDriveService::GetRemainingTeamDriveList( const std::string& page_token, TeamDriveListCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce DummyDriveService::GetRemainingFileList( const GURL& next_link, FileListCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::GetFileResource( +CancelCallbackOnce DummyDriveService::GetFileResource( const std::string& resource_id, FileResourceCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::GetAboutResource( +CancelCallbackOnce DummyDriveService::GetAboutResource( AboutResourceCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::GetStartPageToken( +CancelCallbackOnce DummyDriveService::GetStartPageToken( const std::string& team_drive_id, google_apis::StartPageTokenCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::DeleteResource(const std::string& resource_id, - const std::string& etag, - EntryActionCallback callback) { - return CancelCallback(); +CancelCallbackOnce DummyDriveService::DeleteResource( + const std::string& resource_id, + const std::string& etag, + EntryActionCallback callback) { + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::TrashResource(const std::string& resource_id, - EntryActionCallback callback) { - return CancelCallback(); +CancelCallbackOnce DummyDriveService::TrashResource( + const std::string& resource_id, + EntryActionCallback callback) { + return CancelCallbackOnce(); } CancelCallbackOnce DummyDriveService::DownloadFile( @@ -146,19 +148,19 @@ DownloadActionCallback download_action_callback, const GetContentCallback& get_content_callback, ProgressCallback progress_callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::CopyResource( +CancelCallbackOnce DummyDriveService::CopyResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, const base::Time& last_modified, FileResourceCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::UpdateResource( +CancelCallbackOnce DummyDriveService::UpdateResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -166,21 +168,21 @@ const base::Time& last_viewed_by_me, const google_apis::drive::Properties& properties, FileResourceCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::AddResourceToDirectory( +CancelCallbackOnce DummyDriveService::AddResourceToDirectory( const std::string& parent_resource_id, const std::string& resource_id, EntryActionCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce DummyDriveService::RemoveResourceFromDirectory( const std::string& parent_resource_id, const std::string& resource_id, EntryActionCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce DummyDriveService::AddNewDirectory( @@ -191,26 +193,26 @@ return CancelCallbackOnce(); } -CancelCallback DummyDriveService::InitiateUploadNewFile( +CancelCallbackOnce DummyDriveService::InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, const std::string& title, const UploadNewFileOptions& options, InitiateUploadCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::InitiateUploadExistingFile( +CancelCallbackOnce DummyDriveService::InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, const UploadExistingFileOptions& options, InitiateUploadCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::ResumeUpload( +CancelCallbackOnce DummyDriveService::ResumeUpload( const GURL& upload_url, int64_t start_position, int64_t end_position, @@ -219,17 +221,17 @@ const base::FilePath& local_file_path, UploadRangeCallback callback, ProgressCallback progress_callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::GetUploadStatus( +CancelCallbackOnce DummyDriveService::GetUploadStatus( const GURL& upload_url, int64_t content_length, UploadRangeCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::MultipartUploadNewFile( +CancelCallbackOnce DummyDriveService::MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -238,10 +240,10 @@ const UploadNewFileOptions& options, FileResourceCallback callback, ProgressCallback progress_callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::MultipartUploadExistingFile( +CancelCallbackOnce DummyDriveService::MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -249,15 +251,15 @@ const UploadExistingFileOptions& options, FileResourceCallback callback, ProgressCallback progress_callback) { - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback DummyDriveService::AddPermission( +CancelCallbackOnce DummyDriveService::AddPermission( const std::string& resource_id, const std::string& email, google_apis::drive::PermissionRole role, EntryActionCallback callback) { - return CancelCallback(); + return CancelCallbackOnce(); } std::unique_ptr<BatchRequestConfiguratorInterface> DummyDriveService::StartBatchRequest() {
diff --git a/components/drive/service/dummy_drive_service.h b/components/drive/service/dummy_drive_service.h index 42d80a7..744f28e 100644 --- a/components/drive/service/dummy_drive_service.h +++ b/components/drive/service/dummy_drive_service.h
@@ -48,35 +48,35 @@ const std::string& title, const std::string& directory_resource_id, google_apis::FileListCallback callback) override; - google_apis::CancelCallback GetChangeList( + google_apis::CancelCallbackOnce GetChangeList( int64_t start_changestamp, google_apis::ChangeListCallback callback) override; - google_apis::CancelCallback GetChangeListByToken( + google_apis::CancelCallbackOnce GetChangeListByToken( const std::string& team_drive_id, const std::string& start_page_token, google_apis::ChangeListCallback callback) override; google_apis::CancelCallbackOnce GetRemainingChangeList( const GURL& next_link, google_apis::ChangeListCallback callback) override; - google_apis::CancelCallback GetRemainingTeamDriveList( + google_apis::CancelCallbackOnce GetRemainingTeamDriveList( const std::string& page_token, google_apis::TeamDriveListCallback callback) override; google_apis::CancelCallbackOnce GetRemainingFileList( const GURL& next_link, google_apis::FileListCallback callback) override; - google_apis::CancelCallback GetFileResource( + google_apis::CancelCallbackOnce GetFileResource( const std::string& resource_id, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback GetAboutResource( + google_apis::CancelCallbackOnce GetAboutResource( google_apis::AboutResourceCallback callback) override; - google_apis::CancelCallback GetStartPageToken( + google_apis::CancelCallbackOnce GetStartPageToken( const std::string& team_drive_id, google_apis::StartPageTokenCallback callback) override; - google_apis::CancelCallback DeleteResource( + google_apis::CancelCallbackOnce DeleteResource( const std::string& resource_id, const std::string& etag, google_apis::EntryActionCallback callback) override; - google_apis::CancelCallback TrashResource( + google_apis::CancelCallbackOnce TrashResource( const std::string& resource_id, google_apis::EntryActionCallback callback) override; google_apis::CancelCallbackOnce DownloadFile( @@ -85,13 +85,13 @@ google_apis::DownloadActionCallback download_action_callback, const google_apis::GetContentCallback& get_content_callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback CopyResource( + google_apis::CancelCallbackOnce CopyResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, const base::Time& last_modified, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback UpdateResource( + google_apis::CancelCallbackOnce UpdateResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -99,7 +99,7 @@ const base::Time& last_viewed_by_me, const google_apis::drive::Properties& properties, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback AddResourceToDirectory( + google_apis::CancelCallbackOnce AddResourceToDirectory( const std::string& parent_resource_id, const std::string& resource_id, google_apis::EntryActionCallback callback) override; @@ -112,20 +112,20 @@ const std::string& directory_title, const AddNewDirectoryOptions& options, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback InitiateUploadNewFile( + google_apis::CancelCallbackOnce InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, const std::string& title, const UploadNewFileOptions& options, google_apis::InitiateUploadCallback callback) override; - google_apis::CancelCallback InitiateUploadExistingFile( + google_apis::CancelCallbackOnce InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, const UploadExistingFileOptions& options, google_apis::InitiateUploadCallback callback) override; - google_apis::CancelCallback ResumeUpload( + google_apis::CancelCallbackOnce ResumeUpload( const GURL& upload_url, int64_t start_position, int64_t end_position, @@ -134,11 +134,11 @@ const base::FilePath& local_file_path, google_apis::drive::UploadRangeCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback GetUploadStatus( + google_apis::CancelCallbackOnce GetUploadStatus( const GURL& upload_url, int64_t content_length, google_apis::drive::UploadRangeCallback callback) override; - google_apis::CancelCallback MultipartUploadNewFile( + google_apis::CancelCallbackOnce MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -147,7 +147,7 @@ const UploadNewFileOptions& options, google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback MultipartUploadExistingFile( + google_apis::CancelCallbackOnce MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -155,7 +155,7 @@ const UploadExistingFileOptions& options, google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback AddPermission( + google_apis::CancelCallbackOnce AddPermission( const std::string& resource_id, const std::string& email, google_apis::drive::PermissionRole role,
diff --git a/components/drive/service/fake_drive_service.cc b/components/drive/service/fake_drive_service.cc index 0293f527..0c83660 100644 --- a/components/drive/service/fake_drive_service.cc +++ b/components/drive/service/fake_drive_service.cc
@@ -38,7 +38,6 @@ using google_apis::AboutResource; using google_apis::AboutResourceCallback; using google_apis::AuthStatusCallback; -using google_apis::CancelCallback; using google_apis::CancelCallbackOnce; using google_apis::ChangeList; using google_apis::ChangeListCallback; @@ -409,7 +408,7 @@ if (never_return_all_file_list_) { ++blocked_file_list_load_count_; - return CancelCallback(); + return CancelCallbackOnce(); } GetChangeListInternal( @@ -453,7 +452,7 @@ 0, // start offset default_max_results_, nullptr, base::BindOnce(&FileListCallbackAdapter, std::move(callback))); - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce FakeDriveService::SearchByTitle( @@ -475,8 +474,9 @@ return CancelCallbackOnce(); } -CancelCallback FakeDriveService::GetChangeList(int64_t start_changestamp, - ChangeListCallback callback) { +CancelCallbackOnce FakeDriveService::GetChangeList( + int64_t start_changestamp, + ChangeListCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(callback); @@ -487,10 +487,10 @@ 0, // start offset default_max_results_, &change_list_load_count_, std::move(callback)); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::GetChangeListByToken( +CancelCallbackOnce FakeDriveService::GetChangeListByToken( const std::string& team_drive_id, const std::string& start_page_token, ChangeListCallback callback) { @@ -508,7 +508,7 @@ default_max_results_, &change_list_load_count_, std::move(callback)); - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce FakeDriveService::GetRemainingChangeList( @@ -559,7 +559,7 @@ return CancelCallbackOnce(); } -CancelCallback FakeDriveService::GetRemainingTeamDriveList( +CancelCallbackOnce FakeDriveService::GetRemainingTeamDriveList( const std::string& page_token, TeamDriveListCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -572,7 +572,7 @@ DCHECK(parse_success); GetTeamDriveListInternal(start_offset, default_max_results_, nullptr, std::move(callback)); - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce FakeDriveService::GetRemainingFileList( @@ -585,7 +585,7 @@ next_link, base::BindOnce(&FileListCallbackAdapter, std::move(callback))); } -CancelCallback FakeDriveService::GetFileResource( +CancelCallbackOnce FakeDriveService::GetFileResource( const std::string& resource_id, FileResourceCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -595,7 +595,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, std::unique_ptr<FileResource>())); - return CancelCallback(); + return CancelCallbackOnce(); } EntryInfo* entry = FindEntryByResourceId(resource_id); @@ -604,16 +604,16 @@ FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS, std::make_unique<FileResource>( *entry->change_resource.file()))); - return CancelCallback(); + return CancelCallbackOnce(); } base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND, std::unique_ptr<FileResource>())); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::GetAboutResource( +CancelCallbackOnce FakeDriveService::GetAboutResource( AboutResourceCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(callback); @@ -623,7 +623,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, std::move(null))); - return CancelCallback(); + return CancelCallbackOnce(); } ++about_resource_load_count_; @@ -632,10 +632,10 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS, std::move(about_resource))); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::GetStartPageToken( +CancelCallbackOnce FakeDriveService::GetStartPageToken( const std::string& team_drive_id, google_apis::StartPageTokenCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -646,7 +646,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, std::move(null))); - return CancelCallback(); + return CancelCallbackOnce(); } std::unique_ptr<StartPageToken> start_page_token; @@ -661,46 +661,47 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS, std::move(start_page_token))); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::DeleteResource(const std::string& resource_id, - const std::string& etag, - EntryActionCallback callback) { +CancelCallbackOnce FakeDriveService::DeleteResource( + const std::string& resource_id, + const std::string& etag, + EntryActionCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(callback); if (offline_) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION)); - return CancelCallback(); + return CancelCallbackOnce(); } EntryInfo* entry = FindEntryByResourceId(resource_id); if (!entry) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND)); - return CancelCallback(); + return CancelCallbackOnce(); } ChangeResource* change = &entry->change_resource; if (change->is_deleted()) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND)); - return CancelCallback(); + return CancelCallbackOnce(); } const FileResource* file = change->file(); if (!etag.empty() && etag != file->etag()) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_PRECONDITION)); - return CancelCallback(); + return CancelCallbackOnce(); } if (entry->user_permission != google_apis::drive::PERMISSION_ROLE_OWNER) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_FORBIDDEN)); - return CancelCallback(); + return CancelCallbackOnce(); } change->set_deleted(true); @@ -711,25 +712,26 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers, weak_ptr_factory_.GetWeakPtr())); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::TrashResource(const std::string& resource_id, - EntryActionCallback callback) { +CancelCallbackOnce FakeDriveService::TrashResource( + const std::string& resource_id, + EntryActionCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(callback); if (offline_) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION)); - return CancelCallback(); + return CancelCallbackOnce(); } EntryInfo* entry = FindEntryByResourceId(resource_id); if (!entry) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND)); - return CancelCallback(); + return CancelCallbackOnce(); } ChangeResource* change = &entry->change_resource; @@ -737,13 +739,13 @@ if (change->is_deleted() || file->labels().is_trashed()) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND)); - return CancelCallback(); + return CancelCallbackOnce(); } if (entry->user_permission != google_apis::drive::PERMISSION_ROLE_OWNER) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_FORBIDDEN)); - return CancelCallback(); + return CancelCallbackOnce(); } file->mutable_labels()->set_trashed(true); @@ -753,7 +755,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers, weak_ptr_factory_.GetWeakPtr())); - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce FakeDriveService::DownloadFile( @@ -821,7 +823,7 @@ return google_apis::CancelCallbackOnce(); } -CancelCallback FakeDriveService::CopyResource( +CancelCallbackOnce FakeDriveService::CopyResource( const std::string& resource_id, const std::string& in_parent_resource_id, const std::string& new_title, @@ -834,7 +836,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, std::unique_ptr<FileResource>())); - return CancelCallback(); + return CancelCallbackOnce(); } const std::string& parent_resource_id = in_parent_resource_id.empty() ? @@ -845,7 +847,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND, std::unique_ptr<FileResource>())); - return CancelCallback(); + return CancelCallbackOnce(); } // Make a copy and set the new resource ID and the new title. @@ -897,10 +899,10 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers, weak_ptr_factory_.GetWeakPtr())); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::UpdateResource( +CancelCallbackOnce FakeDriveService::UpdateResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -915,7 +917,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, std::unique_ptr<FileResource>())); - return CancelCallback(); + return CancelCallbackOnce(); } EntryInfo* entry = FindEntryByResourceId(resource_id); @@ -923,14 +925,14 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND, std::unique_ptr<FileResource>())); - return CancelCallback(); + return CancelCallbackOnce(); } if (!UserHasWriteAccess(entry->user_permission)) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_FORBIDDEN, std::unique_ptr<FileResource>())); - return CancelCallback(); + return CancelCallbackOnce(); } ChangeResource* change = &entry->change_resource; @@ -966,10 +968,10 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers, weak_ptr_factory_.GetWeakPtr())); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::AddResourceToDirectory( +CancelCallbackOnce FakeDriveService::AddResourceToDirectory( const std::string& parent_resource_id, const std::string& resource_id, EntryActionCallback callback) { @@ -979,14 +981,14 @@ if (offline_) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION)); - return CancelCallback(); + return CancelCallbackOnce(); } EntryInfo* entry = FindEntryByResourceId(resource_id); if (!entry) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND)); - return CancelCallback(); + return CancelCallbackOnce(); } ChangeResource* change = &entry->change_resource; @@ -1004,7 +1006,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers, weak_ptr_factory_.GetWeakPtr())); - return CancelCallback(); + return CancelCallbackOnce(); } CancelCallbackOnce FakeDriveService::RemoveResourceFromDirectory( @@ -1058,7 +1060,7 @@ directory_title, options, std::move(callback)); } -CancelCallback FakeDriveService::InitiateUploadNewFile( +CancelCallbackOnce FakeDriveService::InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -1072,14 +1074,14 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, GURL())); - return CancelCallback(); + return CancelCallbackOnce(); } if (parent_resource_id != GetRootResourceId() && !entries_.count(parent_resource_id)) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND, GURL())); - return CancelCallback(); + return CancelCallbackOnce(); } GURL session_url = GetNewUploadSessionUrl(); @@ -1091,16 +1093,16 @@ title); if (title == "never-sync.txt") { - return CancelCallback(); + return CancelCallbackOnce(); } base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS, session_url)); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::InitiateUploadExistingFile( +CancelCallbackOnce FakeDriveService::InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -1113,20 +1115,20 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), DRIVE_NO_CONNECTION, GURL())); - return CancelCallback(); + return CancelCallbackOnce(); } EntryInfo* entry = FindEntryByResourceId(resource_id); if (!entry) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_NOT_FOUND, GURL())); - return CancelCallback(); + return CancelCallbackOnce(); } if (!UserHasWriteAccess(entry->user_permission)) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_FORBIDDEN, GURL())); - return CancelCallback(); + return CancelCallbackOnce(); } FileResource* file = entry->change_resource.mutable_file(); @@ -1134,7 +1136,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_PRECONDITION, GURL())); - return CancelCallback(); + return CancelCallbackOnce(); } // TODO(hashimoto): Update |file|'s metadata with |options|. @@ -1149,18 +1151,19 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), HTTP_SUCCESS, session_url)); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::GetUploadStatus(const GURL& upload_url, - int64_t content_length, - UploadRangeCallback callback) { +CancelCallbackOnce FakeDriveService::GetUploadStatus( + const GURL& upload_url, + int64_t content_length, + UploadRangeCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(callback); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::ResumeUpload( +CancelCallbackOnce FakeDriveService::ResumeUpload( const GURL& upload_url, int64_t start_position, int64_t end_position, @@ -1179,13 +1182,13 @@ if (offline_) { std::move(completion_callback) .Run(DRIVE_NO_CONNECTION, std::unique_ptr<FileResource>()); - return CancelCallback(); + return CancelCallbackOnce(); } if (!upload_sessions_.count(upload_url)) { std::move(completion_callback) .Run(HTTP_NOT_FOUND, std::unique_ptr<FileResource>()); - return CancelCallback(); + return CancelCallbackOnce(); } UploadSession* session = &upload_sessions_[upload_url]; @@ -1195,7 +1198,7 @@ if (session->uploaded_size != start_position) { std::move(completion_callback) .Run(HTTP_BAD_REQUEST, std::unique_ptr<FileResource>()); - return CancelCallback(); + return CancelCallbackOnce(); } if (!progress_callback.is_null()) { @@ -1217,7 +1220,7 @@ session->uploaded_size = end_position; std::move(completion_callback) .Run(HTTP_RESUME_INCOMPLETE, std::unique_ptr<FileResource>()); - return CancelCallback(); + return CancelCallbackOnce(); } std::string content_data; @@ -1227,7 +1230,7 @@ session->uploaded_size = end_position; std::move(completion_callback) .Run(DRIVE_FILE_ERROR, std::unique_ptr<FileResource>()); - return CancelCallback(); + return CancelCallbackOnce(); } } session->uploaded_size = end_position; @@ -1246,7 +1249,7 @@ if (!new_entry) { std::move(completion_callback) .Run(HTTP_NOT_FOUND, std::unique_ptr<FileResource>()); - return CancelCallback(); + return CancelCallbackOnce(); } std::move(completion_callback) @@ -1255,14 +1258,14 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers, weak_ptr_factory_.GetWeakPtr())); - return CancelCallback(); + return CancelCallbackOnce(); } EntryInfo* entry = FindEntryByResourceId(session->resource_id); if (!entry) { std::move(completion_callback) .Run(HTTP_NOT_FOUND, std::unique_ptr<FileResource>()); - return CancelCallback(); + return CancelCallbackOnce(); } ChangeResource* change = &entry->change_resource; @@ -1270,7 +1273,7 @@ if (file->etag().empty() || session->etag != file->etag()) { std::move(completion_callback) .Run(HTTP_PRECONDITION, std::unique_ptr<FileResource>()); - return CancelCallback(); + return CancelCallbackOnce(); } file->set_md5_checksum(base::MD5String(content_data)); @@ -1284,10 +1287,10 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&FakeDriveService::NotifyObservers, weak_ptr_factory_.GetWeakPtr())); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::MultipartUploadNewFile( +CancelCallbackOnce FakeDriveService::MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -1310,10 +1313,10 @@ title, options, base::Bind(&CallResumeUpload::Run, base::Owned(call_resume_upload))); - return CancelCallback(); + return CancelCallbackOnce(); } -CancelCallback FakeDriveService::MultipartUploadExistingFile( +CancelCallbackOnce FakeDriveService::MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -1334,7 +1337,7 @@ resource_id, options, base::Bind(&CallResumeUpload::Run, base::Owned(call_resume_upload))); - return CancelCallback(); + return CancelCallbackOnce(); } void FakeDriveService::AddNewFile(const std::string& content_type, @@ -1913,7 +1916,7 @@ base::NumberToString(next_upload_sequence_number_++)); } -google_apis::CancelCallback FakeDriveService::AddPermission( +CancelCallbackOnce FakeDriveService::AddPermission( const std::string& resource_id, const std::string& email, google_apis::drive::PermissionRole role, @@ -1922,7 +1925,7 @@ DCHECK(callback); NOTREACHED(); - return CancelCallback(); + return CancelCallbackOnce(); } std::unique_ptr<BatchRequestConfiguratorInterface>
diff --git a/components/drive/service/fake_drive_service.h b/components/drive/service/fake_drive_service.h index f77076a..54a8662 100644 --- a/components/drive/service/fake_drive_service.h +++ b/components/drive/service/fake_drive_service.h
@@ -150,35 +150,35 @@ const std::string& title, const std::string& directory_resource_id, google_apis::FileListCallback callback) override; - google_apis::CancelCallback GetChangeList( + google_apis::CancelCallbackOnce GetChangeList( int64_t start_changestamp, google_apis::ChangeListCallback callback) override; - google_apis::CancelCallback GetChangeListByToken( + google_apis::CancelCallbackOnce GetChangeListByToken( const std::string& team_drive_id, const std::string& start_page_token, google_apis::ChangeListCallback callback) override; google_apis::CancelCallbackOnce GetRemainingChangeList( const GURL& next_link, google_apis::ChangeListCallback callback) override; - google_apis::CancelCallback GetRemainingTeamDriveList( + google_apis::CancelCallbackOnce GetRemainingTeamDriveList( const std::string& page_token, google_apis::TeamDriveListCallback callback) override; google_apis::CancelCallbackOnce GetRemainingFileList( const GURL& next_link, google_apis::FileListCallback callback) override; - google_apis::CancelCallback GetFileResource( + google_apis::CancelCallbackOnce GetFileResource( const std::string& resource_id, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback GetAboutResource( + google_apis::CancelCallbackOnce GetAboutResource( google_apis::AboutResourceCallback callback) override; - google_apis::CancelCallback GetStartPageToken( + google_apis::CancelCallbackOnce GetStartPageToken( const std::string& team_drive_id, google_apis::StartPageTokenCallback callback) override; - google_apis::CancelCallback DeleteResource( + google_apis::CancelCallbackOnce DeleteResource( const std::string& resource_id, const std::string& etag, google_apis::EntryActionCallback callback) override; - google_apis::CancelCallback TrashResource( + google_apis::CancelCallbackOnce TrashResource( const std::string& resource_id, google_apis::EntryActionCallback callback) override; google_apis::CancelCallbackOnce DownloadFile( @@ -187,13 +187,13 @@ google_apis::DownloadActionCallback download_action_callback, const google_apis::GetContentCallback& get_content_callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback CopyResource( + google_apis::CancelCallbackOnce CopyResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, const base::Time& last_modified, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback UpdateResource( + google_apis::CancelCallbackOnce UpdateResource( const std::string& resource_id, const std::string& parent_resource_id, const std::string& new_title, @@ -201,7 +201,7 @@ const base::Time& last_viewed_by_me, const google_apis::drive::Properties& properties, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback AddResourceToDirectory( + google_apis::CancelCallbackOnce AddResourceToDirectory( const std::string& parent_resource_id, const std::string& resource_id, google_apis::EntryActionCallback callback) override; @@ -214,20 +214,20 @@ const std::string& directory_title, const AddNewDirectoryOptions& options, google_apis::FileResourceCallback callback) override; - google_apis::CancelCallback InitiateUploadNewFile( + google_apis::CancelCallbackOnce InitiateUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, const std::string& title, const UploadNewFileOptions& options, google_apis::InitiateUploadCallback callback) override; - google_apis::CancelCallback InitiateUploadExistingFile( + google_apis::CancelCallbackOnce InitiateUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, const UploadExistingFileOptions& options, google_apis::InitiateUploadCallback callback) override; - google_apis::CancelCallback ResumeUpload( + google_apis::CancelCallbackOnce ResumeUpload( const GURL& upload_url, int64_t start_position, int64_t end_position, @@ -236,11 +236,11 @@ const base::FilePath& local_file_path, google_apis::drive::UploadRangeCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback GetUploadStatus( + google_apis::CancelCallbackOnce GetUploadStatus( const GURL& upload_url, int64_t content_length, google_apis::drive::UploadRangeCallback callback) override; - google_apis::CancelCallback MultipartUploadNewFile( + google_apis::CancelCallbackOnce MultipartUploadNewFile( const std::string& content_type, int64_t content_length, const std::string& parent_resource_id, @@ -249,7 +249,7 @@ const UploadNewFileOptions& options, google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback MultipartUploadExistingFile( + google_apis::CancelCallbackOnce MultipartUploadExistingFile( const std::string& content_type, int64_t content_length, const std::string& resource_id, @@ -257,7 +257,7 @@ const UploadExistingFileOptions& options, google_apis::FileResourceCallback callback, google_apis::ProgressCallback progress_callback) override; - google_apis::CancelCallback AddPermission( + google_apis::CancelCallbackOnce AddPermission( const std::string& resource_id, const std::string& email, google_apis::drive::PermissionRole role,
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index 6d738eb..071f9f16 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -498,6 +498,10 @@ return true; } +void ShellSurface::SetDecorationMode(SurfaceFrameType type) { + OnSetFrame(type); +} + //////////////////////////////////////////////////////////////////////////////// // ShellSurface, private:
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h index 056114a..3b53ff7 100644 --- a/components/exo/shell_surface.h +++ b/components/exo/shell_surface.h
@@ -125,6 +125,9 @@ void SetWidgetBounds(const gfx::Rect& bounds) override; bool OnPreWidgetCommit() override; + // Set xdg-shell decoration mode. + void SetDecorationMode(SurfaceFrameType type); + private: struct Config;
diff --git a/components/exo/wayland/xdg_shell.cc b/components/exo/wayland/xdg_shell.cc index 07abcf49..4bcd391 100644 --- a/components/exo/wayland/xdg_shell.cc +++ b/components/exo/wayland/xdg_shell.cc
@@ -159,36 +159,6 @@ DISALLOW_COPY_AND_ASSIGN(WaylandXdgSurface); }; -class WaylandXdgToplevelDecoration { - public: - WaylandXdgToplevelDecoration(wl_resource* resource) : resource_(resource) {} - - WaylandXdgToplevelDecoration(const WaylandXdgToplevelDecoration&) = delete; - WaylandXdgToplevelDecoration& operator=(const WaylandXdgToplevelDecoration&) = - delete; - - uint32_t decoration_mode() const { return default_mode_; } - void SetDecorationMode(uint32_t mode) { - if (default_mode_ != mode) { - default_mode_ = mode; - OnConfigure(mode); - } - } - - private: - void OnConfigure(uint32_t mode) { - switch (mode) { - case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE: - case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE: - zxdg_toplevel_decoration_v1_send_configure(resource_, mode); - break; - } - } - - wl_resource* const resource_; - uint32_t default_mode_ = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; -}; - // Wrapper around shell surface that allows us to handle the case where the // xdg surface resource is destroyed before the toplevel resource. class WaylandToplevel : public aura::WindowObserver { @@ -287,6 +257,11 @@ shell_surface_data_->shell_surface->Minimize(); } + void SetDecorationMode(SurfaceFrameType type) { + if (shell_surface_data_) + shell_surface_data_->shell_surface->SetDecorationMode(type); + } + private: void OnClose() { xdg_toplevel_send_close(resource_); @@ -425,6 +400,44 @@ xdg_toplevel_unset_maximized, xdg_toplevel_set_fullscreen, xdg_toplevel_unset_fullscreen, xdg_toplevel_set_minimized}; +class WaylandXdgToplevelDecoration { + public: + WaylandXdgToplevelDecoration(wl_resource* resource, + wl_resource* toplevel_resource) + : resource_(resource), + top_level_(GetUserDataAs<WaylandToplevel>(toplevel_resource)) {} + + WaylandXdgToplevelDecoration(const WaylandXdgToplevelDecoration&) = delete; + WaylandXdgToplevelDecoration& operator=(const WaylandXdgToplevelDecoration&) = + delete; + + uint32_t decoration_mode() const { return default_mode_; } + void SetDecorationMode(uint32_t mode) { + if (default_mode_ != mode) { + default_mode_ = mode; + OnConfigure(mode); + } + } + + private: + void OnConfigure(uint32_t mode) { + switch (mode) { + case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE: + top_level_->SetDecorationMode(SurfaceFrameType::NONE); + break; + case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE: + top_level_->SetDecorationMode(SurfaceFrameType::NORMAL); + break; + } + zxdg_toplevel_decoration_v1_send_configure(resource_, mode); + } + + wl_resource* const resource_; + WaylandToplevel* top_level_; + // Keeps track of the xdg-decoration mode on server side. + uint32_t default_mode_ = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; +}; + //////////////////////////////////////////////////////////////////////////////// // xdg_popup_interface: @@ -733,12 +746,8 @@ return; } - auto xdg_toplevel_decoration = - std::make_unique<WaylandXdgToplevelDecoration>(decoration_resource); - - // Enables client-side decoration - xdg_toplevel_decoration->SetDecorationMode( - ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); + auto xdg_toplevel_decoration = std::make_unique<WaylandXdgToplevelDecoration>( + decoration_resource, toplevel_resource); SetImplementation(decoration_resource, &toplevel_decoration_impl, std::move(xdg_toplevel_decoration));
diff --git a/components/optimization_guide/optimization_guide_switches.cc b/components/optimization_guide/optimization_guide_switches.cc index ff032c3..570dff9 100644 --- a/components/optimization_guide/optimization_guide_switches.cc +++ b/components/optimization_guide/optimization_guide_switches.cc
@@ -66,6 +66,9 @@ const char kDisableCheckingUserPermissionsForTesting[] = "disable-checking-optimization-guide-user-permissions"; +const char kDisableModelDownloadVerificationForTesting[] = + "disable-model-download-verification"; + bool IsHintComponentProcessingDisabled() { return base::CommandLine::ForCurrentProcess()->HasSwitch(kHintsProtoOverride); } @@ -149,5 +152,10 @@ return command_line->HasSwitch(kDisableCheckingUserPermissionsForTesting); } +bool ShouldSkipModelDownloadVerificationForTesting() { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + return command_line->HasSwitch(kDisableModelDownloadVerificationForTesting); +} + } // namespace switches } // namespace optimization_guide
diff --git a/components/optimization_guide/optimization_guide_switches.h b/components/optimization_guide/optimization_guide_switches.h index 6460a34..29d05fd 100644 --- a/components/optimization_guide/optimization_guide_switches.h +++ b/components/optimization_guide/optimization_guide_switches.h
@@ -29,6 +29,7 @@ extern const char kPurgeModelAndFeaturesStore[]; extern const char kDisableFetchingHintsAtNavigationStartForTesting[]; extern const char kDisableCheckingUserPermissionsForTesting[]; +extern const char kDisableModelDownloadVerificationForTesting[]; // Returns whether the hint component should be processed. // Available hint components are only processed if a proto override isn't being @@ -72,6 +73,9 @@ // tests. bool ShouldOverrideCheckingUserPermissionsToFetchHintsForTesting(); +// Returns true if the verification of model downloads should be skipped. +bool ShouldSkipModelDownloadVerificationForTesting(); + } // namespace switches } // namespace optimization_guide
diff --git a/components/payments/content/autofill_payment_app.cc b/components/payments/content/autofill_payment_app.cc index b5718993..d4c6f50 100644 --- a/components/payments/content/autofill_payment_app.cc +++ b/components/payments/content/autofill_payment_app.cc
@@ -193,7 +193,8 @@ GenerateBasicCardResponse(); } -void AutofillPaymentApp::OnFullCardRequestFailed() { +void AutofillPaymentApp::OnFullCardRequestFailed( + autofill::payments::FullCardRequest::FailureType failure_type) { // The user may have cancelled the unmask or something has gone wrong (e.g., // the network request failed). In all cases, reset the |delegate_| so another // request can start.
diff --git a/components/payments/content/autofill_payment_app.h b/components/payments/content/autofill_payment_app.h index 2f6b4df8..cae2824 100644 --- a/components/payments/content/autofill_payment_app.h +++ b/components/payments/content/autofill_payment_app.h
@@ -64,7 +64,8 @@ const autofill::payments::FullCardRequest& full_card_request, const autofill::CreditCard& card, const base::string16& cvc) override; - void OnFullCardRequestFailed() override; + void OnFullCardRequestFailed( + autofill::payments::FullCardRequest::FailureType failure_type) override; void RecordMissingFieldsForApp() const;
diff --git a/components/policy/tools/syntax_check_policy_template_json.py b/components/policy/tools/syntax_check_policy_template_json.py index 7c8a883..b2dd1d0c 100755 --- a/components/policy/tools/syntax_check_policy_template_json.py +++ b/components/policy/tools/syntax_check_policy_template_json.py
@@ -182,22 +182,6 @@ if supported_on_to else None) -def _PolicyStillSupported(supported_on, current_version): - for s in supported_on: - _, _, supported_on_to = _GetSupportedVersionPlatformAndRange(s) - - # If supported_on_to isn't given, this policy is still supported. - if supported_on_to is None: - return True - - # If supported_on_to is equal or greater than the current version, it's - # still supported. - if current_version <= int(supported_on_to): - return True - - return False - - def _GetPolicyValueType(policy_type): if policy_type == 'main': return bool @@ -516,10 +500,16 @@ def _NeedsDefault(self, policy): return policy.get('type') in ('int', 'main', 'string-enum', 'int-enum') - def _CheckDefault(self, policy): + def _CheckDefault(self, policy, current_version): if not self._NeedsDefault(policy): return + # If a policy should have a default but it is no longer supported, we can + # safely ignore this error. + if ('default' not in policy + and not self._SupportedPolicy(policy, current_version)): + return + # Only validate the default when present. # TODO(crbug.com/1139046): Always validate the default for types that # should have it. @@ -559,10 +549,16 @@ return policy.get('type') in ('main', 'int-enum', 'string-enum', 'string-enum-list') - def _CheckItems(self, policy): + def _CheckItems(self, policy, current_version): if not self._NeedsItems(policy): return + # If a policy should have items, but it is no longer supported, we + # can safely ignore this error. + if 'items' not in policy and not self._SupportedPolicy( + policy, current_version): + return + # TODO(crbug.com/1139306): Remove this check once all main policies # have specified their items field. policy_type = policy.get('type') @@ -684,6 +680,25 @@ 'be committer emails or file:// paths' % (policy.get('name'), owner)) + def _SupportedPolicy(self, policy, current_version): + # If a policy has any future_on platforms, it is still supported. + if len(policy.get('future_on', [])) > 0: + return True + + for s in policy.get('supported_on', []): + _, _, supported_on_to = _GetSupportedVersionPlatformAndRange(s) + + # If supported_on_to isn't given, this policy is still supported. + if supported_on_to is None: + return True + + # If supported_on_to is equal or greater than the current version, it's + # still supported. + if current_version <= int(supported_on_to): + return True + + return False + def _CheckPolicy(self, policy, is_in_group, policy_ids, deleted_policy_ids, current_version): if not isinstance(policy, dict): @@ -832,7 +847,7 @@ 'supported version must have a version larger than the ' 'starting supported version.', 'policy', policy, supported_on) - if (not _PolicyStillSupported(supported_on, current_version) + if (not self._SupportedPolicy(policy, current_version) and not policy.get('deprecated', False)): self._Error( 'Policy %s is marked as no longer supported (%s), but isn\'t ' @@ -1029,14 +1044,14 @@ self._Error(('Example for policy %s does not comply to the ' + 'policy\'s validation_schema') % policy.get('name')) - self._CheckDefault(policy) + self._CheckDefault(policy, current_version) # Statistics. self.num_policies += 1 if is_in_group: self.num_policies_in_groups += 1 - self._CheckItems(policy) + self._CheckItems(policy, current_version) if policy_type == 'external': # Each policy referencing external data must specify a maximum data
diff --git a/components/printing/browser/print_composite_client.cc b/components/printing/browser/print_composite_client.cc index 02a7786..a14bba7 100644 --- a/components/printing/browser/print_composite_client.cc +++ b/components/printing/browser/print_composite_client.cc
@@ -101,6 +101,19 @@ print_render_frames_.erase(render_frame_host); } +PrintCompositeClient::RequestedSubFrame::RequestedSubFrame( + int render_process_id, + int render_frame_id, + int document_cookie, + mojom::DidPrintContentParamsPtr params, + bool is_live) + : render_process_id_(render_process_id), + render_frame_id_(render_frame_id), + document_cookie_(document_cookie), + params_(std::move(params)), + is_live_(is_live) {} +PrintCompositeClient::RequestedSubFrame::~RequestedSubFrame() = default; + void PrintCompositeClient::OnDidPrintFrameContent( int render_process_id, int render_frame_id, @@ -121,8 +134,16 @@ return; } - if (!IsDocumentCookieValid(document_cookie)) + if (!IsDocumentCookieValid(document_cookie)) { + if (!compositor_) { + // Queues the subframe information to |requested_subframes_| to handle it + // after |compositor_| is created by the main frame. + requested_subframes_.insert(std::make_unique<RequestedSubFrame>( + render_process_id, render_frame_id, document_cookie, + std::move(params), true)); + } return; + } auto* render_frame_host = content::RenderFrameHost::FromID(render_process_id, render_frame_id); @@ -161,8 +182,16 @@ content::RenderFrameHost* subframe_host) { auto params = mojom::PrintFrameContentParams::New(rect, document_cookie); if (!subframe_host->IsRenderFrameLive()) { - if (!IsDocumentCookieValid(document_cookie)) + if (!IsDocumentCookieValid(document_cookie)) { + if (!compositor_) { + // Queues the subframe information to |requested_subframes_| to handle + // it after |compositor_| is created by the main frame. + requested_subframes_.insert(std::make_unique<RequestedSubFrame>( + subframe_host->GetProcess()->GetID(), subframe_host->GetRoutingID(), + document_cookie, nullptr, false)); + } return; + } // When the subframe is dead, no need to send message, // just notify the service. @@ -178,14 +207,13 @@ } // Send the request to the destination frame. - int render_process_id = subframe_host->GetProcess()->GetID(); - int render_frame_id = subframe_host->GetRoutingID(); GetPrintRenderFrame(subframe_host) ->PrintFrameContent( std::move(params), base::BindOnce(&PrintCompositeClient::OnDidPrintFrameContent, - weak_ptr_factory_.GetWeakPtr(), render_process_id, - render_frame_id)); + weak_ptr_factory_.GetWeakPtr(), + subframe_host->GetProcess()->GetID(), + subframe_host->GetRoutingID())); pending_subframes_.insert(subframe_host); } @@ -253,6 +281,23 @@ DCHECK(!GetIsDocumentConcurrentlyComposited(document_cookie)); auto* compositor = CreateCompositeRequest(document_cookie, render_frame_host); + + for (auto& requested : requested_subframes_) { + if (!IsDocumentCookieValid(requested->document_cookie_)) + continue; + if (requested->is_live_) { + OnDidPrintFrameContent( + requested->render_process_id_, requested->render_frame_id_, + requested->document_cookie_, std::move(requested->params_)); + } else { + auto* render_frame_host = content::RenderFrameHost::FromID( + requested->render_process_id_, requested->render_frame_id_); + compositor->NotifyUnavailableSubframe( + GenerateFrameGuid(render_frame_host)); + } + } + requested_subframes_.clear(); + auto region = content.metafile_data_region.Duplicate(); // Since this class owns compositor, compositor will be gone when this class
diff --git a/components/printing/browser/print_composite_client.h b/components/printing/browser/print_composite_client.h index 40ff2d3..284371d 100644 --- a/components/printing/browser/print_composite_client.h +++ b/components/printing/browser/print_composite_client.h
@@ -94,6 +94,9 @@ private: friend class content::WebContentsUserData<PrintCompositeClient>; + FRIEND_TEST_ALL_PREFIXES(PrintBrowserTest, + PrintSubframeContentBeforeCompositeClientCreation); + // Callback functions for getting the replies. static void OnDidCompositePageToPdf( mojom::PrintCompositor::CompositePageToPdfCallback callback, @@ -167,6 +170,25 @@ // Stores the printed subframes for the composited document. base::flat_set<content::RenderFrameHost*> printed_subframes_; + struct RequestedSubFrame { + RequestedSubFrame(int render_process_id, + int render_frame_id, + int document_cookie, + mojom::DidPrintContentParamsPtr params, + bool is_live); + ~RequestedSubFrame(); + RequestedSubFrame(const PrintCompositeClient::RequestedSubFrame&) = delete; + RequestedSubFrame& operator=( + const PrintCompositeClient::RequestedSubFrame&) = delete; + + int render_process_id_; + int render_frame_id_; + int document_cookie_; + mojom::DidPrintContentParamsPtr params_; + bool is_live_; + }; + base::flat_set<std::unique_ptr<RequestedSubFrame>> requested_subframes_; + std::string user_agent_; // Stores a PrintRenderFrame associated remote with the RenderFrameHost used
diff --git a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm index 5e5a39c..44a574e 100644 --- a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm +++ b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
@@ -19,10 +19,6 @@ - (BOOL)hasKeyAppearance; - (long long)_resizeDirectionForMouseLocation:(CGPoint)location; - (BOOL)_isConsideredOpenForPersistentState; - -// Available in later point releases of 10.10. On 10.11+, use the public -// -performWindowDragWithEvent: instead. -- (void)beginWindowDragWithEvent:(NSEvent*)event; @end @interface NativeWidgetMacNSWindow () <NSKeyedArchiverDelegate> @@ -47,13 +43,7 @@ if ([self.window _resizeDirectionForMouseLocation:event.locationInWindow] != -1) return; - if (@available(macOS 10.11, *)) - [self.window performWindowDragWithEvent:event]; - else if ([self.window - respondsToSelector:@selector(beginWindowDragWithEvent:)]) - [self.window beginWindowDragWithEvent:event]; - else - NOTREACHED(); + [self.window performWindowDragWithEvent:event]; } @end
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc index 9c4b1c7..cc236b1 100644 --- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc +++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
@@ -259,7 +259,7 @@ } if (is_prefetch) { - // Destroy the prefetch with FINAL_STATUS_SAFEBROSWING. + // Destroy the prefetch with FINAL_STATUS_SAFE_BROWSING. if (resource_type_ == ResourceType::kMainFrame) { url_checker_delegate_->MaybeDestroyPrerenderContents( web_contents_getter_);
diff --git a/components/scheduling_metrics/DIR_METADATA b/components/scheduling_metrics/DIR_METADATA new file mode 100644 index 0000000..7291e29 --- /dev/null +++ b/components/scheduling_metrics/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Blink>Scheduler" +}
diff --git a/components/scheduling_metrics/OWNERS b/components/scheduling_metrics/OWNERS index fff52aa..d1d314f 100644 --- a/components/scheduling_metrics/OWNERS +++ b/components/scheduling_metrics/OWNERS
@@ -10,5 +10,3 @@ # MON scheduling team fdoray@chromium.org gab@chromium.org - -# COMPONENT: Blink>Scheduler
diff --git a/components/schema_org/DIR_METADATA b/components/schema_org/DIR_METADATA new file mode 100644 index 0000000..1620260 --- /dev/null +++ b/components/schema_org/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Blink>DocumentMetadata" +} + +team_email: "media-dev@chromium.org"
diff --git a/components/schema_org/OWNERS b/components/schema_org/OWNERS index 12cb8c1..65f49a1 100644 --- a/components/schema_org/OWNERS +++ b/components/schema_org/OWNERS
@@ -1,6 +1,3 @@ beccahughes@chromium.org steimel@chromium.org sgbowen@google.com - -# COMPONENT: Blink>DocumentMetadata -# TEAM: media-dev@chromium.org
diff --git a/components/shared_highlighting/DIR_METADATA b/components/shared_highlighting/DIR_METADATA new file mode 100644 index 0000000..eafcc7d --- /dev/null +++ b/components/shared_highlighting/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "UI>Browser>SharedHighlighting" +} + +team_email: "chrome-shared-highlighting@google.com"
diff --git a/components/shared_highlighting/OWNERS b/components/shared_highlighting/OWNERS index eab70ff..0cee9a5 100644 --- a/components/shared_highlighting/OWNERS +++ b/components/shared_highlighting/OWNERS
@@ -1,5 +1,2 @@ sebsg@chromium.org seblalancette@chromium.org - -# COMPONENT: UI>Browser>SharedHighlighting -# TEAM: chrome-shared-highlighting@google.com \ No newline at end of file
diff --git a/components/signin/DIR_METADATA b/components/signin/DIR_METADATA new file mode 100644 index 0000000..4735e25f --- /dev/null +++ b/components/signin/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Services>SignIn" +} + +team_email: "chrome-signin@chromium.org"
diff --git a/components/signin/OWNERS b/components/signin/OWNERS index 26af5a6..4b57883 100644 --- a/components/signin/OWNERS +++ b/components/signin/OWNERS
@@ -6,6 +6,3 @@ # For android related change per-file *android*=aliceywang@chromium.org - -# TEAM: chrome-signin@chromium.org -# COMPONENT: Services>SignIn
diff --git a/components/signin/core/browser/signin_error_controller_unittest.cc b/components/signin/core/browser/signin_error_controller_unittest.cc index 4cf9bfc..d428880 100644 --- a/components/signin/core/browser/signin_error_controller_unittest.cc +++ b/components/signin/core/browser/signin_error_controller_unittest.cc
@@ -137,73 +137,6 @@ EXPECT_FALSE(error_controller.HasError()); } -// This test exercises behavior on signin/signout, which is not relevant on -// ChromeOS. -#if !BUILDFLAG(IS_CHROMEOS_ASH) -TEST(SigninErrorControllerTest, AccountTransitionPrimaryAccount) { - base::test::TaskEnvironment task_environment; - signin::IdentityTestEnvironment identity_test_env; - signin::PrimaryAccountMutator* primary_account_mutator = - identity_test_env.identity_manager()->GetPrimaryAccountMutator(); - - CoreAccountId test_account_id = - identity_test_env.MakeAccountAvailable(kTestEmail).account_id; - CoreAccountId other_test_account_id = - identity_test_env.MakeAccountAvailable(kOtherTestEmail).account_id; - SigninErrorController error_controller( - SigninErrorController::AccountMode::PRIMARY_ACCOUNT, - identity_test_env.identity_manager()); - ASSERT_FALSE(error_controller.HasError()); - - identity_test_env.UpdatePersistentErrorOfRefreshTokenForAccount( - test_account_id, - GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); - identity_test_env.UpdatePersistentErrorOfRefreshTokenForAccount( - other_test_account_id, - GoogleServiceAuthError(GoogleServiceAuthError::NONE)); - ASSERT_FALSE(error_controller.HasError()); // No primary account. - - // Set the primary account. - identity_test_env.SetPrimaryAccount(kOtherTestEmail); - - ASSERT_FALSE(error_controller.HasError()); // Error is on secondary. - - // Change the primary account to the account with an error and check that the - // error controller updates its error status accordingly. - primary_account_mutator->ClearPrimaryAccount( - signin::PrimaryAccountMutator::ClearAccountsAction::kKeepAll, - signin_metrics::FORCE_SIGNOUT_ALWAYS_ALLOWED_FOR_TEST, - signin_metrics::SignoutDelete::IGNORE_METRIC); - identity_test_env.SetPrimaryAccount(kTestEmail); - ASSERT_TRUE(error_controller.HasError()); - ASSERT_EQ(test_account_id, error_controller.error_account_id()); - - identity_test_env.UpdatePersistentErrorOfRefreshTokenForAccount( - other_test_account_id, - GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); - ASSERT_TRUE(error_controller.HasError()); - ASSERT_EQ(test_account_id, error_controller.error_account_id()); - - // Change the primary account again and check that the error controller - // updates its error status accordingly. - primary_account_mutator->ClearPrimaryAccount( - signin::PrimaryAccountMutator::ClearAccountsAction::kKeepAll, - signin_metrics::FORCE_SIGNOUT_ALWAYS_ALLOWED_FOR_TEST, - signin_metrics::SignoutDelete::IGNORE_METRIC); - identity_test_env.SetPrimaryAccount(kOtherTestEmail); - ASSERT_TRUE(error_controller.HasError()); - ASSERT_EQ(other_test_account_id, error_controller.error_account_id()); - - // Sign out and check that that the error controller updates its error status - // accordingly. - primary_account_mutator->ClearPrimaryAccount( - signin::PrimaryAccountMutator::ClearAccountsAction::kKeepAll, - signin_metrics::FORCE_SIGNOUT_ALWAYS_ALLOWED_FOR_TEST, - signin_metrics::SignoutDelete::IGNORE_METRIC); - ASSERT_FALSE(error_controller.HasError()); -} -#endif - // Verify that SigninErrorController handles errors properly. TEST(SigninErrorControllerTest, AuthStatusEnumerateAllErrors) { base::test::TaskEnvironment task_environment;
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc index 657c94a..d7d25cb 100644 --- a/components/signin/internal/identity_manager/primary_account_manager.cc +++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -363,6 +363,7 @@ if (HasPrimaryAccount(signin::ConsentLevel::kSync)) SetPrimaryAccountInternal(account_info, /*consented_to_sync=*/false); + DCHECK(!HasPrimaryAccount(signin::ConsentLevel::kSync)); // Revoke all tokens before sending signed_out notification, because there // may be components that don't listen for token service events when the // profile is not connected to an account.
diff --git a/components/signin/internal/identity_manager/primary_account_manager.h b/components/signin/internal/identity_manager/primary_account_manager.h index baaac24..9d502412 100644 --- a/components/signin/internal/identity_manager/primary_account_manager.h +++ b/components/signin/internal/identity_manager/primary_account_manager.h
@@ -139,6 +139,9 @@ // Signs a user out, removing the preference, erasing all keys // associated with the authenticated user, and canceling all auth in progress. // Does not remove the accounts from the token service. + // + // TODO(msarda): This method is only called from within the IdentityManager + // and from tests and should be removed. void SignOutAndKeepAllAccounts( signin_metrics::ProfileSignout signout_source_metric, signin_metrics::SignoutDelete signout_delete_metric);
diff --git a/components/signin/internal/identity_manager/primary_account_mutator_impl.cc b/components/signin/internal/identity_manager/primary_account_mutator_impl.cc index 733f5316..db1a06c 100644 --- a/components/signin/internal/identity_manager/primary_account_mutator_impl.cc +++ b/components/signin/internal/identity_manager/primary_account_mutator_impl.cc
@@ -87,10 +87,6 @@ case PrimaryAccountMutator::ClearAccountsAction::kDefault: primary_account_manager_->SignOut(source_metric, delete_metric); break; - case PrimaryAccountMutator::ClearAccountsAction::kKeepAll: - primary_account_manager_->SignOutAndKeepAllAccounts(source_metric, - delete_metric); - break; case PrimaryAccountMutator::ClearAccountsAction::kRemoveAll: primary_account_manager_->SignOutAndRemoveAllAccounts(source_metric, delete_metric);
diff --git a/components/signin/ios/DIR_METADATA b/components/signin/ios/DIR_METADATA new file mode 100644 index 0000000..5fad689 --- /dev/null +++ b/components/signin/ios/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Services>SignIn" +}
diff --git a/components/signin/ios/OWNERS b/components/signin/ios/OWNERS index 04f4beaa..6d56d2f 100644 --- a/components/signin/ios/OWNERS +++ b/components/signin/ios/OWNERS
@@ -1,5 +1,3 @@ fernandex@chromium.org jlebel@chromium.org msarda@chromium.org - -# COMPONENT: Services>SignIn
diff --git a/components/signin/public/identity_manager/primary_account_mutator.h b/components/signin/public/identity_manager/primary_account_mutator.h index feb55a4..14d0e3f 100644 --- a/components/signin/public/identity_manager/primary_account_mutator.h +++ b/components/signin/public/identity_manager/primary_account_mutator.h
@@ -33,7 +33,6 @@ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.signin.identitymanager enum class ClearAccountsAction { kDefault, // Default action based on internal policy. - kKeepAll, // Keep all accounts. kRemoveAll, // Remove all accounts. };
diff --git a/components/signin/public/identity_manager/primary_account_mutator_unittest.cc b/components/signin/public/identity_manager/primary_account_mutator_unittest.cc index 136ff2b..7eb1b5f 100644 --- a/components/signin/public/identity_manager/primary_account_mutator_unittest.cc +++ b/components/signin/public/identity_manager/primary_account_mutator_unittest.cc
@@ -437,18 +437,6 @@ other_account_info.account_id)); } -// Test that ClearPrimaryAccount(...) with ClearAccountTokensAction::kKeepAll -// keep all tokens, independently of the account consistency method. -TEST_F(PrimaryAccountMutatorTest, ClearPrimaryAccount_KeepAll) { - for (signin::AccountConsistencyMethod account_consistency_method : - kTestedAccountConsistencyMethods) { - RunClearPrimaryAccountTest( - account_consistency_method, - signin::PrimaryAccountMutator::ClearAccountsAction::kKeepAll, - RemoveAccountExpectation::kKeepAll); - } -} - // Test that ClearPrimaryAccount(...) with ClearAccountTokensAction::kRemoveAll // remove all tokens, independently of the account consistency method. TEST_F(PrimaryAccountMutatorTest, ClearPrimaryAccount_RemoveAll) {
diff --git a/components/site_isolation/DIR_METADATA b/components/site_isolation/DIR_METADATA new file mode 100644 index 0000000..1ffb19b --- /dev/null +++ b/components/site_isolation/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>Sandbox>SiteIsolation" +}
diff --git a/components/site_isolation/OWNERS b/components/site_isolation/OWNERS index ccf5c29..36c7e5a 100644 --- a/components/site_isolation/OWNERS +++ b/components/site_isolation/OWNERS
@@ -2,5 +2,3 @@ creis@chromium.org lukasza@chromium.org nasko@chromium.org - -# COMPONENT: Internals>Sandbox>SiteIsolation
diff --git a/components/soda/DIR_METADATA b/components/soda/DIR_METADATA new file mode 100644 index 0000000..6667e7f --- /dev/null +++ b/components/soda/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>Media" +}
diff --git a/components/soda/OWNERS b/components/soda/OWNERS index d21dfa0..9d6ce60 100644 --- a/components/soda/OWNERS +++ b/components/soda/OWNERS
@@ -1,4 +1,3 @@ -# COMPONENT: Internals>Media evliu@google.com beccahughes@chromium.org
diff --git a/components/spellcheck/DIR_METADATA b/components/spellcheck/DIR_METADATA new file mode 100644 index 0000000..49408cf --- /dev/null +++ b/components/spellcheck/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "UI>Browser>Spellcheck" +} + +team_email: "language@chromium.org"
diff --git a/components/spellcheck/OWNERS b/components/spellcheck/OWNERS index 3d17b34..03f054d 100644 --- a/components/spellcheck/OWNERS +++ b/components/spellcheck/OWNERS
@@ -9,6 +9,3 @@ # Android, component, refactoring timvolodine@chromium.org - -# TEAM: language@chromium.org -# COMPONENT: UI>Browser>Spellcheck
diff --git a/components/sqlite_proto/DIR_METADATA b/components/sqlite_proto/DIR_METADATA new file mode 100644 index 0000000..c9091f0 --- /dev/null +++ b/components/sqlite_proto/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>Storage" +}
diff --git a/components/sqlite_proto/OWNERS b/components/sqlite_proto/OWNERS index f8dc556..4dc72e3d 100644 --- a/components/sqlite_proto/OWNERS +++ b/components/sqlite_proto/OWNERS
@@ -1,4 +1,3 @@ -# COMPONENT: Internals>Storage pasko@chromium.org lizeb@chromium.org alexilin@chromium.org
diff --git a/components/ssl_errors/DIR_METADATA b/components/ssl_errors/DIR_METADATA new file mode 100644 index 0000000..cd27c405 --- /dev/null +++ b/components/ssl_errors/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "UI>Browser>Interstitials" +} + +team_email: "security-enamel@chromium.org"
diff --git a/components/ssl_errors/OWNERS b/components/ssl_errors/OWNERS index 62bf9b3..756eae9 100644 --- a/components/ssl_errors/OWNERS +++ b/components/ssl_errors/OWNERS
@@ -4,6 +4,3 @@ felt@chromium.org meacer@chromium.org rsleevi@chromium.org - -# TEAM: security-enamel@chromium.org -# COMPONENT: UI>Browser>Interstitials
diff --git a/components/ssl_errors_strings_grdp/DIR_METADATA b/components/ssl_errors_strings_grdp/DIR_METADATA new file mode 100644 index 0000000..b302215 --- /dev/null +++ b/components/ssl_errors_strings_grdp/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>Interstitials" +}
diff --git a/components/ssl_errors_strings_grdp/OWNERS b/components/ssl_errors_strings_grdp/OWNERS index 43af85e..877ebf5a 100644 --- a/components/ssl_errors_strings_grdp/OWNERS +++ b/components/ssl_errors_strings_grdp/OWNERS
@@ -1,2 +1 @@ file://components/ssl_errors/OWNERS -# COMPONENT: UI>Browser>Interstitials
diff --git a/components/startup_metric_utils/DIR_METADATA b/components/startup_metric_utils/DIR_METADATA new file mode 100644 index 0000000..21c44628 --- /dev/null +++ b/components/startup_metric_utils/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Internals>Metrics" +} + +team_email: "catan-team@chromium.org"
diff --git a/components/startup_metric_utils/OWNERS b/components/startup_metric_utils/OWNERS index 32d1ee3c..711005f 100644 --- a/components/startup_metric_utils/OWNERS +++ b/components/startup_metric_utils/OWNERS
@@ -2,5 +2,3 @@ # To increase bus factor but prefer above OWNERS :). gab@chromium.org -# COMPONENT: Internals>Metrics -# TEAM: catan-team@chromium.org
diff --git a/components/storage_monitor/DIR_METADATA b/components/storage_monitor/DIR_METADATA new file mode 100644 index 0000000..5b8d7cd --- /dev/null +++ b/components/storage_monitor/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Platform>Apps>FileManager" +}
diff --git a/components/storage_monitor/OWNERS b/components/storage_monitor/OWNERS index ff7f764..ed5b39e3 100644 --- a/components/storage_monitor/OWNERS +++ b/components/storage_monitor/OWNERS
@@ -1,3 +1,2 @@ thestig@chromium.org tommycli@chromium.org -# COMPONENT: Platform>Apps>FileManager
diff --git a/components/strictmode/DIR_METADATA b/components/strictmode/DIR_METADATA new file mode 100644 index 0000000..a750913 --- /dev/null +++ b/components/strictmode/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Build" +}
diff --git a/components/strictmode/OWNERS b/components/strictmode/OWNERS index 29db243..0d5a3f25 100644 --- a/components/strictmode/OWNERS +++ b/components/strictmode/OWNERS
@@ -1,3 +1 @@ file://build/config/android/OWNERS - -# COMPONENT: Build
diff --git a/components/strings/DIR_METADATA b/components/strings/DIR_METADATA new file mode 100644 index 0000000..14b5edb --- /dev/null +++ b/components/strings/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals" +}
diff --git a/components/strings/OWNERS b/components/strings/OWNERS index d41af37..2f13f5b 100644 --- a/components/strings/OWNERS +++ b/components/strings/OWNERS
@@ -3,5 +3,3 @@ # be discussed with blink-api-owners-discuss@ first or go through the # official Blink launch process. per-file components_locale_settings_*.xtb=file://third_party/blink/API_OWNERS - -# COMPONENT: Internals
diff --git a/components/subresource_filter/DIR_METADATA b/components/subresource_filter/DIR_METADATA new file mode 100644 index 0000000..352eefc --- /dev/null +++ b/components/subresource_filter/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>AdFilter" +}
diff --git a/components/subresource_filter/OWNERS b/components/subresource_filter/OWNERS index 090edda5..4284fde4 100644 --- a/components/subresource_filter/OWNERS +++ b/components/subresource_filter/OWNERS
@@ -1,4 +1,2 @@ csharrison@chromium.org jkarlin@chromium.org - -# COMPONENT: UI>Browser>AdFilter
diff --git a/components/suggestions/DIR_METADATA b/components/suggestions/DIR_METADATA new file mode 100644 index 0000000..1ee6aef --- /dev/null +++ b/components/suggestions/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "UI>Browser>NewTabPage" +} + +team_email: "ntp-dev@chromium.org"
diff --git a/components/suggestions/OWNERS b/components/suggestions/OWNERS index e3a7435..2bbc81a 100644 --- a/components/suggestions/OWNERS +++ b/components/suggestions/OWNERS
@@ -1,6 +1,3 @@ mahmadi@chromium.org tiborg@chromium.org treib@chromium.org - -# TEAM: ntp-dev@chromium.org -# COMPONENT: UI>Browser>NewTabPage
diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn index c5e534c..9eb282e 100644 --- a/components/vector_icons/BUILD.gn +++ b/components/vector_icons/BUILD.gn
@@ -46,6 +46,8 @@ "insert_drive_file_outline.icon", "launch.icon", "lightbulb_outline.icon", + "live_caption_off.icon", + "live_caption_on.icon", "location_on.icon", "lock.icon", "media_next_track.icon",
diff --git a/components/vector_icons/live_caption_off.icon b/components/vector_icons/live_caption_off.icon new file mode 100644 index 0000000..7281f9794 --- /dev/null +++ b/components/vector_icons/live_caption_off.icon
@@ -0,0 +1,56 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 3.5f, 4, +H_LINE_TO, 4, +R_LINE_TO, 2, 2, +H_LINE_TO, 4, +R_V_LINE_TO, 8, +R_H_LINE_TO, 10, +R_LINE_TO, 2, 2, +H_LINE_TO, 3.5f, +ARC_TO, 1.5f, 1.5f, 0, 0, 1, 2, 14.5f, +R_V_LINE_TO, -9, +ARC_TO, 1.5f, 1.5f, 0, 0, 1, 3.5f, 4, +CLOSE, +MOVE_TO, 9, 10, +V_LINE_TO, 9, +R_LINE_TO, 1, 1, +H_LINE_TO, 9, +CLOSE, +R_MOVE_TO, 6, -2, +R_H_LINE_TO, -4.17f, +R_LINE_TO, 2, 2, +H_LINE_TO, 15, +V_LINE_TO, 8, +CLOSE, +R_MOVE_TO, 1, -2, +R_V_LINE_TO, 7.17f, +R_LINE_TO, 1.89f, 1.89f, +R_CUBIC_TO, 0.07f, -0.17f, 0.11f, -0.36f, 0.11f, -0.56f, +R_V_LINE_TO, -9, +ARC_TO, 1.5f, 1.5f, 0, 0, 0, 16.5f, 4, +H_LINE_TO, 6.83f, +R_LINE_TO, 2, 2, +H_LINE_TO, 16, +CLOSE, +MOVE_TO, 5, 8, +R_H_LINE_TO, 3, +R_V_LINE_TO, 2, +H_LINE_TO, 5, +V_LINE_TO, 8, +CLOSE, +R_MOVE_TO, 6, 3, +R_V_LINE_TO, 2, +H_LINE_TO, 5, +R_V_LINE_TO, -2, +R_H_LINE_TO, 6, +CLOSE, +NEW_PATH, +MOVE_TO, 1, 3, +R_LINE_TO, 1.41f, -1.41f, +R_LINE_TO, 15.56f, 15.56f, +R_LINE_TO, -1.41f, 1.41f, +CLOSE
diff --git a/components/vector_icons/live_caption_on.icon b/components/vector_icons/live_caption_on.icon new file mode 100644 index 0000000..28ea861 --- /dev/null +++ b/components/vector_icons/live_caption_on.icon
@@ -0,0 +1,45 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 2, 5.5f, +ARC_TO, 1.5f, 1.5f, 0, 0, 1, 3.5f, 4, +R_H_LINE_TO, 13, +ARC_TO, 1.5f, 1.5f, 0, 0, 1, 18, 5.5f, +R_V_LINE_TO, 9, +R_ARC_TO, 1.5f, 1.5f, 0, 0, 1, -1.5f, 1.5f, +R_H_LINE_TO, -13, +ARC_TO, 1.5f, 1.5f, 0, 0, 1, 2, 14.5f, +R_V_LINE_TO, -9, +CLOSE, +MOVE_TO, 4, 6, +R_H_LINE_TO, 12, +R_V_LINE_TO, 8, +H_LINE_TO, 4, +V_LINE_TO, 6, +CLOSE, +R_MOVE_TO, 1, 2, +R_H_LINE_TO, 4, +R_V_LINE_TO, 2, +H_LINE_TO, 5, +V_LINE_TO, 8, +CLOSE, +R_MOVE_TO, 0, 3, +R_H_LINE_TO, 7, +R_V_LINE_TO, 2, +H_LINE_TO, 5, +R_V_LINE_TO, -2, +CLOSE, +R_MOVE_TO, 10, 0, +R_H_LINE_TO, -2, +R_V_LINE_TO, 2, +R_H_LINE_TO, 2, +R_V_LINE_TO, -2, +CLOSE, +R_MOVE_TO, -5, -3, +R_H_LINE_TO, 5, +R_V_LINE_TO, 2, +R_H_LINE_TO, -5, +V_LINE_TO, 8, +CLOSE
diff --git a/components/viz/DIR_METADATA b/components/viz/DIR_METADATA new file mode 100644 index 0000000..f7e4412 --- /dev/null +++ b/components/viz/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Internals>Compositing" +} + +team_email: "graphics-dev@chromium.org"
diff --git a/components/viz/OWNERS b/components/viz/OWNERS index b9559dfa..13c6cfe 100644 --- a/components/viz/OWNERS +++ b/components/viz/OWNERS
@@ -54,6 +54,3 @@ danakj@chromium.org vmpstr@chromium.org kylechar@chromium.org - -# TEAM: graphics-dev@chromium.org -# COMPONENT: Internals>Compositing
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index 55a38b9d..8190ffb 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -196,6 +196,8 @@ "quads/compositor_frame.h", "quads/compositor_frame_metadata.cc", "quads/compositor_frame_metadata.h", + "quads/compositor_frame_transition_directive.cc", + "quads/compositor_frame_transition_directive.h", "quads/compositor_render_pass.cc", "quads/compositor_render_pass.h", "quads/compositor_render_pass_draw_quad.cc", @@ -353,6 +355,7 @@ "frame_sinks/copy_output_util_unittest.cc", "frame_sinks/delay_based_time_source_unittest.cc", "gpu/context_cache_controller_unittest.cc", + "quads/compositor_frame_transition_directive_unittest.cc", "quads/compositor_render_pass_unittest.cc", "quads/draw_quad_unittest.cc", "quads/render_pass_io_unittest.cc",
diff --git a/components/viz/common/gpu/metal_api_proxy.h b/components/viz/common/gpu/metal_api_proxy.h index c32a55c..7d717a2 100644 --- a/components/viz/common/gpu/metal_api_proxy.h +++ b/components/viz/common/gpu/metal_api_proxy.h
@@ -9,7 +9,6 @@ #include <string> #import <Metal/Metal.h> -#include <os/availability.h> #include "base/mac/scoped_nsobject.h" @@ -17,12 +16,11 @@ class ProgressReporter; } // namespace gl -class API_AVAILABLE(macos(10.11)) MTLLibraryCache; +class MTLLibraryCache; // The MTLDeviceProxy wraps all calls to an MTLDevice. It reports progress // to the GPU watchdog to prevent the watchdog from killing the GPU process // when progress is being made. -API_AVAILABLE(macos(10.11)) @interface MTLDeviceProxy : NSObject <MTLDevice> { base::scoped_nsprotocol<id<MTLDevice>> _device;
diff --git a/components/viz/common/gpu/metal_api_proxy.mm b/components/viz/common/gpu/metal_api_proxy.mm index a6df2c7..e8e73a18 100644 --- a/components/viz/common/gpu/metal_api_proxy.mm +++ b/components/viz/common/gpu/metal_api_proxy.mm
@@ -29,8 +29,7 @@ // newRenderPipelineStateWithDescriptor:]. The completion handler may be called // on another thread, so all members are protected by a lock. Accessed via // scoped_refptr to ensure that it exists until its last accessor is gone. -class API_AVAILABLE(macos(10.11)) AsyncMetalState - : public base::RefCountedThreadSafe<AsyncMetalState> { +class AsyncMetalState : public base::RefCountedThreadSafe<AsyncMetalState> { public: AsyncMetalState() : condition_variable(&lock) {} @@ -52,12 +51,11 @@ ~AsyncMetalState() { DCHECK(has_result); } }; -id<MTLLibrary> API_AVAILABLE(macos(10.11)) - NewLibraryWithRetry(id<MTLDevice> device, - NSString* source, - MTLCompileOptions* options, - __autoreleasing NSError** error, - gl::ProgressReporter* progress_reporter) { +id<MTLLibrary> NewLibraryWithRetry(id<MTLDevice> device, + NSString* source, + MTLCompileOptions* options, + __autoreleasing NSError** error, + gl::ProgressReporter* progress_reporter) { SCOPED_UMA_HISTOGRAM_TIMER("Gpu.MetalProxy.NewLibraryTime"); const base::TimeTicks start_time = base::TimeTicks::Now(); auto state = base::MakeRefCounted<AsyncMetalState>(); @@ -99,11 +97,11 @@ } } -id<MTLRenderPipelineState> API_AVAILABLE(macos(10.11)) - NewRenderPipelineStateWithRetry(id<MTLDevice> device, - MTLRenderPipelineDescriptor* descriptor, - __autoreleasing NSError** error, - gl::ProgressReporter* progress_reporter) { +id<MTLRenderPipelineState> NewRenderPipelineStateWithRetry( + id<MTLDevice> device, + MTLRenderPipelineDescriptor* descriptor, + __autoreleasing NSError** error, + gl::ProgressReporter* progress_reporter) { // This function is almost-identical to the above NewLibraryWithRetry. See // comments in that function. SCOPED_UMA_HISTOGRAM_TIMER("Gpu.MetalProxy.NewRenderPipelineStateTime"); @@ -147,7 +145,7 @@ // to hangs. Should this significantly help the situation, a more robust (and // not indefinitely-growing) cache will be added either here or in Skia. // https://crbug.com/974219 -class API_AVAILABLE(macos(10.11)) MTLLibraryCache { +class MTLLibraryCache { public: MTLLibraryCache() = default; ~MTLLibraryCache() = default;
diff --git a/components/viz/common/gpu/metal_context_provider.mm b/components/viz/common/gpu/metal_context_provider.mm index f5a0bacb..5ffc304 100644 --- a/components/viz/common/gpu/metal_context_provider.mm +++ b/components/viz/common/gpu/metal_context_provider.mm
@@ -23,8 +23,7 @@ namespace { -struct API_AVAILABLE(macos(10.11)) MetalContextProviderImpl - : public MetalContextProvider { +struct MetalContextProviderImpl : public MetalContextProvider { public: explicit MetalContextProviderImpl(id<MTLDevice> device, const GrContextOptions& context_options) { @@ -59,20 +58,15 @@ // static std::unique_ptr<MetalContextProvider> MetalContextProvider::Create( const GrContextOptions& context_options) { - if (@available(macOS 10.11, *)) { - // First attempt to find a low power device to use. - base::scoped_nsprotocol<id<MTLDevice>> device_to_use( - metal::CreateDefaultDevice()); - if (!device_to_use) { - DLOG(ERROR) << "Failed to find MTLDevice."; - return nullptr; - } - return std::make_unique<MetalContextProviderImpl>(device_to_use.get(), - context_options); + // First attempt to find a low power device to use. + base::scoped_nsprotocol<id<MTLDevice>> device_to_use( + metal::CreateDefaultDevice()); + if (!device_to_use) { + DLOG(ERROR) << "Failed to find MTLDevice."; + return nullptr; } - // If no device was found, or if the macOS version is too old for Metal, - // return no context provider. - return nullptr; + return std::make_unique<MetalContextProviderImpl>(device_to_use.get(), + context_options); } } // namespace viz
diff --git a/components/viz/common/quads/compositor_frame_transition_directive.cc b/components/viz/common/quads/compositor_frame_transition_directive.cc new file mode 100644 index 0000000..4fcf676b --- /dev/null +++ b/components/viz/common/quads/compositor_frame_transition_directive.cc
@@ -0,0 +1,25 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/viz/common/quads/compositor_frame_transition_directive.h" + +#include "base/time/time.h" + +namespace viz { + +constexpr base::TimeDelta CompositorFrameTransitionDirective::kMaxDuration; + +CompositorFrameTransitionDirective::CompositorFrameTransitionDirective( + uint32_t sequence_id, + Type type, + Effect effect, + base::TimeDelta duration) + : sequence_id_(sequence_id), + type_(type), + effect_(effect), + duration_(duration) { + DCHECK_LE(duration_, kMaxDuration); +} + +} // namespace viz
diff --git a/components/viz/common/quads/compositor_frame_transition_directive.h b/components/viz/common/quads/compositor_frame_transition_directive.h new file mode 100644 index 0000000..26a7311 --- /dev/null +++ b/components/viz/common/quads/compositor_frame_transition_directive.h
@@ -0,0 +1,82 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_VIZ_COMMON_QUADS_COMPOSITOR_FRAME_TRANSITION_DIRECTIVE_H_ +#define COMPONENTS_VIZ_COMMON_QUADS_COMPOSITOR_FRAME_TRANSITION_DIRECTIVE_H_ + +#include "base/time/time.h" +#include "components/viz/common/viz_common_export.h" + +namespace viz { + +// This is a transition directive that can be associcated with a compositor +// frame. The intent is to be able to animate a compositor frame into the right +// place instead of simply drawing the final result at the final destination. +// This is used by a JavaScript-exposed document transitions API. See +// third_party/blink/renderer/core/document_transition/README.md for more +// information. +class VIZ_COMMON_EXPORT CompositorFrameTransitionDirective { + public: + // What is the directive? + // - Save means that the currently submitted frame will be used in the future + // as the source frame of the animation. + // - Animate means that this frame should be used as a (new) destination frame + // of the animation, using the previously saved frame as the source. + enum class Type { kSave, kAnimate }; + + // The type of an effect that should be used in the animation. + enum class Effect { + kNone, + kCoverDown, + kCoverLeft, + kCoverRight, + kCoverUp, + kExplode, + kFade, + kImplode, + kRevealDown, + kRevealLeft, + kRevealRight, + kRevealUp + }; + + // This is the maximum allowable transition duration. + static constexpr base::TimeDelta kMaxDuration = + base::TimeDelta::FromMilliseconds(500); + + // Constructs a new directive. Note that if type is `kSave`, the effect and + // duration should be specified for a desired effect. These are ignored for + // the `kAnimate` type. + CompositorFrameTransitionDirective(uint32_t sequence_id, + Type type, + Effect effect = Effect::kNone, + base::TimeDelta duration = {}); + + // A monotonically increasing sequence_id for a given communication channel + // (i.e. surface). This is used to distinguish new directives from directives + // that have already been processed. + uint32_t sequence_id() const { return sequence_id_; } + + // The type of this directive. + Type type() const { return type_; } + + // The duration of the animation. Note that this is at most kMaxDuration. + base::TimeDelta duration() const { return duration_; } + + // The effect for the transition. + Effect effect() const { return effect_; } + + private: + uint32_t sequence_id_; + + Type type_; + + Effect effect_; + + base::TimeDelta duration_; +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_COMMON_QUADS_COMPOSITOR_FRAME_TRANSITION_DIRECTIVE_H_
diff --git a/components/viz/common/quads/compositor_frame_transition_directive_unittest.cc b/components/viz/common/quads/compositor_frame_transition_directive_unittest.cc new file mode 100644 index 0000000..1df5f7bd --- /dev/null +++ b/components/viz/common/quads/compositor_frame_transition_directive_unittest.cc
@@ -0,0 +1,32 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/viz/common/quads/compositor_frame_transition_directive.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace viz { +namespace { + +using Effect = CompositorFrameTransitionDirective::Effect; +using Type = CompositorFrameTransitionDirective::Type; + +TEST(CompositorFrameTransitionDirective, GettersReflectParameters) { + CompositorFrameTransitionDirective save_directive( + 1u, Type::kSave, Effect::kCoverLeft, + base::TimeDelta::FromMilliseconds(100)); + + EXPECT_EQ(1u, save_directive.sequence_id()); + EXPECT_EQ(Type::kSave, save_directive.type()); + EXPECT_EQ(Effect::kCoverLeft, save_directive.effect()); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(100), save_directive.duration()); + + CompositorFrameTransitionDirective animate_directive(2, Type::kAnimate); + + EXPECT_EQ(2u, animate_directive.sequence_id()); + EXPECT_EQ(Type::kAnimate, animate_directive.type()); +} + +} // namespace +} // namespace viz
diff --git a/components/viz/common/resources/resource_format_utils_mac.mm b/components/viz/common/resources/resource_format_utils_mac.mm index 5a095e7..41091d71 100644 --- a/components/viz/common/resources/resource_format_utils_mac.mm +++ b/components/viz/common/resources/resource_format_utils_mac.mm
@@ -11,30 +11,27 @@ namespace viz { unsigned int ToMTLPixelFormat(ResourceFormat format) { - if (@available(macOS 10.11, *)) { - MTLPixelFormat mtl_pixel_format = MTLPixelFormatInvalid; - switch (format) { - case RED_8: - case ALPHA_8: - case LUMINANCE_8: - mtl_pixel_format = MTLPixelFormatR8Unorm; - break; - case RG_88: - mtl_pixel_format = MTLPixelFormatRG8Unorm; - break; - case RGBA_8888: - mtl_pixel_format = MTLPixelFormatRGBA8Unorm; - break; - case BGRA_8888: - mtl_pixel_format = MTLPixelFormatBGRA8Unorm; - break; - default: - DLOG(ERROR) << "Invalid Metal pixel format."; - break; - } - return static_cast<unsigned int>(mtl_pixel_format); + MTLPixelFormat mtl_pixel_format = MTLPixelFormatInvalid; + switch (format) { + case RED_8: + case ALPHA_8: + case LUMINANCE_8: + mtl_pixel_format = MTLPixelFormatR8Unorm; + break; + case RG_88: + mtl_pixel_format = MTLPixelFormatRG8Unorm; + break; + case RGBA_8888: + mtl_pixel_format = MTLPixelFormatRGBA8Unorm; + break; + case BGRA_8888: + mtl_pixel_format = MTLPixelFormatBGRA8Unorm; + break; + default: + DLOG(ERROR) << "Invalid Metal pixel format."; + break; } - return 0; + return static_cast<unsigned int>(mtl_pixel_format); } } // namespace viz
diff --git a/components/viz/service/frame_sinks/video_capture/DIR_METADATA b/components/viz/service/frame_sinks/video_capture/DIR_METADATA new file mode 100644 index 0000000..d0f2f68a --- /dev/null +++ b/components/viz/service/frame_sinks/video_capture/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>Media>ScreenCapture" +}
diff --git a/components/viz/service/frame_sinks/video_capture/OWNERS b/components/viz/service/frame_sinks/video_capture/OWNERS index 12fd84a..90320c9 100644 --- a/components/viz/service/frame_sinks/video_capture/OWNERS +++ b/components/viz/service/frame_sinks/video_capture/OWNERS
@@ -1,4 +1,2 @@ miu@chromium.org mfoltz@chromium.org - -# COMPONENT: Internals>Media>ScreenCapture
diff --git a/components/viz/service/gl/DIR_METADATA b/components/viz/service/gl/DIR_METADATA new file mode 100644 index 0000000..d7359ed --- /dev/null +++ b/components/viz/service/gl/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>GPU>Internals" +}
diff --git a/components/viz/service/gl/OWNERS b/components/viz/service/gl/OWNERS index 2a2fdb63..f18fedb 100644 --- a/components/viz/service/gl/OWNERS +++ b/components/viz/service/gl/OWNERS
@@ -1,4 +1,2 @@ kbr@chromium.org file://gpu/OWNERS - -# COMPONENT: Internals>GPU>Internals
diff --git a/components/web_cache/DIR_METADATA b/components/web_cache/DIR_METADATA new file mode 100644 index 0000000..14b5edb --- /dev/null +++ b/components/web_cache/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals" +}
diff --git a/components/web_cache/OWNERS b/components/web_cache/OWNERS index e8a333cd..3463baf5 100644 --- a/components/web_cache/OWNERS +++ b/components/web_cache/OWNERS
@@ -3,4 +3,3 @@ sky@chromium.org thakis@chromium.org thestig@chromium.org -# COMPONENT: Internals
diff --git a/components/web_modal/DIR_METADATA b/components/web_modal/DIR_METADATA new file mode 100644 index 0000000..69976b6 --- /dev/null +++ b/components/web_modal/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>Core" +}
diff --git a/components/web_modal/OWNERS b/components/web_modal/OWNERS index f8ca2ec..12a9b09 100644 --- a/components/web_modal/OWNERS +++ b/components/web_modal/OWNERS
@@ -1,2 +1 @@ wittman@chromium.org -# COMPONENT: UI>Browser>Core
diff --git a/components/web_package/DIR_METADATA b/components/web_package/DIR_METADATA new file mode 100644 index 0000000..2352b85e --- /dev/null +++ b/components/web_package/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Blink>Loader>WebPackaging" +} + +team_email: "webpackage-dev@chromium.org"
diff --git a/components/web_package/OWNERS b/components/web_package/OWNERS index 25537e1..0addbbd1 100644 --- a/components/web_package/OWNERS +++ b/components/web_package/OWNERS
@@ -1,6 +1,3 @@ horo@chromium.org kinuko@chromium.org ksakamoto@chromium.org - -# COMPONENT: Blink>Loader>WebPackaging -# TEAM: webpackage-dev@chromium.org
diff --git a/components/web_resource/DIR_METADATA b/components/web_resource/DIR_METADATA new file mode 100644 index 0000000..d08126ac --- /dev/null +++ b/components/web_resource/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Shell" +}
diff --git a/components/web_resource/OWNERS b/components/web_resource/OWNERS index d029a52..d0a6461 100644 --- a/components/web_resource/OWNERS +++ b/components/web_resource/OWNERS
@@ -4,4 +4,3 @@ # For ResourceRequestAllowedNotifier and EulaAcceptedNotifier: per-file eula_accepted_notifier*=file://components/variations/OWNERS per-file resource_request_allowed_notifier*=file://components/variations/OWNERS -# COMPONENT: UI>Shell
diff --git a/components/webapk/DIR_METADATA b/components/webapk/DIR_METADATA new file mode 100644 index 0000000..1a508bb4 --- /dev/null +++ b/components/webapk/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Mobile>WebAPKs" +} + +team_email: "webapk-team@chromium.org"
diff --git a/components/webapk/OWNERS b/components/webapk/OWNERS index 195458c..b7e271d 100644 --- a/components/webapk/OWNERS +++ b/components/webapk/OWNERS
@@ -1,6 +1,3 @@ hanxi@chromium.org pkotwicz@chromium.org yfriedman@chromium.org - -# TEAM: webapk-team@chromium.org -# COMPONENT: Mobile>WebAPKs
diff --git a/components/webcrypto/DIR_METADATA b/components/webcrypto/DIR_METADATA new file mode 100644 index 0000000..86d9592 --- /dev/null +++ b/components/webcrypto/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Blink>WebCrypto" +}
diff --git a/components/webcrypto/OWNERS b/components/webcrypto/OWNERS index 36ea0ea..81033345 100644 --- a/components/webcrypto/OWNERS +++ b/components/webcrypto/OWNERS
@@ -1,3 +1 @@ rsleevi@chromium.org - -# COMPONENT: Blink>WebCrypto
diff --git a/components/webdata/DIR_METADATA b/components/webdata/DIR_METADATA new file mode 100644 index 0000000..d9fe49da --- /dev/null +++ b/components/webdata/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Internals" +} + +team_email: "chromium-reviews@chromium.org"
diff --git a/components/webdata/OWNERS b/components/webdata/OWNERS index 7aa99e6..1310ba4c 100644 --- a/components/webdata/OWNERS +++ b/components/webdata/OWNERS
@@ -3,6 +3,3 @@ # For sqlite stuff: pwnall@chromium.org - -# COMPONENT: Internals -# TEAM: chromium-reviews@chromium.org
diff --git a/components/webdata_services/DIR_METADATA b/components/webdata_services/DIR_METADATA new file mode 100644 index 0000000..d9fe49da --- /dev/null +++ b/components/webdata_services/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Internals" +} + +team_email: "chromium-reviews@chromium.org"
diff --git a/components/webdata_services/OWNERS b/components/webdata_services/OWNERS index 7aa99e6..1310ba4c 100644 --- a/components/webdata_services/OWNERS +++ b/components/webdata_services/OWNERS
@@ -3,6 +3,3 @@ # For sqlite stuff: pwnall@chromium.org - -# COMPONENT: Internals -# TEAM: chromium-reviews@chromium.org
diff --git a/components/webrtc/DIR_METADATA b/components/webrtc/DIR_METADATA new file mode 100644 index 0000000..66cc019 --- /dev/null +++ b/components/webrtc/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Blink>WebRTC" +}
diff --git a/components/webrtc/OWNERS b/components/webrtc/OWNERS index 48b19446..a129378 100644 --- a/components/webrtc/OWNERS +++ b/components/webrtc/OWNERS
@@ -1,3 +1 @@ file://third_party/blink/public/platform/modules/webrtc/OWNERS - -# COMPONENT: Blink>WebRTC
diff --git a/components/webrtc_logging/DIR_METADATA b/components/webrtc_logging/DIR_METADATA new file mode 100644 index 0000000..44125f6 --- /dev/null +++ b/components/webrtc_logging/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Blink>WebRTC>Tools" +} + +team_email: "webrtc-dev@chromium.org"
diff --git a/components/webrtc_logging/OWNERS b/components/webrtc_logging/OWNERS index 2046f22..b88212c 100644 --- a/components/webrtc_logging/OWNERS +++ b/components/webrtc_logging/OWNERS
@@ -1,5 +1,2 @@ grunell@chromium.org tommi@chromium.org - -# COMPONENT: Blink>WebRTC>Tools -# TEAM: webrtc-dev@chromium.org
diff --git a/components/webxr/DIR_METADATA b/components/webxr/DIR_METADATA new file mode 100644 index 0000000..743074be --- /dev/null +++ b/components/webxr/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Internals>XR" +} + +team_email: "xr-dev@chromium.org"
diff --git a/components/webxr/OWNERS b/components/webxr/OWNERS index ef5e626..2310121 100644 --- a/components/webxr/OWNERS +++ b/components/webxr/OWNERS
@@ -1,5 +1,2 @@ alcooper@chromium.org bialpio@chromium.org - -# TEAM: xr-dev@chromium.org -# COMPONENT: Internals>XR
diff --git a/components/webxr_strings_grdp/DIR_METADATA b/components/webxr_strings_grdp/DIR_METADATA new file mode 100644 index 0000000..d62bf7a --- /dev/null +++ b/components/webxr_strings_grdp/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>XR" +}
diff --git a/components/webxr_strings_grdp/OWNERS b/components/webxr_strings_grdp/OWNERS index 8c91bd7..d95d28c 100644 --- a/components/webxr_strings_grdp/OWNERS +++ b/components/webxr_strings_grdp/OWNERS
@@ -1,2 +1 @@ file://components/webxr/OWNERS -# COMPONENT: Internals>XR
diff --git a/components/wifi/DIR_METADATA b/components/wifi/DIR_METADATA new file mode 100644 index 0000000..709d8280 --- /dev/null +++ b/components/wifi/DIR_METADATA
@@ -0,0 +1,5 @@ +monorail { + component: "Internals>Network" +} + +team_email: "net-dev@chromium.org"
diff --git a/components/wifi/OWNERS b/components/wifi/OWNERS index 7e5ec6e..fb59c70 100644 --- a/components/wifi/OWNERS +++ b/components/wifi/OWNERS
@@ -1,3 +1 @@ file://net/OWNERS -# COMPONENT: Internals>Network -# TEAM: net-dev@chromium.org
diff --git a/components/zoom/DIR_METADATA b/components/zoom/DIR_METADATA new file mode 100644 index 0000000..3ad212d --- /dev/null +++ b/components/zoom/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>Zoom" +}
diff --git a/components/zoom/OWNERS b/components/zoom/OWNERS index fd016d7..9e07757 100644 --- a/components/zoom/OWNERS +++ b/components/zoom/OWNERS
@@ -1,3 +1 @@ wjmaclean@chromium.org - -# COMPONENT: UI>Browser>Zoom
diff --git a/components/zucchini/DIR_METADATA b/components/zucchini/DIR_METADATA new file mode 100644 index 0000000..03fc466 --- /dev/null +++ b/components/zucchini/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>Installer>Diff" +}
diff --git a/components/zucchini/OWNERS b/components/zucchini/OWNERS index 06b665e4..1eb740b 100644 --- a/components/zucchini/OWNERS +++ b/components/zucchini/OWNERS
@@ -2,5 +2,3 @@ huangs@chromium.org grt@chromium.org wfh@chromium.org - -# COMPONENT: Internals>Installer>Diff
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index aa611448..c0823fa 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -170,6 +170,10 @@ #include "content/common/android/cpu_affinity.h" #endif +#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) +#include "base/allocator/partition_allocator/thread_cache.h" +#endif + namespace content { extern int GpuMain(const content::MainFunctionParams&); #if BUILDFLAG(ENABLE_PLUGINS) @@ -1009,6 +1013,10 @@ // Enable PCScan once we are certain that FeatureList was initialized. EnablePCScanForMallocPartitionsIfNeeded(); +#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + base::internal::ThreadCacheRegistry::Instance().StartPeriodicPurge(); +#endif + if (should_start_minimal_browser) { DVLOG(0) << "Chrome is running in minimal browser mode."; return -1;
diff --git a/content/browser/file_system_access/file_system_chooser.cc b/content/browser/file_system_access/file_system_chooser.cc index 95dbf69..41f7297 100644 --- a/content/browser/file_system_access/file_system_chooser.cc +++ b/content/browser/file_system_access/file_system_chooser.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/i18n/file_util_icu.h" #include "base/metrics/histogram_functions.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" @@ -47,6 +48,51 @@ "NativeFileSystemAPI.FileChooserResult." + TypeToString(type), count); } +// Similar to base::FilePath::FinalExtension, but operates with the +// understanding that the StringType passed in is an extension, not a path. +// Returns the last extension without a leading ".". +base::FilePath::StringType GetLastExtension( + const base::FilePath::StringType& extension) { + auto last_separator = extension.rfind(base::FilePath::kExtensionSeparator); + return (last_separator != base::FilePath::StringType::npos) + ? extension.substr(last_separator + 1) + : extension; +} + +// Returns whether the specified extension receives special handling by the +// Windows shell. +bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) { + // TODO(https://crbug.com/1154757): Figure out some way to unify this with + // net::IsSafePortablePathComponent, with the result probably ending up in + // base/i18n/file_util_icu.h. + base::FilePath::StringType extension_lower = base::ToLowerASCII(extension); + + // .lnk files may be used to execute arbitrary code (see + // https://nvd.nist.gov/vuln/detail/CVE-2010-2568). .local files are used by + // Windows to determine which DLLs to load for an application. + if ((extension_lower == FILE_PATH_LITERAL("local")) || + (extension_lower == FILE_PATH_LITERAL("lnk"))) + return true; + + // Setting a file's extension to a CLSID may conceal its actual file type on + // some Windows versions (see https://nvd.nist.gov/vuln/detail/CVE-2004-0420). + if (!extension_lower.empty() && + (extension_lower.front() == FILE_PATH_LITERAL('{')) && + (extension_lower.back() == FILE_PATH_LITERAL('}'))) + return true; + return false; +} + +// Extension validation primarily takes place in the renderer. This checks for a +// subset of invalid extensions in the event the renderer is compromised. +bool IsInvalidExtension(base::FilePath::StringType& extension) { + std::string component8 = base::FilePath(extension).AsUTF8Unsafe(); + auto extension16 = base::UTF8ToUTF16(component8.c_str()); + + return !base::i18n::IsFilenameLegal(extension16) || + IsShellIntegratedExtension(GetLastExtension(extension)); +} + // Converts the accepted mime types and extensions from |option| into a list // of just extensions to be passed to the file dialog implementation. // The returned list will start with all the explicit website provided @@ -67,7 +113,8 @@ #else extension = extension_string; #endif - if (extension_set.insert(extension).second) { + if (extension_set.insert(extension).second && + !IsInvalidExtension(extension)) { extensions->push_back(std::move(extension)); } } @@ -76,7 +123,8 @@ base::FilePath::StringType preferred_extension; if (net::GetPreferredExtensionForMimeType(mime_type, &preferred_extension)) { - if (extension_set.insert(preferred_extension).second) { + if (extension_set.insert(preferred_extension).second && + !IsInvalidExtension(preferred_extension)) { extensions->push_back(std::move(preferred_extension)); } } @@ -86,7 +134,8 @@ if (inner.empty()) continue; for (auto& extension : inner) { - if (extension_set.insert(extension).second) { + if (extension_set.insert(extension).second && + !IsInvalidExtension(extension)) { extensions->push_back(std::move(extension)); } }
diff --git a/content/browser/file_system_access/file_system_chooser_browsertest.cc b/content/browser/file_system_access/file_system_chooser_browsertest.cc index 7aaf0f65..8d35646 100644 --- a/content/browser/file_system_access/file_system_chooser_browsertest.cc +++ b/content/browser/file_system_access/file_system_chooser_browsertest.cc
@@ -37,6 +37,8 @@ using blink::mojom::PermissionStatus; using SensitiveDirectoryResult = NativeFileSystemPermissionContext::SensitiveDirectoryResult; +using PathInfo = NativeFileSystemPermissionContext::PathInfo; +using PathType = NativeFileSystemPermissionContext::PathType; static constexpr char kTestMountPoint[] = "testfs"; @@ -484,20 +486,17 @@ .WillOnce(testing::Return(true)); EXPECT_CALL(permission_context, GetLastPickedDirectory(origin)) - .WillOnce(testing::Return(NativeFileSystemPermissionContext::PathInfo())); + .WillOnce(testing::Return(PathInfo())); EXPECT_CALL(permission_context, GetDefaultDirectory()) - .WillOnce(testing::Return(NativeFileSystemPermissionContext::PathInfo())); + .WillOnce(testing::Return(PathInfo())); EXPECT_CALL(permission_context, - SetLastPickedDirectory( - origin, test_dir, - NativeFileSystemPermissionContext::PathType::kLocal)); + SetLastPickedDirectory(origin, test_dir, PathType::kLocal)); - EXPECT_CALL( - permission_context, - ConfirmSensitiveDirectoryAccess_( - origin, NativeFileSystemPermissionContext::PathType::kLocal, test_dir, - NativeFileSystemPermissionContext::HandleType::kDirectory, frame_id, - testing::_)) + EXPECT_CALL(permission_context, + ConfirmSensitiveDirectoryAccess_( + origin, PathType::kLocal, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + frame_id, testing::_)) .WillOnce(RunOnceCallback<5>(SensitiveDirectoryResult::kAllowed)); EXPECT_CALL(permission_context, @@ -560,16 +559,15 @@ .WillOnce(testing::Return(true)); EXPECT_CALL(permission_context, GetLastPickedDirectory(origin)) - .WillOnce(testing::Return(NativeFileSystemPermissionContext::PathInfo())); + .WillOnce(testing::Return(PathInfo())); EXPECT_CALL(permission_context, GetDefaultDirectory()) - .WillOnce(testing::Return(NativeFileSystemPermissionContext::PathInfo())); + .WillOnce(testing::Return(PathInfo())); - EXPECT_CALL( - permission_context, - ConfirmSensitiveDirectoryAccess_( - origin, NativeFileSystemPermissionContext::PathType::kLocal, - test_file, NativeFileSystemPermissionContext::HandleType::kFile, - frame_id, testing::_)) + EXPECT_CALL(permission_context, + ConfirmSensitiveDirectoryAccess_( + origin, PathType::kLocal, test_file, + NativeFileSystemPermissionContext::HandleType::kFile, + frame_id, testing::_)) .WillOnce(RunOnceCallback<5>(SensitiveDirectoryResult::kAbort)); ASSERT_TRUE( @@ -621,16 +619,15 @@ .WillOnce(testing::Return(true)); EXPECT_CALL(permission_context, GetLastPickedDirectory(origin)) - .WillOnce(testing::Return(NativeFileSystemPermissionContext::PathInfo())); + .WillOnce(testing::Return(PathInfo())); EXPECT_CALL(permission_context, GetDefaultDirectory()) - .WillOnce(testing::Return(NativeFileSystemPermissionContext::PathInfo())); + .WillOnce(testing::Return(PathInfo())); - EXPECT_CALL( - permission_context, - ConfirmSensitiveDirectoryAccess_( - origin, NativeFileSystemPermissionContext::PathType::kLocal, - test_file, NativeFileSystemPermissionContext::HandleType::kFile, - frame_id, testing::_)) + EXPECT_CALL(permission_context, + ConfirmSensitiveDirectoryAccess_( + origin, PathType::kLocal, test_file, + NativeFileSystemPermissionContext::HandleType::kFile, + frame_id, testing::_)) .WillOnce(RunOnceCallback<5>(SensitiveDirectoryResult::kAbort)); ASSERT_TRUE( @@ -707,4 +704,341 @@ "NativeFileSystem")); } +IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, + OpenDirectory_LastPickedDirExists) { + base::FilePath test_dir = CreateTestDir(); + + SelectFileDialogParams dialog_params; + ui::SelectFileDialog::SetFactory( + new FakeSelectFileDialogFactory({test_dir}, &dialog_params)); + + testing::StrictMock<MockNativeFileSystemPermissionContext> permission_context; + static_cast<NativeFileSystemManagerImpl*>( + BrowserContext::GetStoragePartition( + shell()->web_contents()->GetBrowserContext(), + shell()->web_contents()->GetSiteInstance()) + ->GetNativeFileSystemEntryFactory()) + ->SetPermissionContextForTesting(&permission_context); + + auto read_grant = base::MakeRefCounted< + testing::StrictMock<MockNativeFileSystemPermissionGrant>>(); + auto write_grant = base::MakeRefCounted<FixedNativeFileSystemPermissionGrant>( + PermissionStatus::GRANTED, base::FilePath()); + + auto origin = + url::Origin::Create(embedded_test_server()->GetURL("/title1.html")); + auto frame_id = GlobalFrameRoutingId( + shell()->web_contents()->GetMainFrame()->GetProcess()->GetID(), + shell()->web_contents()->GetMainFrame()->GetRoutingID()); + EXPECT_CALL(permission_context, CanObtainReadPermission(origin)) + .WillOnce(testing::Return(true)); + + // The last picked directory exists, so do not call GetDefaultDirectory. + PathInfo good_dir_info; + good_dir_info.path = temp_dir_.GetPath(); + + EXPECT_CALL(permission_context, GetLastPickedDirectory(origin)) + .WillOnce(testing::Return(good_dir_info)); + EXPECT_CALL(permission_context, + SetLastPickedDirectory(origin, test_dir, PathType::kLocal)); + + EXPECT_CALL(permission_context, + ConfirmSensitiveDirectoryAccess_( + origin, PathType::kLocal, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + frame_id, testing::_)) + .WillOnce(RunOnceCallback<5>(SensitiveDirectoryResult::kAllowed)); + + EXPECT_CALL(permission_context, + GetReadPermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(read_grant)); + EXPECT_CALL(permission_context, + GetWritePermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(write_grant)); + + EXPECT_CALL( + *read_grant, + RequestPermission_( + frame_id, + NativeFileSystemPermissionGrant::UserActivationState::kNotRequired, + testing::_)) + .WillOnce(RunOnceCallback<2>(NativeFileSystemPermissionGrant:: + PermissionRequestOutcome::kUserGranted)); + EXPECT_CALL(*read_grant, GetStatus()) + .WillRepeatedly(testing::Return(PermissionStatus::GRANTED)); + + ASSERT_TRUE( + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"))); + EXPECT_EQ(test_dir.BaseName().AsUTF8Unsafe(), + EvalJs(shell(), + "(async () => {" + " let e = await self.showDirectoryPicker();" + " self.selected_entry = e;" + " return e.name; })()")); + EXPECT_EQ(ui::SelectFileDialog::SELECT_FOLDER, dialog_params.type); + EXPECT_EQ(good_dir_info.path, dialog_params.default_path); +} + +IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, + OpenDirectory_LastPickedDirNotExists) { + base::FilePath test_dir = CreateTestDir(); + + SelectFileDialogParams dialog_params; + ui::SelectFileDialog::SetFactory( + new FakeSelectFileDialogFactory({test_dir}, &dialog_params)); + + testing::StrictMock<MockNativeFileSystemPermissionContext> permission_context; + static_cast<NativeFileSystemManagerImpl*>( + BrowserContext::GetStoragePartition( + shell()->web_contents()->GetBrowserContext(), + shell()->web_contents()->GetSiteInstance()) + ->GetNativeFileSystemEntryFactory()) + ->SetPermissionContextForTesting(&permission_context); + + auto read_grant = base::MakeRefCounted< + testing::StrictMock<MockNativeFileSystemPermissionGrant>>(); + auto write_grant = base::MakeRefCounted<FixedNativeFileSystemPermissionGrant>( + PermissionStatus::GRANTED, base::FilePath()); + + auto origin = + url::Origin::Create(embedded_test_server()->GetURL("/title1.html")); + auto frame_id = GlobalFrameRoutingId( + shell()->web_contents()->GetMainFrame()->GetProcess()->GetID(), + shell()->web_contents()->GetMainFrame()->GetRoutingID()); + EXPECT_CALL(permission_context, CanObtainReadPermission(origin)) + .WillOnce(testing::Return(true)); + + // The last picked directory no longer exists, so resort to showing the + // default directory, then set the test_file's dir as last picked. + PathInfo bad_dir_info; + bad_dir_info.path = temp_dir_.GetPath().AppendASCII("nonexistent"); + PathInfo default_dir_info; + default_dir_info.path = temp_dir_.GetPath().AppendASCII("default"); + + EXPECT_CALL(permission_context, GetLastPickedDirectory(origin)) + .WillOnce(testing::Return(bad_dir_info)); + EXPECT_CALL(permission_context, GetDefaultDirectory()) + .WillOnce(testing::Return(default_dir_info)); + EXPECT_CALL(permission_context, + SetLastPickedDirectory(origin, test_dir, PathType::kLocal)); + + EXPECT_CALL(permission_context, + ConfirmSensitiveDirectoryAccess_( + origin, PathType::kLocal, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + frame_id, testing::_)) + .WillOnce(RunOnceCallback<5>(SensitiveDirectoryResult::kAllowed)); + + EXPECT_CALL(permission_context, + GetReadPermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(read_grant)); + EXPECT_CALL(permission_context, + GetWritePermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(write_grant)); + + EXPECT_CALL( + *read_grant, + RequestPermission_( + frame_id, + NativeFileSystemPermissionGrant::UserActivationState::kNotRequired, + testing::_)) + .WillOnce(RunOnceCallback<2>(NativeFileSystemPermissionGrant:: + PermissionRequestOutcome::kUserGranted)); + EXPECT_CALL(*read_grant, GetStatus()) + .WillRepeatedly(testing::Return(PermissionStatus::GRANTED)); + + ASSERT_TRUE( + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"))); + EXPECT_EQ(test_dir.BaseName().AsUTF8Unsafe(), + EvalJs(shell(), + "(async () => {" + " let e = await self.showDirectoryPicker();" + " self.selected_entry = e;" + " return e.name; })()")); + EXPECT_EQ(ui::SelectFileDialog::SELECT_FOLDER, dialog_params.type); + EXPECT_EQ(default_dir_info.path, dialog_params.default_path); +} + +IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, + OpenDirectory_LastPickedDirExistsExternal) { + base::FilePath test_dir = CreateTestDir(); + + SelectFileDialogParams dialog_params; + ui::SelectFileDialog::SetFactory( + new FakeSelectFileDialogFactory({test_dir}, &dialog_params)); + + testing::StrictMock<MockNativeFileSystemPermissionContext> permission_context; + static_cast<NativeFileSystemManagerImpl*>( + BrowserContext::GetStoragePartition( + shell()->web_contents()->GetBrowserContext(), + shell()->web_contents()->GetSiteInstance()) + ->GetNativeFileSystemEntryFactory()) + ->SetPermissionContextForTesting(&permission_context); + + auto read_grant = base::MakeRefCounted< + testing::StrictMock<MockNativeFileSystemPermissionGrant>>(); + auto write_grant = base::MakeRefCounted<FixedNativeFileSystemPermissionGrant>( + PermissionStatus::GRANTED, base::FilePath()); + + auto origin = + url::Origin::Create(embedded_test_server()->GetURL("/title1.html")); + auto frame_id = GlobalFrameRoutingId( + shell()->web_contents()->GetMainFrame()->GetProcess()->GetID(), + shell()->web_contents()->GetMainFrame()->GetRoutingID()); + EXPECT_CALL(permission_context, CanObtainReadPermission(origin)) + .WillOnce(testing::Return(true)); + + // The last picked directory exists, so do not call GetDefaultDirectory. + PathInfo good_dir_info; + good_dir_info.path = base::FilePath::FromUTF8Unsafe(kTestMountPoint); + good_dir_info.type = PathType::kExternal; + + EXPECT_CALL(permission_context, GetLastPickedDirectory(origin)) + .WillOnce(testing::Return(good_dir_info)); + EXPECT_CALL(permission_context, + SetLastPickedDirectory(origin, test_dir, PathType::kLocal)); + + EXPECT_CALL(permission_context, + ConfirmSensitiveDirectoryAccess_( + origin, PathType::kLocal, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + frame_id, testing::_)) + .WillOnce(RunOnceCallback<5>(SensitiveDirectoryResult::kAllowed)); + + EXPECT_CALL(permission_context, + GetReadPermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(read_grant)); + EXPECT_CALL(permission_context, + GetWritePermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(write_grant)); + + EXPECT_CALL( + *read_grant, + RequestPermission_( + frame_id, + NativeFileSystemPermissionGrant::UserActivationState::kNotRequired, + testing::_)) + .WillOnce(RunOnceCallback<2>(NativeFileSystemPermissionGrant:: + PermissionRequestOutcome::kUserGranted)); + EXPECT_CALL(*read_grant, GetStatus()) + .WillRepeatedly(testing::Return(PermissionStatus::GRANTED)); + + ASSERT_TRUE( + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"))); + EXPECT_EQ(test_dir.BaseName().AsUTF8Unsafe(), + EvalJs(shell(), + "(async () => {" + " let e = await self.showDirectoryPicker();" + " self.selected_entry = e;" + " return e.name; })()")); + EXPECT_EQ(ui::SelectFileDialog::SELECT_FOLDER, dialog_params.type); + // temp_dir_.GetPath() maps to kTestMountPoint. + EXPECT_EQ(temp_dir_.GetPath(), dialog_params.default_path); +} + +IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, + OpenDirectory_LastPickedDirNotExistsExternal) { + base::FilePath test_dir = CreateTestDir(); + + SelectFileDialogParams dialog_params; + ui::SelectFileDialog::SetFactory( + new FakeSelectFileDialogFactory({test_dir}, &dialog_params)); + + testing::StrictMock<MockNativeFileSystemPermissionContext> permission_context; + static_cast<NativeFileSystemManagerImpl*>( + BrowserContext::GetStoragePartition( + shell()->web_contents()->GetBrowserContext(), + shell()->web_contents()->GetSiteInstance()) + ->GetNativeFileSystemEntryFactory()) + ->SetPermissionContextForTesting(&permission_context); + + auto read_grant = base::MakeRefCounted< + testing::StrictMock<MockNativeFileSystemPermissionGrant>>(); + auto write_grant = base::MakeRefCounted<FixedNativeFileSystemPermissionGrant>( + PermissionStatus::GRANTED, base::FilePath()); + + auto origin = + url::Origin::Create(embedded_test_server()->GetURL("/title1.html")); + auto frame_id = GlobalFrameRoutingId( + shell()->web_contents()->GetMainFrame()->GetProcess()->GetID(), + shell()->web_contents()->GetMainFrame()->GetRoutingID()); + EXPECT_CALL(permission_context, CanObtainReadPermission(origin)) + .WillOnce(testing::Return(true)); + + // The last picked directory no longer exists, so resort to showing the + // default directory, then set the test_file's dir as last picked. + PathInfo bad_dir_info; + bad_dir_info.path = base::FilePath::FromUTF8Unsafe(kTestMountPoint) + .AppendASCII("nonexistent"); + PathInfo default_dir_info; + default_dir_info.path = temp_dir_.GetPath().AppendASCII("default"); + + EXPECT_CALL(permission_context, GetLastPickedDirectory(origin)) + .WillOnce(testing::Return(bad_dir_info)); + EXPECT_CALL(permission_context, GetDefaultDirectory()) + .WillOnce(testing::Return(default_dir_info)); + EXPECT_CALL(permission_context, + SetLastPickedDirectory(origin, test_dir, PathType::kLocal)); + + EXPECT_CALL(permission_context, + ConfirmSensitiveDirectoryAccess_( + origin, PathType::kLocal, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + frame_id, testing::_)) + .WillOnce(RunOnceCallback<5>(SensitiveDirectoryResult::kAllowed)); + + EXPECT_CALL(permission_context, + GetReadPermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(read_grant)); + EXPECT_CALL(permission_context, + GetWritePermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(write_grant)); + + EXPECT_CALL( + *read_grant, + RequestPermission_( + frame_id, + NativeFileSystemPermissionGrant::UserActivationState::kNotRequired, + testing::_)) + .WillOnce(RunOnceCallback<2>(NativeFileSystemPermissionGrant:: + PermissionRequestOutcome::kUserGranted)); + EXPECT_CALL(*read_grant, GetStatus()) + .WillRepeatedly(testing::Return(PermissionStatus::GRANTED)); + + ASSERT_TRUE( + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"))); + EXPECT_EQ(test_dir.BaseName().AsUTF8Unsafe(), + EvalJs(shell(), + "(async () => {" + " let e = await self.showDirectoryPicker();" + " self.selected_entry = e;" + " return e.name; })()")); + EXPECT_EQ(ui::SelectFileDialog::SELECT_FOLDER, dialog_params.type); + EXPECT_EQ(default_dir_info.path, dialog_params.default_path); +} + } // namespace content
diff --git a/content/browser/file_system_access/file_system_chooser_test_helpers.cc b/content/browser/file_system_access/file_system_chooser_test_helpers.cc index 89a8fc1f..3dfe58a 100644 --- a/content/browser/file_system_access/file_system_chooser_test_helpers.cc +++ b/content/browser/file_system_access/file_system_chooser_test_helpers.cc
@@ -35,6 +35,7 @@ out_params_->file_types = base::nullopt; out_params_->owning_window = owning_window; out_params_->file_type_index = file_type_index; + out_params_->default_path = default_path; } listener_->FileSelectionCanceled(params); } @@ -77,6 +78,7 @@ out_params_->file_types = base::nullopt; out_params_->owning_window = owning_window; out_params_->file_type_index = file_type_index; + out_params_->default_path = default_path; } if (result_.size() == 1) listener_->FileSelectedWithExtraInfo(result_[0], 0, params);
diff --git a/content/browser/file_system_access/file_system_chooser_test_helpers.h b/content/browser/file_system_access/file_system_chooser_test_helpers.h index 92ad3fb5..5696b25 100644 --- a/content/browser/file_system_access/file_system_chooser_test_helpers.h +++ b/content/browser/file_system_access/file_system_chooser_test_helpers.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_CHOOSER_TEST_HELPERS_H_ #define CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_CHOOSER_TEST_HELPERS_H_ +#include "base/files/file_path.h" #include "base/optional.h" #include "ui/gfx/native_widget_types.h" #include "ui/shell_dialogs/select_file_dialog.h" @@ -23,6 +24,7 @@ base::Optional<ui::SelectFileDialog::FileTypeInfo> file_types; gfx::NativeWindow owning_window = {}; int file_type_index = -1; + base::FilePath default_path; }; // A fake ui::SelectFileDialog, which will cancel the file selection instead of
diff --git a/content/browser/file_system_access/file_system_chooser_unittest.cc b/content/browser/file_system_access/file_system_chooser_unittest.cc index c82e373..0166261 100644 --- a/content/browser/file_system_access/file_system_chooser_unittest.cc +++ b/content/browser/file_system_access/file_system_chooser_unittest.cc
@@ -180,6 +180,32 @@ dialog_params.file_types->extension_description_overrides[0]); } +TEST_F(FileSystemChooserTest, IgnoreShellIntegratedExtensions) { + SelectFileDialogParams dialog_params; + ui::SelectFileDialog::SetFactory( + new CancellingSelectFileDialogFactory(&dialog_params)); + std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts; + accepts.emplace_back(blink::mojom::ChooseFileSystemEntryAcceptsOption::New( + base::ASCIIToUTF16(""), std::vector<std::string>({}), + std::vector<std::string>( + {"lnk", "foo.lnk", "foo.bar.local", "text", "local"}))); + SyncShowDialog(std::move(accepts), /*include_accepts_all=*/false); + + ASSERT_TRUE(dialog_params.file_types); + EXPECT_FALSE(dialog_params.file_types->include_all_files); + ASSERT_EQ(1u, dialog_params.file_types->extensions.size()); + EXPECT_EQ(1, dialog_params.file_type_index); + + ASSERT_EQ(1u, dialog_params.file_types->extensions[0].size()); + EXPECT_EQ(dialog_params.file_types->extensions[0][0], + FILE_PATH_LITERAL("text")); + + ASSERT_EQ(1u, + dialog_params.file_types->extension_description_overrides.size()); + EXPECT_EQ(base::ASCIIToUTF16(""), + dialog_params.file_types->extension_description_overrides[0]); +} + TEST_F(FileSystemChooserTest, LocalPath) { const base::FilePath local_path(FILE_PATH_LITERAL("/foo/bar")); ui::SelectedFileInfo selected_file(local_path, local_path);
diff --git a/content/browser/file_system_access/native_file_system_manager_impl.cc b/content/browser/file_system_access/native_file_system_manager_impl.cc index a4ae8c9..4d5d21a7 100644 --- a/content/browser/file_system_access/native_file_system_manager_impl.cc +++ b/content/browser/file_system_access/native_file_system_manager_impl.cc
@@ -36,6 +36,7 @@ #include "storage/browser/file_system/file_system_operation_runner.h" #include "storage/browser/file_system/file_system_url.h" #include "storage/browser/file_system/isolated_context.h" +#include "storage/common/file_system/file_system_types.h" #include "storage/common/file_system/file_system_util.h" #include "third_party/blink/public/mojom/file_system_access/native_file_system_drag_drop_token.mojom.h" #include "third_party/blink/public/mojom/file_system_access/native_file_system_error.mojom.h" @@ -49,6 +50,7 @@ NativeFileSystemPermissionContext::SensitiveDirectoryResult; using storage::FileSystemContext; using HandleType = NativeFileSystemPermissionContext::HandleType; +using PathInfo = NativeFileSystemPermissionContext::PathInfo; namespace { @@ -177,6 +179,23 @@ std::move(reply_runner), std::move(callback))); } +void GetDirectoryExistsFromUrl( + storage::FileSystemURL url, + base::OnceCallback<void(base::File::Error)> callback, + scoped_refptr<base::SequencedTaskRunner> reply_runner, + storage::FileSystemOperationRunner* operation_runner) { + operation_runner->DirectoryExists( + url, base::BindOnce( + [](scoped_refptr<base::SequencedTaskRunner> reply_runner, + base::OnceCallback<void(base::File::Error)> callback, + base::File::Error result) { + // Post next task back on the UI thread. + reply_runner->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), result)); + }, + std::move(reply_runner), std::move(callback))); +} + } // namespace NativeFileSystemManagerImpl::SharedHandleState::SharedHandleState( @@ -310,21 +329,52 @@ return; } - // TODO(https://crbug.com/1142824): Check if path exists. - // TODO(asully): If PathType is kExternal, use FileSystemURL resolved path. - base::FilePath default_directory; + PathInfo path_info; if (permission_context_) { - default_directory = - permission_context_->GetLastPickedDirectory(context.origin).path; - if (default_directory.empty()) { - default_directory = permission_context_->GetDefaultDirectory().path; - } + path_info = permission_context_->GetLastPickedDirectory(context.origin); } - // TODO(https://crbug.com/1019408): Append suggested filename to the default - // directory. + auto url = CreateFileSystemURLFromPath(context.origin, path_info.type, + path_info.path); + auto fs_url = url.url; + operation_runner().PostTaskWithThisObject( + FROM_HERE, + base::BindOnce( + &GetDirectoryExistsFromUrl, std::move(fs_url), + base::BindOnce( + &NativeFileSystemManagerImpl::SetDefaultPathAndShowPicker, + weak_factory_.GetWeakPtr(), context, type, std::move(accepts), + include_accepts_all, std::move(url).url, std::move(callback)), + base::SequencedTaskRunnerHandle::Get())); +} + +void NativeFileSystemManagerImpl::SetDefaultPathAndShowPicker( + const BindingContext& context, + blink::mojom::ChooseFileSystemEntryType type, + std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts, + bool include_accepts_all, + storage::FileSystemURL url, + ChooseEntriesCallback callback, + base::File::Error result) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + base::FilePath default_directory; + if (result != base::File::Error::FILE_OK) { + if (permission_context_) { + auto default_path_info = permission_context_->GetDefaultDirectory(); + auto default_url = CreateFileSystemURLFromPath( + context.origin, default_path_info.type, default_path_info.path); + default_directory = default_url.url.path(); + } + } else /*result == base::File::Error::FILE_OK*/ { + default_directory = url.path(); + } + + // TODO(https://crbug.com/1019408): Append suggested filename to + // default_path. FileSystemChooser::Options options(type, std::move(accepts), - include_accepts_all, default_directory); + include_accepts_all, + std::move(default_directory)); if (auto_file_picker_result_for_test_) { DidChooseEntries(context, options, std::move(callback),
diff --git a/content/browser/file_system_access/native_file_system_manager_impl.h b/content/browser/file_system_access/native_file_system_manager_impl.h index 827c18a..bdaa672 100644 --- a/content/browser/file_system_access/native_file_system_manager_impl.h +++ b/content/browser/file_system_access/native_file_system_manager_impl.h
@@ -260,6 +260,14 @@ friend class NativeFileSystemFileHandleImpl; ~NativeFileSystemManagerImpl() override; + void SetDefaultPathAndShowPicker( + const BindingContext& context, + blink::mojom::ChooseFileSystemEntryType type, + std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts, + bool include_accepts_all, + storage::FileSystemURL url, + ChooseEntriesCallback callback, + base::File::Error result); void DidOpenSandboxedFileSystem(const BindingContext& binding_context, GetSandboxedFileSystemCallback callback, const GURL& root,
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index da600f6..959568d 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -37,6 +37,7 @@ #include "gpu/config/gpu_switches.h" #include "gpu/ipc/host/gpu_memory_buffer_support.h" #include "gpu/vulkan/buildflags.h" +#include "media/base/media_switches.h" #include "media/media_buildflags.h" #include "third_party/blink/public/common/switches.h" #include "ui/gl/gl_switches.h" @@ -133,7 +134,7 @@ SafeGetFeatureStatus(gpu_feature_info, gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE), #if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && !defined(OS_ANDROID) - !command_line.HasSwitch(switches::kEnableAcceleratedVideoDecode), + !base::FeatureList::IsEnabled(media::kVaapiVideoDecodeLinux), #else command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode), #endif // (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))&&
diff --git a/content/browser/initiator_csp_context.cc b/content/browser/initiator_csp_context.cc index 3384af1..f8f26e2 100644 --- a/content/browser/initiator_csp_context.cc +++ b/content/browser/initiator_csp_context.cc
@@ -8,14 +8,11 @@ InitiatorCSPContext::InitiatorCSPContext( std::vector<network::mojom::ContentSecurityPolicyPtr> policies, - network::mojom::CSPSourcePtr self_source, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator) : reporting_render_frame_host_impl_(nullptr), initiator(std::move(navigation_initiator)) { for (auto& policy : policies) AddContentSecurityPolicy(std::move(policy)); - - SetSelf(std::move(self_source)); } InitiatorCSPContext::~InitiatorCSPContext() = default;
diff --git a/content/browser/initiator_csp_context.h b/content/browser/initiator_csp_context.h index d7e8b3bc..c21cc8e 100644 --- a/content/browser/initiator_csp_context.h +++ b/content/browser/initiator_csp_context.h
@@ -24,7 +24,6 @@ public: InitiatorCSPContext( std::vector<network::mojom::ContentSecurityPolicyPtr> policies, - network::mojom::CSPSourcePtr self_source, mojo::PendingRemote<blink::mojom::NavigationInitiator> navigation_initiator); ~InitiatorCSPContext() override;
diff --git a/content/browser/media/media_internals_audio_focus_helper.cc b/content/browser/media/media_internals_audio_focus_helper.cc index 3540c65..482d282 100644 --- a/content/browser/media/media_internals_audio_focus_helper.cc +++ b/content/browser/media/media_internals_audio_focus_helper.cc
@@ -4,11 +4,12 @@ #include "content/browser/media/media_internals_audio_focus_helper.h" -#include <list> #include <string> #include "base/bind.h" #include "base/containers/adapters.h" +#include "base/ranges/algorithm.h" +#include "base/strings/strcat.h" #include "base/values.h" #include "content/browser/media/media_internals.h" #include "content/public/browser/browser_task_traits.h" @@ -44,6 +45,7 @@ const char kMediaSessionIsSensitive[] = "Sensitive"; const char kMediaSessionHasAudio[] = "HasAudio"; +const char kMediaSessionHasVideo[] = "HasVideo"; const char kMediaSessionHasAudioVideo[] = "HasAudioVideo"; } // namespace @@ -225,100 +227,114 @@ std::string MediaInternalsAudioFocusHelper::BuildNameString( const media_session::mojom::AudioFocusRequestStatePtr& state, const std::string& provided_name) const { - std::stringstream stream; + std::string result; // Add the |source_name| (optional). - if (state->source_name.has_value()) { - stream << state->source_name.value(); - stream << ":"; - } + if (state->source_name.has_value()) + base::StrAppend(&result, {state->source_name.value(), ":"}); // Add the |request_id|. - stream << state->request_id.value().ToString(); + result.append(state->request_id.value().ToString()); if (!provided_name.empty()) - stream << " " << provided_name; - return stream.str(); + base::StrAppend(&result, {" ", provided_name}); + + return result; } std::string MediaInternalsAudioFocusHelper::BuildStateString( const media_session::mojom::AudioFocusRequestStatePtr& state, const std::string& provided_state) const { - std::stringstream stream; + std::string result(" "); // Convert the AudioFocusType mojo enum to a string. switch (state->audio_focus_type) { case media_session::mojom::AudioFocusType::kGain: - stream << " " << kAudioFocusTypeGain; + result.append(kAudioFocusTypeGain); break; case media_session::mojom::AudioFocusType::kGainTransient: - stream << " " << kAudioFocusTypeGainTransient; + result.append(kAudioFocusTypeGainTransient); break; case media_session::mojom::AudioFocusType::kGainTransientMayDuck: - stream << " " << kAudioFocusTypeGainTransientMayDuck; + result.append(kAudioFocusTypeGainTransientMayDuck); break; case media_session::mojom::AudioFocusType::kAmbient: - stream << " " << kAudioFocusTypeAmbient; + result.append(kAudioFocusTypeAmbient); break; } // Convert the MediaSessionInfo::SessionState mojo enum to a string. + result.append(" "); switch (state->session_info->state) { case media_session::mojom::MediaSessionInfo::SessionState::kActive: - stream << " " << kMediaSessionStateActive; + result.append(kMediaSessionStateActive); break; case media_session::mojom::MediaSessionInfo::SessionState::kDucking: - stream << " " << kMediaSessionStateDucking; + result.append(kMediaSessionStateDucking); break; case media_session::mojom::MediaSessionInfo::SessionState::kSuspended: - stream << " " << kMediaSessionStateSuspended; + result.append(kMediaSessionStateSuspended); break; case media_session::mojom::MediaSessionInfo::SessionState::kInactive: - stream << " " << kMediaSessionStateInactive; + result.append(kMediaSessionStateInactive); break; } // Convert the MediaPlaybackState mojo enum to a string. + result.append(" "); switch (state->session_info->playback_state) { case media_session::mojom::MediaPlaybackState::kPaused: - stream << " " << kMediaSessionPlaybackStatePaused; + result.append(kMediaSessionPlaybackStatePaused); break; case media_session::mojom::MediaPlaybackState::kPlaying: - stream << " " << kMediaSessionPlaybackStatePlaying; + result.append(kMediaSessionPlaybackStatePlaying); break; } - // Convert the audio_video_state to a string. - switch (state->session_info->audio_video_state) { - case media_session::mojom::MediaAudioVideoState::kUnknown: - break; - case media_session::mojom::MediaAudioVideoState::kAudioOnly: - stream << " " << kMediaSessionHasAudio; - break; - case media_session::mojom::MediaAudioVideoState::kAudioVideo: - stream << " " << kMediaSessionHasAudioVideo; - break; + // Convert the audio_video_states to a string. + if (state->session_info->audio_video_states) { + result.append(" {"); + base::ranges::for_each( + *state->session_info->audio_video_states, [&result](const auto& state) { + result.append(" "); + switch (state) { + case media_session::mojom::MediaAudioVideoState::kAudioOnly: + result.append(kMediaSessionHasAudio); + break; + case media_session::mojom::MediaAudioVideoState::kVideoOnly: + result.append(kMediaSessionHasVideo); + break; + case media_session::mojom::MediaAudioVideoState::kAudioVideo: + result.append(kMediaSessionHasAudioVideo); + break; + case media_session::mojom::MediaAudioVideoState::kDeprecatedUnknown: + NOTREACHED(); + break; + } + }); + result.append(" }"); } // Convert the |force_duck| boolean into a string. if (state->session_info->force_duck) - stream << " " << kAudioFocusForceDuck; + base::StrAppend(&result, {" ", kAudioFocusForceDuck}); // Convert the |prefer_stop_for_gain_focus_loss| boolean into a string. if (state->session_info->prefer_stop_for_gain_focus_loss) - stream << " " << kAudioFocusPreferStop; + base::StrAppend(&result, {" ", kAudioFocusPreferStop}); // Convert the |is_controllable| boolean into a string. if (state->session_info->is_controllable) - stream << " " << kMediaSessionIsControllable; + base::StrAppend(&result, {" ", kMediaSessionIsControllable}); // Convert the |is_sensitive| boolean into a string. if (state->session_info->is_sensitive) - stream << " " << kMediaSessionIsSensitive; + base::StrAppend(&result, {" ", kMediaSessionIsSensitive}); if (!provided_state.empty()) - stream << " " << provided_state; - return stream.str(); + base::StrAppend(&result, {" ", provided_state}); + + return result; } } // namespace content
diff --git a/content/browser/media/session/media_session_controller.cc b/content/browser/media/session/media_session_controller.cc index d50a377..4e27c52a 100644 --- a/content/browser/media/session/media_session_controller.cc +++ b/content/browser/media/session/media_session_controller.cc
@@ -213,9 +213,14 @@ return true; } +bool MediaSessionController::HasAudio(int player_id) const { + DCHECK_EQ(player_id_, player_id); + return has_audio_; +} + bool MediaSessionController::HasVideo(int player_id) const { DCHECK_EQ(player_id_, player_id); - return has_video_ && has_audio_; + return has_video_; } std::string MediaSessionController::GetAudioOutputSinkId(int player_id) const {
diff --git a/content/browser/media/session/media_session_controller.h b/content/browser/media/session/media_session_controller.h index 5231d6b..2b2033c 100644 --- a/content/browser/media/session/media_session_controller.h +++ b/content/browser/media/session/media_session_controller.h
@@ -25,6 +25,10 @@ // Helper class for controlling a single player's MediaSession instance. Sends // browser side MediaSession commands back to a player hosted in the renderer // process. +// MediaSessionController registers itself with MediaSessionImpl as the +// MediaSessionPlayerObserver for the associated player, and for that player +// only. Consequently, it expects all MediaSessionPlayerObserver calls to +// occur for that player only. class CONTENT_EXPORT MediaSessionController : public MediaSessionPlayerObserver { public: @@ -44,7 +48,7 @@ // the MediaSession instance in sync with renderer side behavior. void OnPlaybackPaused(bool reached_end_of_stream); - // MediaSessionObserver implementation. + // MediaSessionPlayerObserver implementation. void OnSuspend(int player_id) override; void OnResume(int player_id) override; void OnSeekForward(int player_id, base::TimeDelta seek_time) override; @@ -58,6 +62,7 @@ base::Optional<media_session::MediaPosition> GetPosition( int player_id) const override; bool IsPictureInPictureAvailable(int player_id) const override; + bool HasAudio(int player_id) const override; bool HasVideo(int player_id) const override; std::string GetAudioOutputSinkId(int player_id) const override; bool SupportsAudioOutputDeviceSwitching(int player_id) const override;
diff --git a/content/browser/media/session/media_session_controller_unittest.cc b/content/browser/media/session/media_session_controller_unittest.cc index a2e96ed..4ac41d1 100644 --- a/content/browser/media/session/media_session_controller_unittest.cc +++ b/content/browser/media/session/media_session_controller_unittest.cc
@@ -179,7 +179,7 @@ }; TEST_F(MediaSessionControllerTest, NoAudioNoSession) { - controller_->SetMetadata(false, false, media::MediaContentType::Persistent); + controller_->SetMetadata(false, true, media::MediaContentType::Persistent); ASSERT_TRUE(controller_->OnPlaybackStarted()); EXPECT_FALSE(media_session()->IsActive()); EXPECT_FALSE(media_session()->IsControllable()); @@ -258,7 +258,7 @@ } TEST_F(MediaSessionControllerTest, Reinitialize) { - controller_->SetMetadata(false, false, media::MediaContentType::Persistent); + controller_->SetMetadata(false, true, media::MediaContentType::Persistent); ASSERT_TRUE(controller_->OnPlaybackStarted()); EXPECT_FALSE(media_session()->IsActive()); EXPECT_FALSE(media_session()->IsControllable()); @@ -408,7 +408,7 @@ TEST_F(MediaSessionControllerTest, AddPlayerWhenAddingAudio) { controller_->SetMetadata( - /* has_audio = */ false, /* has_video = */ false, + /* has_audio = */ false, /* has_video = */ true, media::MediaContentType::Persistent); ASSERT_TRUE(controller_->OnPlaybackStarted()); ASSERT_FALSE(media_session()->IsActive()); @@ -422,7 +422,7 @@ TEST_F(MediaSessionControllerTest, AddPlayerWhenEnteringPictureInPictureWithNoAudio) { controller_->SetMetadata( - /* has_audio = */ false, /* has_video = */ false, + /* has_audio = */ false, /* has_video = */ true, media::MediaContentType::Persistent); ASSERT_TRUE(controller_->OnPlaybackStarted()); ASSERT_FALSE(media_session()->IsActive()); @@ -435,7 +435,7 @@ TEST_F(MediaSessionControllerTest, AddPlayerWhenEnteringPictureInPicturePaused) { controller_->SetMetadata( - /*has_audio=*/false, /*has_video=*/false, + /*has_audio=*/false, /*has_video=*/true, media::MediaContentType::Persistent); ASSERT_TRUE(controller_->OnPlaybackStarted()); controller_->OnPlaybackPaused(/*reached_end_of_stream=*/false); @@ -451,7 +451,7 @@ contents()->SetHasPictureInPictureVideo(true); controller_->SetMetadata( - /* has_audio = */ false, /* has_video = */ false, + /* has_audio = */ false, /* has_video = */ true, media::MediaContentType::Persistent); ASSERT_TRUE(controller_->OnPlaybackStarted()); EXPECT_TRUE(media_session()->IsActive()); @@ -471,7 +471,7 @@ TEST_F(MediaSessionControllerTest, HasVideo_False) { controller_->SetMetadata( - /* has_audio = */ false, /* has_video = */ false, + /* has_audio = */ true, /* has_video = */ false, media::MediaContentType::Persistent); EXPECT_FALSE(controller_->HasVideo(controller_->get_player_id_for_testing())); }
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index 8bf006db..aba9289 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -940,7 +940,7 @@ info->playback_state = MediaPlaybackState::kPlaying; } - info->audio_video_state = GetMediaAudioVideoState(); + info->audio_video_states = GetMediaAudioVideoStates(); info->is_controllable = IsControllable(); // If the browser context is off the record then it should be sensitive. @@ -1529,28 +1529,33 @@ }); } -MediaAudioVideoState MediaSessionImpl::GetMediaAudioVideoState() { +std::vector<MediaAudioVideoState> MediaSessionImpl::GetMediaAudioVideoStates() { RenderFrameHost* routed_rfh = routed_service_ ? routed_service_->GetRenderFrameHost() : nullptr; - MediaAudioVideoState state = MediaAudioVideoState::kUnknown; + std::vector<MediaAudioVideoState> states; ForAllPlayers(base::BindRepeating( - [](RenderFrameHost* routed_rfh, MediaAudioVideoState* state, + [](RenderFrameHost* routed_rfh, std::vector<MediaAudioVideoState>* states, const PlayerIdentifier& player) { // If we have a routed frame then we should limit the players to the // frame so it is aligned with the media metadata. if (routed_rfh && player.observer->render_frame_host() != routed_rfh) return; - if (player.observer->HasVideo(player.player_id)) - *state = MediaAudioVideoState::kAudioVideo; - - if (*state != MediaAudioVideoState::kAudioVideo) - *state = MediaAudioVideoState::kAudioOnly; + const bool has_audio = player.observer->HasAudio(player.player_id); + const bool has_video = player.observer->HasVideo(player.player_id); + if (has_audio && has_video) { + states->push_back(MediaAudioVideoState::kAudioVideo); + } else if (has_audio) { + states->push_back(MediaAudioVideoState::kAudioOnly); + } else { + DCHECK(has_video); + states->push_back(MediaAudioVideoState::kVideoOnly); + } }, - routed_rfh, &state)); + routed_rfh, &states)); - return state; + return states; } void MediaSessionImpl::ForAllPlayers(
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h index 05615cd..a79f8b6 100644 --- a/content/browser/media/session/media_session_impl.h +++ b/content/browser/media/session/media_session_impl.h
@@ -409,11 +409,12 @@ void DidReceiveAction(media_session::mojom::MediaSessionAction action, blink::mojom::MediaSessionActionDetailsPtr details); - // Returns the media audio video state. This is whether the players associated - // with the media session are audio-only or have audio and video. If we have - // a |routed_service_| then we limit to players on that frame because this - // should align with the metadata. - media_session::mojom::MediaAudioVideoState GetMediaAudioVideoState(); + // Returns the media audio video state for each player. This is whether the + // players associated with the media session are audio-only, video-only, or + // have both audio and video. If we have a |routed_service_| then we limit to + // players on that frame because this should align with the metadata. + std::vector<media_session::mojom::MediaAudioVideoState> + GetMediaAudioVideoStates(); // Calls the callback with each |PlayerIdentifier| for every player associated // with this media session.
diff --git a/content/browser/media/session/media_session_impl_service_routing_unittest.cc b/content/browser/media/session/media_session_impl_service_routing_unittest.cc index 6eb58be6..6f7f452 100644 --- a/content/browser/media/session/media_session_impl_service_routing_unittest.cc +++ b/content/browser/media/session/media_session_impl_service_routing_unittest.cc
@@ -26,6 +26,7 @@ using ::testing::InvokeWithoutArgs; using ::testing::NiceMock; +using media_session::mojom::MediaAudioVideoState; using media_session::mojom::MediaSessionAction; using media_session::mojom::MediaSessionImageType; @@ -40,8 +41,9 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { public: - explicit MockMediaSessionPlayerObserver(RenderFrameHost* rfh, bool has_video) - : render_frame_host_(rfh), has_video_(has_video) {} + MockMediaSessionPlayerObserver(RenderFrameHost* rfh, + MediaAudioVideoState audio_video_state) + : render_frame_host_(rfh), audio_video_state_(audio_video_state) {} ~MockMediaSessionPlayerObserver() override = default; @@ -70,7 +72,15 @@ return false; } - bool HasVideo(int player_id) const override { return has_video_; } + bool HasAudio(int player_id) const override { + return audio_video_state_ == MediaAudioVideoState::kAudioOnly || + audio_video_state_ == MediaAudioVideoState::kAudioVideo; + } + + bool HasVideo(int player_id) const override { + return audio_video_state_ == MediaAudioVideoState::kVideoOnly || + audio_video_state_ == MediaAudioVideoState::kAudioVideo; + } std::string GetAudioOutputSinkId(int player_id) const override { return ""; } @@ -85,7 +95,7 @@ private: RenderFrameHost* render_frame_host_; - bool const has_video_; + const media_session::mojom::MediaAudioVideoState audio_video_state_; base::Optional<media_session::MediaPosition> position_; }; @@ -138,16 +148,20 @@ : nullptr; } - void StartPlayerForFrame(TestRenderFrameHost* frame, bool has_video = false) { - StartPlayerForFrame(frame, media::MediaContentType::Persistent, has_video); + void StartPlayerForFrame(TestRenderFrameHost* frame, + MediaAudioVideoState audio_video_state = + MediaAudioVideoState::kAudioOnly) { + StartPlayerForFrame(frame, media::MediaContentType::Persistent, + audio_video_state); } void StartPlayerForFrame(TestRenderFrameHost* frame, media::MediaContentType type, - bool has_video = false) { + MediaAudioVideoState audio_video_state = + MediaAudioVideoState::kAudioOnly) { players_[frame] = - std::make_unique<NiceMock<MockMediaSessionPlayerObserver>>(frame, - has_video); + std::make_unique<NiceMock<MockMediaSessionPlayerObserver>>( + frame, audio_video_state); MediaSessionImpl::Get(contents()) ->AddPlayer(players_[frame].get(), kPlayerId, type); } @@ -1061,109 +1075,107 @@ } TEST_F(MediaSessionImplServiceRoutingTest, RouteAudioVideoState) { - { - media_session::test::MockMediaSessionMojoObserver observer( - *GetMediaSession()); + for (const auto audio_or_video_only : + {MediaAudioVideoState::kAudioOnly, MediaAudioVideoState::kVideoOnly}) { + SCOPED_TRACE(audio_or_video_only); - // The default state should be unknown. - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kUnknown); - } + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession()); - StartPlayerForFrame(main_frame_, false /* has_video */); + // The default state should be unknown. + observer.WaitForAudioVideoStates({}); + } - { - media_session::test::MockMediaSessionMojoObserver observer( - *GetMediaSession()); + StartPlayerForFrame(main_frame_, audio_or_video_only); - // We should set the state to audio only. - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioOnly); - } + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession()); - StartPlayerForFrame(sub_frame_, true /* has_video */); + // We should set the state to audio/video only. + observer.WaitForAudioVideoStates({audio_or_video_only}); + } - { - media_session::test::MockMediaSessionMojoObserver observer( - *GetMediaSession()); + StartPlayerForFrame(sub_frame_, MediaAudioVideoState::kAudioVideo); - // The new player has a video track so we should now be AudioVideo. - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); - } + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession()); - CreateServiceForFrame(main_frame_); - ASSERT_EQ(services_[main_frame_].get(), ComputeServiceForRouting()); + // The new player has both an audio and video track. + observer.WaitForAudioVideoStates( + {audio_or_video_only, MediaAudioVideoState::kAudioVideo}); + } - { - media_session::test::MockMediaSessionMojoObserver observer( - *GetMediaSession()); + CreateServiceForFrame(main_frame_); + ASSERT_EQ(services_[main_frame_].get(), ComputeServiceForRouting()); - // The service on the main frame will restrict the audio video state to - // only look at the routed frame. - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioOnly); - } + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession()); - CreateServiceForFrame(sub_frame_); - ASSERT_EQ(services_[main_frame_].get(), ComputeServiceForRouting()); + // The service on the main frame will restrict the audio video state to + // only look at the routed frame. + observer.WaitForAudioVideoStates({audio_or_video_only}); + } - { - media_session::test::MockMediaSessionMojoObserver observer( - *GetMediaSession()); + CreateServiceForFrame(sub_frame_); + ASSERT_EQ(services_[main_frame_].get(), ComputeServiceForRouting()); - // The service on the main frame will restrict the audio video state to - // only look at the routed frame. - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioOnly); - } + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession()); - DestroyServiceForFrame(main_frame_); - ASSERT_EQ(services_[sub_frame_].get(), ComputeServiceForRouting()); + // The service on the main frame will restrict the audio video state to + // only look at the routed frame. + observer.WaitForAudioVideoStates({audio_or_video_only}); + } - { - media_session::test::MockMediaSessionMojoObserver observer( - *GetMediaSession()); + DestroyServiceForFrame(main_frame_); + ASSERT_EQ(services_[sub_frame_].get(), ComputeServiceForRouting()); - // Now that the service on the main frame has been destroyed then we should - // only look at players on the sub frame. - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); - } + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession()); - DestroyServiceForFrame(sub_frame_); - ASSERT_EQ(nullptr, ComputeServiceForRouting()); + // Now that the service on the main frame has been destroyed then we + // should only look at players on the sub frame. + observer.WaitForAudioVideoStates({MediaAudioVideoState::kAudioVideo}); + } - { - media_session::test::MockMediaSessionMojoObserver observer( - *GetMediaSession()); + DestroyServiceForFrame(sub_frame_); + ASSERT_EQ(nullptr, ComputeServiceForRouting()); - // Now that there is no service we should be looking at all the players - // again. - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioVideo); - } + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession()); - ClearPlayersForFrame(sub_frame_); + // Now that there is no service we should be looking at all the players + // again. + observer.WaitForAudioVideoStates( + {audio_or_video_only, MediaAudioVideoState::kAudioVideo}); + } - { - media_session::test::MockMediaSessionMojoObserver observer( - *GetMediaSession()); + ClearPlayersForFrame(sub_frame_); - // The state should be updated when we remove the sub frame players. - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kAudioOnly); - } + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession()); - ClearPlayersForFrame(main_frame_); + // The state should be updated when we remove the sub frame players. + observer.WaitForAudioVideoStates({audio_or_video_only}); + } - { - media_session::test::MockMediaSessionMojoObserver observer( - *GetMediaSession()); + ClearPlayersForFrame(main_frame_); - // We should fallback to the default state. - observer.WaitForAudioVideoState( - media_session::mojom::MediaAudioVideoState::kUnknown); + { + media_session::test::MockMediaSessionMojoObserver observer( + *GetMediaSession()); + + // We should fallback to the default state. + observer.WaitForAudioVideoStates({}); + } } }
diff --git a/content/browser/media/session/media_session_impl_uma_unittest.cc b/content/browser/media/session/media_session_impl_uma_unittest.cc index 06ce7df3..506d8551 100644 --- a/content/browser/media/session/media_session_impl_uma_unittest.cc +++ b/content/browser/media/session/media_session_impl_uma_unittest.cc
@@ -53,6 +53,7 @@ return false; } + bool HasAudio(int player_id) const override { return true; } bool HasVideo(int player_id) const override { return false; } std::string GetAudioOutputSinkId(int player_id) const override { return ""; }
diff --git a/content/browser/media/session/media_session_player_observer.h b/content/browser/media/session/media_session_player_observer.h index 7e1fdf9..6fce422 100644 --- a/content/browser/media/session/media_session_player_observer.h +++ b/content/browser/media/session/media_session_player_observer.h
@@ -56,6 +56,9 @@ // Returns if picture-in-picture is available for |player_id|. virtual bool IsPictureInPictureAvailable(int player_id) const = 0; + // Returns true if the |player_id| has audio tracks. + virtual bool HasAudio(int player_id) const = 0; + // Returns true if the |player_id| has video tracks. virtual bool HasVideo(int player_id) const = 0;
diff --git a/content/browser/media/session/media_session_service_impl_browsertest.cc b/content/browser/media/session/media_session_service_impl_browsertest.cc index 66c80f00..6fcab67 100644 --- a/content/browser/media/session/media_session_service_impl_browsertest.cc +++ b/content/browser/media/session/media_session_service_impl_browsertest.cc
@@ -66,6 +66,7 @@ return false; } + bool HasAudio(int player_id) const override { return true; } bool HasVideo(int player_id) const override { return false; } std::string GetAudioOutputSinkId(int player_id) const override { return ""; }
diff --git a/content/browser/media/session/mock_media_session_player_observer.cc b/content/browser/media/session/mock_media_session_player_observer.cc index 57c7eeb..44a45425 100644 --- a/content/browser/media/session/mock_media_session_player_observer.cc +++ b/content/browser/media/session/mock_media_session_player_observer.cc
@@ -164,6 +164,12 @@ return received_set_audio_sink_id_calls_; } +bool MockMediaSessionPlayerObserver::HasAudio(int player_id) const { + EXPECT_GE(player_id, 0); + EXPECT_GT(players_.size(), static_cast<size_t>(player_id)); + return true; +} + bool MockMediaSessionPlayerObserver::HasVideo(int player_id) const { EXPECT_GE(player_id, 0); EXPECT_GT(players_.size(), static_cast<size_t>(player_id));
diff --git a/content/browser/media/session/mock_media_session_player_observer.h b/content/browser/media/session/mock_media_session_player_observer.h index a8392617..8ada516 100644 --- a/content/browser/media/session/mock_media_session_player_observer.h +++ b/content/browser/media/session/mock_media_session_player_observer.h
@@ -37,6 +37,7 @@ int player_id) const override; bool IsPictureInPictureAvailable(int player_id) const override; RenderFrameHost* render_frame_host() const override; + bool HasAudio(int player_id) const override; bool HasVideo(int player_id) const override; std::string GetAudioOutputSinkId(int player_id) const override; bool SupportsAudioOutputDeviceSwitching(int player_id) const override;
diff --git a/content/browser/media/session/pepper_player_delegate.cc b/content/browser/media/session/pepper_player_delegate.cc index 77b1716..44b546e 100644 --- a/content/browser/media/session/pepper_player_delegate.cc +++ b/content/browser/media/session/pepper_player_delegate.cc
@@ -98,6 +98,11 @@ render_frame_host_->GetRoutingID(), pp_instance_, volume)); } +bool PepperPlayerDelegate::HasAudio(int player_id) const { + // We don't actually know whether a pepper player has both audio/video. + return true; +} + bool PepperPlayerDelegate::HasVideo(int player_id) const { // We don't actually know whether a pepper player has both audio/video. return true;
diff --git a/content/browser/media/session/pepper_player_delegate.h b/content/browser/media/session/pepper_player_delegate.h index f0802ee..68f4e9e1 100644 --- a/content/browser/media/session/pepper_player_delegate.h +++ b/content/browser/media/session/pepper_player_delegate.h
@@ -37,6 +37,7 @@ int player_id) const override; bool IsPictureInPictureAvailable(int player_id) const override; RenderFrameHost* render_frame_host() const override; + bool HasAudio(int player_id) const override; bool HasVideo(int player_id) const override; std::string GetAudioOutputSinkId(int player_id) const override; bool SupportsAudioOutputDeviceSwitching(int player_id) const override;
diff --git a/content/browser/renderer_host/ancestor_throttle.cc b/content/browser/renderer_host/ancestor_throttle.cc index cba465a..e08419c 100644 --- a/content/browser/renderer_host/ancestor_throttle.cc +++ b/content/browser/renderer_host/ancestor_throttle.cc
@@ -156,17 +156,26 @@ // attribute at the beginning of the navigation and not now, since the // beforeunload handlers might have modified it in the meantime. std::vector<network::mojom::ContentSecurityPolicyPtr> frame_csp; - frame_csp.emplace_back( + network::mojom::ContentSecurityPolicyPtr frame_csp_attribute = request->frame_tree_node()->csp_attribute() ? request->frame_tree_node()->csp_attribute()->Clone() - : nullptr); + : nullptr; + if (frame_csp_attribute) { + const GURL& url = navigation_handle()->GetURL(); + + // TODO(antoniosartori): Maybe we should revisit what 'self' means in the + // 'csp' attribute. + frame_csp_attribute->self_origin = network::mojom::CSPSource::New( + url.scheme(), url.host(), url.EffectiveIntPort(), "", false, false); + } + frame_csp.emplace_back(std::move(frame_csp_attribute)); + const network::mojom::ContentSecurityPolicy* parent_required_csp = request->frame_tree_node()->parent()->required_csp(); std::string error_message; - if (!network::IsValidRequiredCSPAttr( - frame_csp, parent_required_csp, - url::Origin::Create(navigation_handle()->GetURL()), error_message)) { + if (!network::IsValidRequiredCSPAttr(frame_csp, parent_required_csp, + error_message)) { if (frame_csp[0]) { navigation_handle()->GetParentFrame()->AddMessageToConsole( blink::mojom::ConsoleMessageLevel::kError, @@ -485,7 +494,6 @@ FrameAncestorCSPContext csp_context( NavigationRequest::From(navigation_handle())->GetRenderFrameHost(), content_security_policy); - csp_context.SetSelf(url::Origin::Create(navigation_handle()->GetURL())); // Check CSP frame-ancestors against every parent. // We enforce frame-ancestors in the outer delegate for portals, but not @@ -554,8 +562,7 @@ } if (network::Subsumes( *request->required_csp(), - request->response()->parsed_headers->content_security_policy, - url::Origin::Create(navigation_handle()->GetURL()))) { + request->response()->parsed_headers->content_security_policy)) { return CheckResult::PROCEED; }
diff --git a/content/browser/renderer_host/cursor_manager_unittest.cc b/content/browser/renderer_host/cursor_manager_unittest.cc index fe49a3a..2edfb0d 100644 --- a/content/browser/renderer_host/cursor_manager_unittest.cc +++ b/content/browser/renderer_host/cursor_manager_unittest.cc
@@ -56,12 +56,12 @@ std::make_unique<MockRenderProcessHost>(browser_context_.get()); agent_scheduling_group_host_ = std::make_unique<AgentSchedulingGroupHost>(*process_host_); - widget_host_.reset(MakeNewWidgetHost()); + widget_host_ = MakeNewWidgetHost(); top_view_ = new MockRenderWidgetHostViewForCursors(widget_host_.get(), true); } - RenderWidgetHostImpl* MakeNewWidgetHost() { + std::unique_ptr<RenderWidgetHostImpl> MakeNewWidgetHost() { int32_t routing_id = process_host_->GetNextRoutingID(); return MockRenderWidgetHost::Create( &delegate_, *agent_scheduling_group_host_, routing_id);
diff --git a/content/browser/renderer_host/form_submission_throttle_unittest.cc b/content/browser/renderer_host/form_submission_throttle_unittest.cc index 03c6636..60b9c9a 100644 --- a/content/browser/renderer_host/form_submission_throttle_unittest.cc +++ b/content/browser/renderer_host/form_submission_throttle_unittest.cc
@@ -19,6 +19,8 @@ policy->header = network::mojom::ContentSecurityPolicyHeader::New(); policy->directives[network::mojom::CSPDirectiveName::FormAction] = std::move(source_none); + policy->self_origin = network::mojom::CSPSource::New( + "https", "www.example.org", 443, "", false, false); main_test_rfh()->AddContentSecurityPolicy(std::move(policy)); } };
diff --git a/content/browser/renderer_host/input/fling_scheduler_unittest.cc b/content/browser/renderer_host/input/fling_scheduler_unittest.cc index 4816881..811f063 100644 --- a/content/browser/renderer_host/input/fling_scheduler_unittest.cc +++ b/content/browser/renderer_host/input/fling_scheduler_unittest.cc
@@ -57,16 +57,17 @@ FlingSchedulerTest() {} void SetUp() override { view_ = CreateView(); - widget_host_->SetView(view_); + widget_host_->SetView(view_.get()); - fling_scheduler_ = std::make_unique<FakeFlingScheduler>(widget_host_); + fling_scheduler_ = std::make_unique<FakeFlingScheduler>(widget_host_.get()); fling_controller_ = std::make_unique<FlingController>( this, fling_scheduler_.get(), FlingController::Config()); } void TearDown() override { - view_->Destroy(); - widget_host_->ShutdownAndDestroyWidget(true); + view_.release()->Destroy(); // 'delete this' is called internally. + widget_host_->ShutdownAndDestroyWidget(false); + widget_host_.reset(); process_host_->Cleanup(); agent_scheduling_group_host_.reset(); process_host_.reset(); @@ -75,7 +76,7 @@ base::RunLoop().RunUntilIdle(); } - TestRenderWidgetHostView* CreateView() { + std::unique_ptr<TestRenderWidgetHostView> CreateView() { browser_context_ = std::make_unique<TestBrowserContext>(); process_host_ = std::make_unique<MockRenderProcessHost>(browser_context_.get()); @@ -84,12 +85,10 @@ std::make_unique<AgentSchedulingGroupHost>(*process_host_); int32_t routing_id = process_host_->GetNextRoutingID(); delegate_ = std::make_unique<MockRenderWidgetHostDelegate>(); - widget_host_ = - TestRenderWidgetHost::Create( - delegate_.get(), *agent_scheduling_group_host_, routing_id, false) - .release(); - delegate_->set_widget_host(widget_host_); - return new TestRenderWidgetHostView(widget_host_); + widget_host_ = TestRenderWidgetHost::Create( + delegate_.get(), *agent_scheduling_group_host_, routing_id, false); + delegate_->set_widget_host(widget_host_.get()); + return std::make_unique<TestRenderWidgetHostView>(widget_host_.get()); } void SimulateFlingStart(const gfx::Vector2dF& velocity) { @@ -128,10 +127,10 @@ private: BrowserTaskEnvironment task_environment_; std::unique_ptr<TestBrowserContext> browser_context_; - RenderWidgetHostImpl* widget_host_; + std::unique_ptr<RenderWidgetHostImpl> widget_host_; std::unique_ptr<MockRenderProcessHost> process_host_; std::unique_ptr<AgentSchedulingGroupHost> agent_scheduling_group_host_; - TestRenderWidgetHostView* view_; + std::unique_ptr<TestRenderWidgetHostView> view_; std::unique_ptr<MockRenderWidgetHostDelegate> delegate_; #if defined(OS_WIN) display::win::test::ScopedScreenWin scoped_screen_win_;
diff --git a/content/browser/renderer_host/input/mouse_latency_browsertest.cc b/content/browser/renderer_host/input/mouse_latency_browsertest.cc index 2cc1f5f..577579a 100644 --- a/content/browser/renderer_host/input/mouse_latency_browsertest.cc +++ b/content/browser/renderer_host/input/mouse_latency_browsertest.cc
@@ -80,7 +80,8 @@ AgentSchedulingGroupHost& agent_scheduling_group, int32_t routing_id, bool hidden) - : RenderWidgetHostImpl(delegate, + : RenderWidgetHostImpl(/*self_owned=*/false, + delegate, agent_scheduling_group, routing_id, hidden, @@ -92,8 +93,6 @@ blink::mojom::InputEventResultState ack_result) override { RenderWidgetHostImpl::OnMouseEventAck(event, ack_source, ack_result); } - - private: }; class TracingRenderWidgetHostFactory : public RenderWidgetHostFactory {
diff --git a/content/browser/renderer_host/mixed_content_navigation_throttle.cc b/content/browser/renderer_host/mixed_content_navigation_throttle.cc index 76a1b53..00a9142b 100644 --- a/content/browser/renderer_host/mixed_content_navigation_throttle.cc +++ b/content/browser/renderer_host/mixed_content_navigation_throttle.cc
@@ -20,8 +20,8 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_client.h" #include "content/public/common/navigation_policy.h" -#include "content/public/common/origin_util.h" #include "net/base/url_util.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" #include "third_party/blink/public/common/loader/network_utils.h" #include "third_party/blink/public/common/security_context/insecure_request_policy.h" #include "third_party/blink/public/common/web_preferences/web_preferences.h" @@ -56,7 +56,7 @@ return url.SchemeIs(url::kBlobScheme) || url.SchemeIs(url::kFileSystemScheme) || blink::network_utils::IsOriginSecure(url) || - IsPotentiallyTrustworthyOrigin(url::Origin::Create(url)); + network::IsOriginPotentiallyTrustworthy(url::Origin::Create(url)); } // This method should return the same results as
diff --git a/content/browser/renderer_host/mock_render_widget_host.cc b/content/browser/renderer_host/mock_render_widget_host.cc index fa6d0ca..f4d0e2e 100644 --- a/content/browser/renderer_host/mock_render_widget_host.cc +++ b/content/browser/renderer_host/mock_render_widget_host.cc
@@ -38,25 +38,27 @@ } // static -MockRenderWidgetHost* MockRenderWidgetHost::Create( +std::unique_ptr<MockRenderWidgetHost> MockRenderWidgetHost::Create( RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_group, int32_t routing_id) { mojo::AssociatedRemote<blink::mojom::Widget> blink_widget; auto blink_widget_receiver = blink_widget.BindNewEndpointAndPassDedicatedReceiver(); - return new MockRenderWidgetHost(delegate, agent_scheduling_group, routing_id, - blink_widget.Unbind()); + return Create(delegate, agent_scheduling_group, routing_id, + blink_widget.Unbind()); } -MockRenderWidgetHost* MockRenderWidgetHost::Create( +// static +std::unique_ptr<MockRenderWidgetHost> MockRenderWidgetHost::Create( RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_group, int32_t routing_id, mojo::PendingAssociatedRemote<blink::mojom::Widget> pending_blink_widget) { DCHECK(pending_blink_widget); - return new MockRenderWidgetHost(delegate, agent_scheduling_group, routing_id, - std::move(pending_blink_widget)); + return base::WrapUnique( + new MockRenderWidgetHost(delegate, agent_scheduling_group, routing_id, + std::move(pending_blink_widget))); } blink::mojom::WidgetInputHandler* @@ -73,7 +75,8 @@ AgentSchedulingGroupHost& agent_scheduling_group, int routing_id, mojo::PendingAssociatedRemote<blink::mojom::Widget> pending_blink_widget) - : RenderWidgetHostImpl(delegate, + : RenderWidgetHostImpl(/*self_owned=*/false, + delegate, agent_scheduling_group, routing_id, /*hidden=*/false,
diff --git a/content/browser/renderer_host/mock_render_widget_host.h b/content/browser/renderer_host/mock_render_widget_host.h index 63c7d232..665757d 100644 --- a/content/browser/renderer_host/mock_render_widget_host.h +++ b/content/browser/renderer_host/mock_render_widget_host.h
@@ -58,12 +58,12 @@ InputRouter* input_router() { return input_router_.get(); } - static MockRenderWidgetHost* Create( + static std::unique_ptr<MockRenderWidgetHost> Create( RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_group, int32_t routing_id); - static MockRenderWidgetHost* Create( + static std::unique_ptr<MockRenderWidgetHost> Create( RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_group, int32_t routing_id,
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc index 273091f..1da9c12 100644 --- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -49,6 +49,7 @@ #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/bindings_policy.h" +#include "content/public/common/content_client.h" #include "content/public/common/content_features.h" #include "content/public/common/url_constants.h" #include "content/public/common/use_zoom_for_dsf_policy.h" @@ -68,6 +69,7 @@ #include "content/test/content_browser_test_utils_internal.h" #include "content/test/did_commit_navigation_interceptor.h" #include "content/test/render_document_feature.h" +#include "content/test/test_content_browser_client.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/controllable_http_response.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -451,6 +453,167 @@ } #endif // defined(OS_ANDROID) +// ContentBrowserClient that blocks normal commits to any URL in +// VerifyDidCommitParams. +class BlockAllCommitContentBrowserClient : public TestContentBrowserClient { + public: + // Any visit to any URL will be blocked by VerifyDidCommitParams, except if + // the checks are skipped (e.g. loadDataWithBaseURL). + BlockAllCommitContentBrowserClient() = default; + + bool CanCommitURL(RenderProcessHost* process_host, + const GURL& site_url) override { + return false; + } + + private: + DISALLOW_COPY_AND_ASSIGN(BlockAllCommitContentBrowserClient); +}; + +// Tests that navigating with LoadDataWithBaseURL succeeds even when the data +// URL is typically blocked by an embedder. +IN_PROC_BROWSER_TEST_P(NavigationControllerBrowserTest, + LoadDataWithBlockedURL) { + // LoadDataWithBaseURL is never subject to --site-per-process policy today + // (this API is only used by Android WebView [where OOPIFs have not shipped + // yet] and GuestView cases [which always hosts guests inside a renderer + // without an origin lock]). Therefore, skip the test in --site-per-process + // mode to avoid renderer kills which won't happen in practice as described + // above. + // + // TODO(https://crbug.com/962643): Consider enabling this test once Android + // Webview or WebView guests support OOPIFs and/or origin locks. + if (AreAllSitesIsolatedForTesting()) + return; + + const GURL base_url = embedded_test_server()->GetURL("/title1.html"); + const GURL history_url("http://historyurl"); + const std::string title = "blocked_url"; + const std::string data = base::StringPrintf( + "<html><head><title>%s</title></head><body>foo</body></html>", + title.c_str()); + const GURL data_url = GURL("data:text/html;charset=utf-8," + data); + BlockAllCommitContentBrowserClient content_browser_client; + ContentBrowserClient* old_client = + SetBrowserClientForTesting(&content_browser_client); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + + TestNavigationObserver same_tab_observer(shell()->web_contents(), 1); + TitleWatcher title_watcher(shell()->web_contents(), base::UTF8ToUTF16(title)); + shell()->LoadDataWithBaseURL(history_url, data, base_url); + same_tab_observer.Wait(); + base::string16 actual_title = title_watcher.WaitAndGetTitle(); + EXPECT_EQ(title, base::UTF16ToUTF8(actual_title)); + + NavigationEntryImpl* entry = controller.GetLastCommittedEntry(); + EXPECT_EQ(base_url, entry->GetBaseURLForDataURL()); + EXPECT_EQ(data_url, contents()->GetMainFrame()->GetLastCommittedURL()); + { + // Make a same-document navigation via history.pushState. + TestNavigationObserver same_tab_observer(shell()->web_contents(), 1); + EXPECT_TRUE( + ExecuteScript(shell(), "history.pushState('', 'test', '#foo')")); + same_tab_observer.Wait(); + } + + // Verify the last committed NavigationEntry. + EXPECT_EQ(2, controller.GetEntryCount()); + entry = controller.GetLastCommittedEntry(); + EXPECT_EQ(base_url, entry->GetBaseURLForDataURL()); + EXPECT_EQ(data_url, contents()->GetMainFrame()->GetLastCommittedURL()); + { + // Go back. + TestNavigationObserver back_load_observer(shell()->web_contents()); + controller.GoBack(); + back_load_observer.Wait(); + } + + // Verify the last committed NavigationEntry. + EXPECT_EQ(2, controller.GetEntryCount()); + entry = controller.GetLastCommittedEntry(); + EXPECT_EQ(base_url, entry->GetBaseURLForDataURL()); + EXPECT_EQ(data_url, contents()->GetMainFrame()->GetLastCommittedURL()); + + { + // Make a same-document navigation via fragment navigation. + TestNavigationObserver same_tab_observer(shell()->web_contents(), 1); + EXPECT_TRUE(ExecuteScript(shell(), "location.href = '#bar';")); + same_tab_observer.Wait(); + } + + // Verify the last committed NavigationEntry. + EXPECT_EQ(2, controller.GetEntryCount()); + entry = controller.GetLastCommittedEntry(); + EXPECT_EQ(base_url, entry->GetBaseURLForDataURL()); + EXPECT_EQ(data_url, contents()->GetMainFrame()->GetLastCommittedURL()); + + SetBrowserClientForTesting(old_client); +} + +// Tests that same-document navigations after a LoadDataWithBaseURL with an +// invalid base_url won't succeed. +IN_PROC_BROWSER_TEST_P(NavigationControllerBrowserTest, + LoadDataWithBlockedURLAndInvalidBaseURL) { + // LoadDataWithBaseURL is never subject to --site-per-process policy today + // (this API is only used by Android WebView [where OOPIFs have not shipped + // yet] and GuestView cases [which always hosts guests inside a renderer + // without an origin lock]). Therefore, skip the test in --site-per-process + // mode to avoid renderer kills which won't happen in practice as described + // above. + // + // TODO(https://crbug.com/962643): Consider enabling this test once Android + // Webview or WebView guests support OOPIFs and/or origin locks. + if (AreAllSitesIsolatedForTesting()) + return; + + const GURL base_url("http://"); // Invalid. + EXPECT_TRUE(!base_url.is_valid()); + const GURL history_url("http://historyurl"); + const std::string title = "invalid_base_url"; + const std::string data = base::StringPrintf( + "<html><head><title>%s</title></head><body>foo</body></html>", + title.c_str()); + const GURL data_url = GURL("data:text/html;charset=utf-8," + data); + BlockAllCommitContentBrowserClient content_browser_client; + ContentBrowserClient* old_client = + SetBrowserClientForTesting(&content_browser_client); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + + TestNavigationObserver same_tab_observer(shell()->web_contents(), 1); + TitleWatcher title_watcher(shell()->web_contents(), base::UTF8ToUTF16(title)); + shell()->LoadDataWithBaseURL(history_url, data, base_url); + same_tab_observer.Wait(); + base::string16 actual_title = title_watcher.WaitAndGetTitle(); + EXPECT_EQ(title, base::UTF16ToUTF8(actual_title)); + + // The navigation succeeds even though the base URL is invalid. + NavigationEntryImpl* entry = controller.GetLastCommittedEntry(); + EXPECT_EQ(1, controller.GetEntryCount()); + EXPECT_EQ(base_url, entry->GetBaseURLForDataURL()); + EXPECT_EQ(data_url, contents()->GetMainFrame()->GetLastCommittedURL()); + + { + // Make a same-document navigation via history.pushState. + TestNavigationObserver same_tab_observer(shell()->web_contents(), 1); + EXPECT_TRUE( + ExecuteScript(shell(), "history.pushState('', 'test', '#foo')")); + same_tab_observer.Wait(); + } + + // Verify that the same-document navigation succeeds. + EXPECT_EQ(2, controller.GetEntryCount()); + entry = controller.GetLastCommittedEntry(); + EXPECT_EQ(base_url, entry->GetBaseURLForDataURL()); + EXPECT_EQ(data_url.spec() + "#foo", + contents()->GetMainFrame()->GetLastCommittedURL().spec()); + + SetBrowserClientForTesting(old_client); +} + IN_PROC_BROWSER_TEST_P(NavigationControllerBrowserTest, NavigateFromLoadDataWithBaseURL) { // LoadDataWithBaseURL is never subject to --site-per-process policy today
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index c0b31bf..0e1c0fa2 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -90,7 +90,6 @@ #include "content/public/common/content_switches.h" #include "content/public/common/navigation_policy.h" #include "content/public/common/network_service_util.h" -#include "content/public/common/origin_util.h" #include "content/public/common/url_constants.h" #include "content/public/common/url_utils.h" #include "mojo/public/cpp/system/data_pipe.h" @@ -235,7 +234,8 @@ // TODO(clamy): This should be function in FrameTreeNode. bool IsSecureFrame(RenderFrameHostImpl* frame) { while (frame) { - if (!IsPotentiallyTrustworthyOrigin(frame->GetLastCommittedOrigin())) + if (!network::IsOriginPotentiallyTrustworthy( + frame->GetLastCommittedOrigin())) return false; frame = frame->GetParent(); } @@ -1024,7 +1024,6 @@ expected_render_process_host_id_(ChildProcessHost::kInvalidUniqueID), initiator_csp_context_(std::make_unique<InitiatorCSPContext>( std::move(common_params_->initiator_csp_info->initiator_csp), - std::move(common_params_->initiator_csp_info->initiator_self_source), std::move(navigation_initiator))), rfh_restored_from_back_forward_cache_( rfh_restored_from_back_forward_cache),
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 1a7c0e9..52dfc50e1 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -328,14 +328,6 @@ base::LazyInstance<TokenFrameMap>::Leaky g_token_frame_map = LAZY_INSTANCE_INITIALIZER; -// Returns true if |validated_params| represents a WebView loadDataWithBaseUrl -// navigation. -bool IsLoadDataWithBaseURL( - const mojom::DidCommitProvisionalLoadParams& validated_params) { - return NavigationRequest::IsLoadDataWithBaseURL(validated_params.url, - validated_params.base_url); -} - // Ensure that we reset nav_entry_id_ in DidCommitProvisionalLoad if any of // the validations fail and lead to an early return. Call disable() once we // know the commit will be successful. Resetting nav_entry_id_ avoids acting on @@ -652,7 +644,8 @@ StartDownload(std::move(parameters), nullptr); } -void RecordCrossOriginIsolationMetrics(RenderFrameHostImpl* rfh) { +void RecordWebPlatformSecurityMetrics(RenderFrameHostImpl* rfh, + NavigationRequest* navigation_request) { ContentBrowserClient* client = GetContentClient()->browser(); if (rfh->cross_origin_opener_policy().value == network::mojom::CrossOriginOpenerPolicyValue::kSameOrigin) { @@ -683,6 +676,45 @@ client->LogWebFeatureForCurrentPage( rfh, blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting); } + + // Record iframes embedded in cross-origin contexts without a CSP + // frame-ancestor directive. + bool is_embedded_in_cross_origin_context = false; + RenderFrameHostImpl* parent = rfh->frame_tree_node()->parent(); + while (parent) { + if (!parent->GetLastCommittedOrigin().IsSameOriginWith( + rfh->GetLastCommittedOrigin())) { + is_embedded_in_cross_origin_context = true; + break; + } + parent = parent->frame_tree_node()->parent(); + } + + bool has_embedding_control = false; + if (!navigation_request->response()) { + // This navigation did not result in a network request. The embedding of + // the frame is not controlled by network headers. + has_embedding_control = true; + } else { + // Check if the request has a CSP frame-ancestor directive. + for (const auto& csp : navigation_request->response() + ->parsed_headers->content_security_policy) { + if (csp->header->type == + network::mojom::ContentSecurityPolicyType::kEnforce && + csp->directives.contains( + network::mojom::CSPDirectiveName::FrameAncestors)) { + has_embedding_control = true; + break; + } + } + } + + if (is_embedded_in_cross_origin_context && !has_embedding_control && + !navigation_request->IsErrorPage()) { + client->LogWebFeatureForCurrentPage( + rfh, + blink::mojom::WebFeature::kCrossOriginSubframeWithoutEmbeddingControl); + } } // Subframe navigations can optionally have associated Trust Tokens operations @@ -1047,7 +1079,6 @@ // RenderWidgetHostImpl, the main render frame should probably start // owning the RenderWidgetHostImpl itself. DCHECK(GetLocalRenderWidgetHost()); - DCHECK(!GetLocalRenderWidgetHost()->owned_by_render_frame_host()); } else { // For local child roots, the RenderFrameHost directly creates and owns // its RenderWidgetHost. @@ -1057,7 +1088,6 @@ owned_render_widget_host_ = RenderWidgetHostFactory::Create( frame_tree_->render_widget_delegate(), agent_scheduling_group_, widget_routing_id, /*hidden=*/true); - owned_render_widget_host_->set_owned_by_render_frame_host(true); #if defined(OS_ANDROID) owned_render_widget_host_->SetForceEnableZoom( delegate_->GetOrCreateWebPreferences().force_enable_zoom); @@ -1072,18 +1102,6 @@ } ResetFeaturePolicy(); - // Content-Security-Policy: The CSP source 'self' is usually the origin of the - // current document, set by SetLastCommittedOrigin(). However, before a new - // frame commits its first navigation, 'self' should correspond to the origin - // of the parent (in case of a new iframe) or the opener (in case of a new - // window). This is necessary to correctly enforce CSP during the initial - // navigation. - FrameTreeNode* frame_owner = - frame_tree_node_->parent() ? frame_tree_node_->parent()->frame_tree_node() - : frame_tree_node_->opener(); - if (frame_owner) - CSPContext::SetSelf(frame_owner->current_origin()); - // New RenderFrameHostImpl are put in their own virtual browsing context // group. Then, they can inherit from: // 1) Their opener in RenderFrameHostImpl::CreateNewWindow(). @@ -2658,7 +2676,6 @@ void RenderFrameHostImpl::SetLastCommittedOrigin(const url::Origin& origin) { last_committed_origin_ = origin; - CSPContext::SetSelf(origin); } void RenderFrameHostImpl::SetLastCommittedOriginForTesting( @@ -8338,11 +8355,17 @@ // WebView's loadDataWithBaseURL API is allowed to bypass normal commit // checks because it is allowed to commit anything into its unlocked process // and its data: URL and non-opaque origin would fail the normal commit - // checks. + // checks. We should also allow same-document navigations within pages loaded + // with loadDataWithBaseURL. Since renderer-initiated same-document + // navigations won't have a NavigationRequest at this point, we need to check + // |is_loaded_from_load_data_with_base_url_|. + DCHECK(navigation_request || is_same_document_navigation || + !frame_tree_node_->has_committed_real_load()); bool bypass_checks_for_webview = false; if ((navigation_request && NavigationRequest::IsLoadDataWithBaseURL( navigation_request->common_params())) || - (is_same_document_navigation && IsLoadDataWithBaseURL(*params))) { + (is_same_document_navigation && + is_loaded_from_load_data_with_base_url_)) { // Allow bypass if the process isn't locked. Otherwise run normal checks. bypass_checks_for_webview = !ChildProcessSecurityPolicyImpl::GetInstance() ->GetProcessLock(process->GetID()) @@ -8760,7 +8783,15 @@ is_overriding_user_agent_ = navigation_request->IsOverridingUserAgent() && frame_tree_node_->IsMainFrame(); - RecordCrossOriginIsolationMetrics(this); + // Mark whether the document is loaded with loadDataWithBaseURL or not. If + // |is_loaded_from_load_data_with_base_url_| is true, we will bypass checks + // in VerifyDidCommitParams for same-document navigations in the loaded + // document. + is_loaded_from_load_data_with_base_url_ = + NavigationRequest::IsLoadDataWithBaseURL( + navigation_request->common_params()); + + RecordWebPlatformSecurityMetrics(this, navigation_request); CrossOriginOpenerPolicyReporter::InstallAccessMonitorsIfNeeded( frame_tree_node_); @@ -9365,19 +9396,10 @@ return last_committed_entry ? last_committed_entry->GetPostID() : -1; } -bool DoBaseURLExpectationsMatch(const GURL& browser_base_url, - const GURL& renderer_base_url, +bool DoBaseURLExpectationsMatch(const GURL& renderer_base_url, const net::Error& net_error_code) { - // base_url value is currently only used in the browser side for two cases: - // 1) To check if the document is loaded with loadDataWithBaseURL in - // ValidateDidCommitParams. In this case, |renderer_base_url| should be the - // same as |browser_base_url|, except for when the browser sent an - // invalid URL - |renderer_base_url| should be empty in this case. - if (!browser_base_url.is_empty() && browser_base_url != renderer_base_url && - (browser_base_url.is_valid() || !renderer_base_url.is_empty())) { - return false; - } - // 2) To check if a navigation results in an error page or not in + // base_url value is currently only used in the browser side to check if a + // navigation results in an error page or not in // NavigationRequest::DidCommitNavigation. This can be known by just checking // for the net error code value instead, as all navigations that result in an // error page should be known by the browser side before committing. @@ -9439,8 +9461,8 @@ data_url_as_string, request->GetNetErrorCode(), frame_tree_node_->IsMainFrame()); - const bool base_url_expectations_match = DoBaseURLExpectationsMatch( - browser_base_url, params.base_url, request->GetNetErrorCode()); + const bool base_url_expectations_match = + DoBaseURLExpectationsMatch(params.base_url, request->GetNetErrorCode()); const int64_t browser_post_id = CalculatePostID(params.method, request->common_params().post_data,
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 685e7e7..f492d77f 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -3075,6 +3075,10 @@ // not. bool is_overriding_user_agent_ = false; + // Whether the currently committed document is a result of webview's + // loadDataWithBaseURL API or not. + bool is_loaded_from_load_data_with_base_url_ = false; + // The last reported character encoding, not canonicalized. std::string last_reported_encoding_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 4fe62d5..0c1b981 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3185,9 +3185,6 @@ !BUILDFLAG(IS_CHROMEOS_LACROS) switches::kDisableDevShmUsage, #endif -#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && !defined(OS_ANDROID) - switches::kEnableAcceleratedVideoDecode, -#endif #if defined(OS_MAC) // Allow this to be set when invoking the browser and relayed along. sandbox::policy::switches::kEnableSandboxLogging,
diff --git a/content/browser/renderer_host/render_widget_host_factory.cc b/content/browser/renderer_host/render_widget_host_factory.cc index 3c7dfe5..8b576dc 100644 --- a/content/browser/renderer_host/render_widget_host_factory.cc +++ b/content/browser/renderer_host/render_widget_host_factory.cc
@@ -22,7 +22,7 @@ return factory_->CreateRenderWidgetHost(delegate, agent_scheduling_group, routing_id, hidden); } - return std::make_unique<RenderWidgetHostImpl>( + return RenderWidgetHostImpl::Create( delegate, agent_scheduling_group, routing_id, hidden, std::make_unique<FrameTokenMessageQueue>()); }
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index d4df86598..eaf64f3 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -326,13 +326,39 @@ /////////////////////////////////////////////////////////////////////////////// // RenderWidgetHostImpl +// static +std::unique_ptr<RenderWidgetHostImpl> RenderWidgetHostImpl::Create( + RenderWidgetHostDelegate* delegate, + AgentSchedulingGroupHost& agent_scheduling_host, + int32_t routing_id, + bool hidden, + std::unique_ptr<FrameTokenMessageQueue> frame_token_message_queue) { + return base::WrapUnique(new RenderWidgetHostImpl( + /*self_owned=*/false, delegate, agent_scheduling_host, routing_id, hidden, + std::move(frame_token_message_queue))); +} + +// static +RenderWidgetHostImpl* RenderWidgetHostImpl::CreateSelfOwned( + RenderWidgetHostDelegate* delegate, + AgentSchedulingGroupHost& agent_scheduling_host, + int32_t routing_id, + bool hidden, + std::unique_ptr<FrameTokenMessageQueue> frame_token_message_queue) { + return new RenderWidgetHostImpl(/*self_owned=*/true, delegate, + agent_scheduling_host, routing_id, hidden, + std::move(frame_token_message_queue)); +} + RenderWidgetHostImpl::RenderWidgetHostImpl( + bool self_owned, RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_group, int32_t routing_id, bool hidden, std::unique_ptr<FrameTokenMessageQueue> frame_token_message_queue) - : delegate_(delegate), + : self_owned_(self_owned), + delegate_(delegate), agent_scheduling_group_(agent_scheduling_group), routing_id_(routing_id), clock_(base::DefaultTickClock::GetInstance()), @@ -372,7 +398,13 @@ routing_id_), this)); CHECK(result.second) << "Inserting a duplicate item!"; - agent_scheduling_group.GetProcess()->AddObserver(this); + + // Self-owned RenderWidgetHost lifetime is managed by the renderer process. + // To avoid leaking any instance. They self-delete when their renderer process + // is gone. + if (self_owned_) + agent_scheduling_group.GetProcess()->AddObserver(this); + render_process_blocked_state_changed_subscription_ = agent_scheduling_group.GetProcess()->RegisterBlockStateChangedCallback( base::BindRepeating( @@ -394,6 +426,7 @@ } RenderWidgetHostImpl::~RenderWidgetHostImpl() { + CHECK(!self_owned_); render_frame_metadata_provider_.RemoveObserver(this); if (!destroyed_) Destroy(false); @@ -812,7 +845,7 @@ // Historically this was done by finding the RenderViewHost for the widget, // but a child local root would not convert to a RenderViewHost but is for a // frame. - const bool is_frame_widget = owner_delegate_ || owned_by_render_frame_host_; + const bool is_frame_widget = !self_owned_; blink::VisualProperties visual_properties; @@ -1895,11 +1928,8 @@ void RenderWidgetHostImpl::RenderProcessExited( RenderProcessHost* host, const ChildProcessTerminationInfo& info) { - // When the RenderViewHost or the RenderFrameHost own this instance, they - // manage its destruction. Otherwise it is owned by the renderer process and - // must self-destroy when it exits. - if (!owner_delegate_ && !owned_by_render_frame_host_) - Destroy(true); + CHECK(self_owned_); + Destroy(/*also_delete=*/true); // Delete |this|. } blink::mojom::WidgetInputHandler* @@ -2199,7 +2229,10 @@ delegate_->RenderWidgetDeleted(this); if (also_delete) { - CHECK(!owner_delegate_); + CHECK(self_owned_); + // The destructor CHECKs self-owned RenderWidgetHostImpl aren't destroyed + // externally. This bit needs to be reset to allow internal deletion. + self_owned_ = false; delete this; } }
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index a023b982..aa994c8 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -148,10 +148,22 @@ public blink::mojom::WidgetHost, public blink::mojom::PointerLockContext { public: - // |routing_id| must not be MSG_ROUTING_NONE. - // If this object outlives |delegate|, DetachDelegate() must be called when - // |delegate| goes away. - RenderWidgetHostImpl( + // See the constructor for documentations. + static std::unique_ptr<RenderWidgetHostImpl> Create( + RenderWidgetHostDelegate* delegate, + AgentSchedulingGroupHost& agent_scheduling_host, + int32_t routing_id, + bool hidden, + std::unique_ptr<FrameTokenMessageQueue> frame_token_message_queue); + + // See the constructor for documentations. + // + // Contrary to Create(), this function doesn't give ownership of the + // RenderWidgetHost. Instead, this instance is self-owned. It deletes itself + // when: + // - ShutdownAndDestroyWidget(also_delete = true) is called. + // - its RenderProcess exit. + static RenderWidgetHostImpl* CreateSelfOwned( RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_host, int32_t routing_id, @@ -352,15 +364,6 @@ // Returns true if the frame content needs be stored before being evicted. bool ShouldShowStaleContentOnEviction(); - // Signal whether this RenderWidgetHost is owned by a RenderFrameHost, in - // which case it does not do self-deletion. - void set_owned_by_render_frame_host(bool owned_by_rfh) { - owned_by_render_frame_host_ = owned_by_rfh; - } - bool owned_by_render_frame_host() const { - return owned_by_render_frame_host_; - } - void SetFrameDepth(unsigned int depth); void SetIntersectsViewport(bool intersects); void UpdatePriority(); @@ -807,6 +810,16 @@ GetLastVisualPropertiesSentToRendererForTesting(); protected: + // |routing_id| must not be MSG_ROUTING_NONE. + // If this object outlives |delegate|, DetachDelegate() must be called when + // |delegate| goes away. + RenderWidgetHostImpl( + bool self_owned, + RenderWidgetHostDelegate* delegate, + AgentSchedulingGroupHost& agent_scheduling_host, + int32_t routing_id, + bool hidden, + std::unique_ptr<FrameTokenMessageQueue> frame_token_message_queue); // --------------------------------------------------------------------------- // The following method is overridden by RenderViewHost to send upwards to // its delegate. @@ -1058,6 +1071,19 @@ // An expiry time for resetting the pending_user_activation_timer_. static const base::TimeDelta kActivationNotificationExpireTime; + // RenderWidgetHost are either: + // - Owned by RenderViewHostImpl. + // - Owned by RenderFrameHost, for local root iframes. + // - Self owned. Lifetime is managed from the renderer process, via Mojo IPC; + // This is used to implement: + // - Color Chooser popup. + // - Date/Time chooser popup. + // - Internal popup. Essentially, the <select> element popup. + // + // self_owned RenderWidgetHost are expected to be deleted using: + // ShutdownAndDestroyWidget(true /* also_delete */); + bool self_owned_; + // true if a renderer has once been valid. We use this flag to display a sad // tab only when we lose our renderer and not if a paint occurs during // initialization. @@ -1247,10 +1273,6 @@ PendingSnapshotMap pending_browser_snapshots_; PendingSnapshotMap pending_surface_browser_snapshots_; - // Indicates whether a RenderFramehost has ownership, in which case this - // object does not self destroy. - bool owned_by_render_frame_host_ = false; - // Indicates whether this RenderWidgetHost thinks is focused. This is trying // to match what the renderer process knows. It is different from // RenderWidgetHostView::HasFocus in that in that the focus request may fail,
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc index 1383b6c..3a3045d4 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
@@ -232,7 +232,7 @@ std::make_unique<MockRenderProcessHost>(browser_context_.get()); agent_scheduling_group_host_root_ = std::make_unique<AgentSchedulingGroupHost>(*process_host_root_); - widget_host_root_ = std::make_unique<RenderWidgetHostImpl>( + widget_host_root_ = RenderWidgetHostImpl::Create( &delegate_, *agent_scheduling_group_host_root_, process_host_root_->GetNextRoutingID(), /*hidden=*/false, std::make_unique<FrameTokenMessageQueue>()); @@ -289,7 +289,7 @@ std::make_unique<MockRenderProcessHost>(browser_context_.get()); child.agent_scheduling_group_host = std::make_unique<AgentSchedulingGroupHost>(*child.process_host); - child.widget_host = std::make_unique<RenderWidgetHostImpl>( + child.widget_host = RenderWidgetHostImpl::Create( &delegate_, *child.agent_scheduling_group_host, child.process_host->GetNextRoutingID(), /*hidden=*/false, std::make_unique<FrameTokenMessageQueue>());
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 81650beb..11fbf37 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -544,9 +544,9 @@ screen_.reset(aura::TestScreen::Create(gfx::Size())); display::Screen::SetScreenInstance(screen_.get()); #endif - host_.reset(MockRenderWidgetHost::Create( + host_ = MockRenderWidgetHost::Create( delegate_.get(), *agent_scheduling_group_host_, - process_->GetNextRoutingID(), widget_.GetNewRemote())); + process_->GetNextRoutingID(), widget_.GetNewRemote()); // Set up the RenderWidgetHost as being for a main frame. host_->set_owner_delegate(&mock_owner_delegate_); // Act like there is no RenderWidget present in the renderer yet.
diff --git a/content/browser/renderer_host/render_widget_host_view_android_unittest.cc b/content/browser/renderer_host/render_widget_host_view_android_unittest.cc index 2817fbb..2e5f06e 100644 --- a/content/browser/renderer_host/render_widget_host_view_android_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_android_unittest.cc
@@ -81,12 +81,12 @@ void RenderWidgetHostViewAndroidTest::SetUp() { browser_context_.reset(new TestBrowserContext()); - delegate_.reset(new MockRenderWidgetHostDelegate()); + delegate_ = std::make_unique<MockRenderWidgetHostDelegate>(); process_ = std::make_unique<MockRenderProcessHost>(browser_context_.get()); agent_scheduling_group_ = std::make_unique<AgentSchedulingGroupHost>(*process_); - host_.reset(MockRenderWidgetHost::Create( - delegate_.get(), *agent_scheduling_group_, process_->GetNextRoutingID())); + host_ = MockRenderWidgetHost::Create( + delegate_.get(), *agent_scheduling_group_, process_->GetNextRoutingID()); parent_layer_ = cc::Layer::Create(); parent_view_.SetLayer(parent_layer_); layer_ = cc::Layer::Create();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 7963225..465d9ff 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -388,6 +388,8 @@ return widget_.ReceivedScreenRects(); } + // Instance self-delete when its |agent_scheduling_groups|'s process will + // exit. static MockRenderWidgetHostImpl* Create( RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_group, @@ -419,7 +421,8 @@ MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_group, int32_t routing_id) - : RenderWidgetHostImpl(delegate, + : RenderWidgetHostImpl(/*self_owned=*/true, + delegate, agent_scheduling_group, routing_id, /*hidden=*/false, @@ -522,8 +525,6 @@ EXPECT_EQ(view, host->GetView()); view->Destroy(); EXPECT_EQ(nullptr, host->GetView()); - - delete host; } void SetUpEnvironment() { @@ -584,16 +585,9 @@ void TearDownEnvironment() { sink_ = nullptr; - if (view_) { + if (view_) DestroyView(view_); - } else if (widget_host_) { - // Delete |widget_host_| in cases where |view_| gets destroyed - // by its parent, but the host does not get destroyed. - delete widget_host_; - } - parent_view_->Destroy(); - delete parent_host_; process_host_->Cleanup(); agent_scheduling_group_host_ = nullptr; @@ -3259,10 +3253,8 @@ EXPECT_EQ(*views[1]->window_->layer()->GetOldestAcceptableFallback(), *views[1]->window_->layer()->GetSurfaceId()); - for (size_t i = 0; i < renderer_count; ++i) { + for (size_t i = 0; i < renderer_count; ++i) views[i]->Destroy(); - delete hosts[i]; - } } // Test that changing the memory pressure should delete saved frames. This test @@ -3330,10 +3322,8 @@ base::RunLoop().RunUntilIdle(); EXPECT_EVICTED(views[1]); - for (size_t i = 0; i < renderer_count; ++i) { + for (size_t i = 0; i < renderer_count; ++i) views[i]->Destroy(); - delete hosts[i]; - } } TEST_F(RenderWidgetHostViewAuraTest, SourceEventTypeExistsInLatencyInfo) { @@ -5825,16 +5815,13 @@ void TearDown() override { view_for_first_process_->Destroy(); - delete widget_host_for_first_process_; view_for_second_process_->Destroy(); - delete widget_host_for_second_process_; second_process_host_->Cleanup(); second_agent_scheduling_group_host_.reset(); second_process_host_.reset(); view_for_third_process_->Destroy(); - delete widget_host_for_third_process_; third_process_host_->Cleanup(); third_agent_scheduling_group_host_.reset(); third_process_host_.reset();
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc index 35813c14..058e36f 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
@@ -124,7 +124,7 @@ int32_t routing_id = process_host_->GetNextRoutingID(); sink_ = &process_host_->sink(); - widget_host_ = new RenderWidgetHostImpl( + widget_host_ = RenderWidgetHostImpl::Create( &delegate_, *agent_scheduling_group_host_, routing_id, /*hidden=*/false, std::make_unique<FrameTokenMessageQueue>()); @@ -143,7 +143,8 @@ blink::ScreenInfo screen_info; screen_info.rect = gfx::Rect(1, 2, 3, 4); - view_ = RenderWidgetHostViewChildFrame::Create(widget_host_, screen_info); + view_ = + RenderWidgetHostViewChildFrame::Create(widget_host_.get(), screen_info); // Test we get the expected ScreenInfo before the FrameDelegate is set. blink::ScreenInfo actual_screen_info; view_->GetScreenInfo(&actual_screen_info); @@ -159,7 +160,7 @@ sink_ = nullptr; if (view_) view_->Destroy(); - delete widget_host_; + widget_host_.reset(); process_host_->Cleanup(); agent_scheduling_group_host_ = nullptr; delete test_frame_connector_; @@ -196,7 +197,7 @@ // Tests should set these to NULL if they've already triggered their // destruction. - RenderWidgetHostImpl* widget_host_; + std::unique_ptr<RenderWidgetHostImpl> widget_host_; RenderWidgetHostViewChildFrame* view_; MockFrameConnector* test_frame_connector_; };
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm index 79e1aaa..6bf39a6 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -149,15 +149,16 @@ @autoreleasepool { int32_t routing_id = process_host->GetNextRoutingID(); - RenderWidgetHostImpl* render_widget = new RenderWidgetHostImpl( - &delegate, *agent_scheduling_group_host, routing_id, - /*hidden=*/false, std::make_unique<FrameTokenMessageQueue>()); + std::unique_ptr<RenderWidgetHostImpl> render_widget = + RenderWidgetHostImpl::Create( + &delegate, *agent_scheduling_group_host, routing_id, + /*hidden=*/false, std::make_unique<FrameTokenMessageQueue>()); ui::WindowResizeHelperMac::Get()->Init(base::ThreadTaskRunnerHandle::Get()); // Owned by its |GetInProcessNSView()|, i.e. |rwhv_cocoa|. RenderWidgetHostViewMac* rwhv_mac = - new RenderWidgetHostViewMac(render_widget); + new RenderWidgetHostViewMac(render_widget.get()); base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa( [rwhv_mac->GetInProcessNSView() retain]); @@ -178,9 +179,6 @@ size_t num_edit_commands = [edit_command_strings count]; EXPECT_EQ(delegate.edit_command_message_count_, num_edit_commands); rwhv_cocoa.reset(); - - // The |render_widget|'s process needs to be deleted within |message_loop|. - delete render_widget; } process_host->Cleanup(); ui::WindowResizeHelperMac::Get()->ShutdownForTests();
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm index 2835c78..dd2d010 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -334,12 +334,12 @@ MOCK_METHOD0(Blur, void()); ui::LatencyInfo lastWheelEventLatencyInfo; - static MockRenderWidgetHostImpl* Create( + static std::unique_ptr<MockRenderWidgetHostImpl> Create( RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_group_host, int32_t routing_id) { - return new MockRenderWidgetHostImpl(delegate, agent_scheduling_group_host, - routing_id); + return base::WrapUnique(new MockRenderWidgetHostImpl( + delegate, agent_scheduling_group_host, routing_id)); } MockWidgetInputHandler* input_handler() { return &input_handler_; } @@ -356,7 +356,8 @@ RenderWidgetHostDelegate* delegate, AgentSchedulingGroupHost& agent_scheduling_group_host, int32_t routing_id) - : RenderWidgetHostImpl(delegate, + : RenderWidgetHostImpl(/*self_owned=*/false, + delegate, agent_scheduling_group_host, routing_id, /*hidden=*/false, @@ -492,9 +493,9 @@ process_host_->Init(); agent_scheduling_group_host_ = std::make_unique<AgentSchedulingGroupHost>(*process_host_); - host_ = base::WrapUnique(MockRenderWidgetHostImpl::Create( - &delegate_, *agent_scheduling_group_host_, - process_host_->GetNextRoutingID())); + host_ = MockRenderWidgetHostImpl::Create(&delegate_, + *agent_scheduling_group_host_, + process_host_->GetNextRoutingID()); mojo::AssociatedRemote<blink::mojom::FrameWidgetHost> frame_widget_host; auto frame_widget_host_receiver = frame_widget_host.BindNewEndpointAndPassDedicatedReceiver(); @@ -1327,9 +1328,10 @@ AgentSchedulingGroupHost agent_scheduling_group_host(process_host); MockRenderWidgetHostDelegate delegate; int32_t routing_id = process_host.GetNextRoutingID(); - MockRenderWidgetHostImpl* host = MockRenderWidgetHostImpl::Create( - &delegate, agent_scheduling_group_host, routing_id); - RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host); + std::unique_ptr<MockRenderWidgetHostImpl> host = + MockRenderWidgetHostImpl::Create(&delegate, agent_scheduling_group_host, + routing_id); + RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host.get()); base::RunLoop().RunUntilIdle(); // Send an initial wheel event for scrolling by 3 lines. @@ -1362,7 +1364,8 @@ const base::TimeDelta max_time_between_phase_ended_and_momentum_phase_began = view->max_time_between_phase_ended_and_momentum_phase_began_for_test(); - host->ShutdownAndDestroyWidget(true); + host->ShutdownAndDestroyWidget(false); + host.reset(); // Wait for the mouse_wheel_end_dispatch_timer_ to expire after host is // destroyed. The pending wheel end event won't get dispatched since the @@ -1388,9 +1391,10 @@ AgentSchedulingGroupHost agent_scheduling_group_host(process_host); MockRenderWidgetHostDelegate delegate; int32_t routing_id = process_host.GetNextRoutingID(); - MockRenderWidgetHostImpl* host = MockRenderWidgetHostImpl::Create( - &delegate, agent_scheduling_group_host, routing_id); - RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host); + std::unique_ptr<MockRenderWidgetHostImpl> host = + MockRenderWidgetHostImpl::Create(&delegate, agent_scheduling_group_host, + routing_id); + RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host.get()); base::RunLoop().RunUntilIdle(); // Send an initial wheel event for scrolling by 3 lines. @@ -1430,7 +1434,8 @@ ASSERT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events)); DCHECK(!view->HasPendingWheelEndEventForTesting()); - host->ShutdownAndDestroyWidget(true); + host->ShutdownAndDestroyWidget(false); + host.reset(); process_host.Cleanup(); } @@ -1445,9 +1450,10 @@ MockRenderWidgetHostDelegate delegate; AgentSchedulingGroupHost agent_scheduling_group_host(process_host); int32_t routing_id = process_host.GetNextRoutingID(); - MockRenderWidgetHostImpl* host = MockRenderWidgetHostImpl::Create( - &delegate, agent_scheduling_group_host, routing_id); - RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host); + std::unique_ptr<MockRenderWidgetHostImpl> host = + MockRenderWidgetHostImpl::Create(&delegate, agent_scheduling_group_host, + routing_id); + RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host.get()); base::RunLoop().RunUntilIdle(); // Send an initial wheel event for scrolling by 3 lines. @@ -1488,7 +1494,8 @@ ASSERT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events)); DCHECK(!view->HasPendingWheelEndEventForTesting()); - host->ShutdownAndDestroyWidget(true); + host->ShutdownAndDestroyWidget(false); + host.reset(); process_host.Cleanup(); } @@ -1755,12 +1762,13 @@ child_widget_ = MockRenderWidgetHostImpl::Create( &delegate_, *child_agent_scheduling_group_host_, child_process_host_->GetNextRoutingID()); - child_view_ = new TestRenderWidgetHostView(child_widget_); + child_view_ = new TestRenderWidgetHostView(child_widget_.get()); base::RunLoop().RunUntilIdle(); } void TearDown() override { - child_widget_->ShutdownAndDestroyWidget(true); + child_widget_->ShutdownAndDestroyWidget(false); + child_widget_.reset(); child_process_host_->Cleanup(); child_agent_scheduling_group_host_.reset(); child_process_host_.reset(); @@ -1795,7 +1803,7 @@ protected: std::unique_ptr<MockRenderProcessHost> child_process_host_; std::unique_ptr<AgentSchedulingGroupHost> child_agent_scheduling_group_host_; - MockRenderWidgetHostImpl* child_widget_; + std::unique_ptr<MockRenderWidgetHostImpl> child_widget_; TestRenderWidgetHostView* child_view_; private: @@ -1812,7 +1820,7 @@ // unmarkText would lead to an IPC. This assumption is made in other similar // tests as well). We should observe an IPC being sent to the |child_widget_|. SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); - EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); + EXPECT_EQ(child_widget_.get(), text_input_manager()->GetActiveWidget()); [tab_GetInProcessNSView() unmarkText]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = @@ -1840,7 +1848,7 @@ // Make the child view active and then call setMarkedText with some values. We // should observe an IPC being sent to the |child_widget_|. SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); - EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); + EXPECT_EQ(child_widget_.get(), text_input_manager()->GetActiveWidget()); [tab_GetInProcessNSView() setMarkedText:text selectedRange:selectedRange replacementRange:replacementRange]; @@ -1871,7 +1879,7 @@ // Make the child view active and then call insertText with some values. We // should observe an IPC being sent to the |child_widget_|. SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); - EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); + EXPECT_EQ(child_widget_.get(), text_input_manager()->GetActiveWidget()); [tab_GetInProcessNSView() insertText:text replacementRange:replacementRange]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = @@ -1899,7 +1907,7 @@ // Make child view active and then call finishComposingText. We should observe // an IPC being sent to the |child_widget_|. SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); - EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); + EXPECT_EQ(child_widget_.get(), text_input_manager()->GetActiveWidget()); // In order to finish composing text, we must first have some marked text. So, // we will first call setMarkedText on cocoa view. This would lead to a set // composition IPC in the sink, but it doesn't matter since we will be looking @@ -1941,7 +1949,7 @@ EXPECT_FALSE(ui::ScopedPasswordInputEnabler::IsPasswordInputEnabled()); SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_PASSWORD); - ASSERT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); + ASSERT_EQ(child_widget_.get(), text_input_manager()->GetActiveWidget()); ASSERT_EQ(text_input_manager(), tab_view()->GetTextInputManager()); ASSERT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, tab_view()->GetTextInputType());
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 0e918ff..16d2127 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3719,7 +3719,7 @@ return nullptr; } - RenderWidgetHostImpl* widget_host = new RenderWidgetHostImpl( + RenderWidgetHostImpl* widget_host = RenderWidgetHostImpl::CreateSelfOwned( this, agent_scheduling_group, route_id, IsHidden(), std::make_unique<FrameTokenMessageQueue>());
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc index 4d0b164..faa9ace 100644 --- a/content/common/navigation_params.cc +++ b/content/common/navigation_params.cc
@@ -10,8 +10,7 @@ mojom::InitiatorCSPInfoPtr CreateInitiatorCSPInfo() { return mojom::InitiatorCSPInfo::New( network::mojom::CSPDisposition::CHECK, - std::vector<network::mojom::ContentSecurityPolicyPtr>() /* empty */, - nullptr /* initiator_self_source */ + std::vector<network::mojom::ContentSecurityPolicyPtr>() /* empty */ ); }
diff --git a/content/common/navigation_params.mojom b/content/common/navigation_params.mojom index 38031af..64c4b56 100644 --- a/content/common/navigation_params.mojom +++ b/content/common/navigation_params.mojom
@@ -51,9 +51,8 @@ network.mojom.CSPDisposition should_check_main_world_csp = network.mojom.CSPDisposition.CHECK; - // The relevant CSP policies and the initiator 'self' source to be used. + // The relevant CSP policies. array<network.mojom.ContentSecurityPolicy> initiator_csp; - network.mojom.CSPSource? initiator_self_source; }; enum NavigationType {
diff --git a/content/common/origin_util.cc b/content/common/origin_util.cc index fa76c3e..8654a973 100644 --- a/content/common/origin_util.cc +++ b/content/common/origin_util.cc
@@ -27,8 +27,4 @@ return false; } -bool IsPotentiallyTrustworthyOrigin(const url::Origin& origin) { - return network::IsOriginPotentiallyTrustworthy(origin); -} - } // namespace content
diff --git a/content/common/origin_util_unittest.cc b/content/common/origin_util_unittest.cc deleted file mode 100644 index edbe97f..0000000 --- a/content/common/origin_util_unittest.cc +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/public/common/origin_util.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace content { - -TEST(OriginUtilTest, IsPotentiallyTrustworthyOrigin) { - EXPECT_FALSE( - IsPotentiallyTrustworthyOrigin(url::Origin::Create(GURL("about:blank")))); - EXPECT_FALSE(IsPotentiallyTrustworthyOrigin( - url::Origin::Create(GURL("about:blank#ref")))); - EXPECT_FALSE(IsPotentiallyTrustworthyOrigin( - url::Origin::Create(GURL("about:srcdoc")))); - - EXPECT_FALSE(IsPotentiallyTrustworthyOrigin( - url::Origin::Create(GURL("javascript:alert('blah')")))); - - EXPECT_FALSE(IsPotentiallyTrustworthyOrigin( - url::Origin::Create(GURL("data:test/plain;blah")))); -} - -} // namespace content
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 2021868..21b56c26 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -897,11 +897,6 @@ const char kDisableAcceleratedVideoDecode[] = "disable-accelerated-video-decode"; -#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && !defined(OS_ANDROID) -// Enables hardware acceleration of video decoding on linux. (defaults to off) -const char kEnableAcceleratedVideoDecode[] = "enable-accelerated-video-decode"; -#endif - #if defined(OS_ANDROID) // Disable Media Session API const char kDisableMediaSessionAPI[] = "disable-media-session-api";
diff --git a/content/public/common/origin_util.h b/content/public/common/origin_util.h index d3457a1..7d30bc8 100644 --- a/content/public/common/origin_util.h +++ b/content/public/common/origin_util.h
@@ -16,13 +16,6 @@ // http (localhost only), https, or a custom-set secure scheme. bool CONTENT_EXPORT OriginCanAccessServiceWorkers(const GURL& url); -// This is based on SecurityOrigin::isPotentiallyTrustworthy and tries to mimic -// its behavior. -// -// TODO(https://crbug.com/1153336): Remove this function and use -// network::IsOriginPotentiallyTrustworthy instead. -bool CONTENT_EXPORT IsPotentiallyTrustworthyOrigin(const url::Origin& origin); - } // namespace content #endif // CONTENT_PUBLIC_COMMON_ORIGIN_UTIL_H_
diff --git a/content/renderer/content_security_policy_util.cc b/content/renderer/content_security_policy_util.cc index c933b66..1e2f40a0 100644 --- a/content/renderer/content_security_policy_util.cc +++ b/content/renderer/content_security_policy_util.cc
@@ -36,6 +36,8 @@ const blink::WebContentSecurityPolicy& policy_in) { auto policy = network::mojom::ContentSecurityPolicy::New(); + policy->self_origin = BuildCSPSource(policy_in.self_origin); + policy->header = network::mojom::ContentSecurityPolicyHeader::New( policy_in.header.Utf8(), policy_in.disposition, policy_in.source); policy->use_reporting_api = policy_in.use_reporting_api;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index f1df03c..33e6dfc 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -572,8 +572,6 @@ auto initiator_csp_info = mojom::InitiatorCSPInfo::New(); initiator_csp_info->should_check_main_world_csp = info->should_check_main_world_content_security_policy; - initiator_csp_info->initiator_self_source = - BuildCSPSource(info->initiator_self_source); for (const auto& policy : info->initiator_csp) { initiator_csp_info->initiator_csp.push_back( BuildContentSecurityPolicy(policy));
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index aa0472b..a52c3c7 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -1104,7 +1104,7 @@ const bool enable_video_accelerator = #if defined(OS_LINUX) && !defined(OS_CHROMEOS) - cmd_line->HasSwitch(switches::kEnableAcceleratedVideoDecode) && + base::FeatureList::IsEnabled(media::kVaapiVideoDecodeLinux) && #else !cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode) && #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 3f001ba..1a2db75 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -2065,7 +2065,6 @@ "../common/input/touch_event_stream_validator_unittest.cc", "../common/inter_process_time_ticks_converter_unittest.cc", "../common/net/ip_address_space_util_unittest.cc", - "../common/origin_util_unittest.cc", "../common/service_manager/service_manager_connection_impl_unittest.cc", "../common/service_worker/service_worker_utils_unittest.cc", "../common/state_transitions_unittest.cc",
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc index 112d2bf..40c2219 100644 --- a/content/test/navigation_simulator_impl.cc +++ b/content/test/navigation_simulator_impl.cc
@@ -1176,7 +1176,7 @@ common_params->has_user_gesture = has_user_gesture_; common_params->initiator_csp_info = mojom::InitiatorCSPInfo::New( should_check_main_world_csp_, - std::vector<network::mojom::ContentSecurityPolicyPtr>(), nullptr); + std::vector<network::mojom::ContentSecurityPolicyPtr>()); mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client_remote;
diff --git a/content/test/test_render_widget_host.cc b/content/test/test_render_widget_host.cc index 5e16091..35a7278d 100644 --- a/content/test/test_render_widget_host.cc +++ b/content/test/test_render_widget_host.cc
@@ -25,7 +25,8 @@ AgentSchedulingGroupHost& agent_scheduling_group, int32_t routing_id, bool hidden) - : RenderWidgetHostImpl(delegate, + : RenderWidgetHostImpl(/*self_owned=*/false, + delegate, agent_scheduling_group, routing_id, hidden,
diff --git a/google_apis/drive/drive_common_callbacks.h b/google_apis/drive/drive_common_callbacks.h index 67674a4..cccf52f8c 100644 --- a/google_apis/drive/drive_common_callbacks.h +++ b/google_apis/drive/drive_common_callbacks.h
@@ -25,9 +25,6 @@ // request is already finished, nothing happens. typedef base::OnceClosure CancelCallbackOnce; typedef base::RepeatingClosure CancelCallbackRepeating; -// TODO(https://crbug.com/1007686): Remove usage of CancelCallback. -// All remaining usages are outside of google_apis/drive. -typedef base::Closure CancelCallback; } // namespace google_apis
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index a059662..b9e0e53 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -20340,7 +20340,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 21600 + execution_timeout_secs: 25200 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -21461,7 +21461,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 21600 + execution_timeout_secs: 25200 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments {
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index a607a0a..75f620c8 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -1235,7 +1235,9 @@ ), cores = 32, os = os.WINDOWS_DEFAULT, - execution_timeout = 6 * time.hour, + # TODO(crbug.com/1155416): + # builds with PGO change take long time. + execution_timeout = 7 * time.hour, tree_closing = False, ) @@ -1272,7 +1274,9 @@ ), cores = 32, os = os.WINDOWS_DEFAULT, - execution_timeout = 6 * time.hour, + # TODO(crbug.com/1155416): + # builds with PGO change take long time. + execution_timeout = 7 * time.hour, tree_closing = False, )
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/full_card_request_result_delegate_bridge.h b/ios/chrome/browser/ui/autofill/manual_fill/full_card_request_result_delegate_bridge.h index 70dbf67..10c0868 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/full_card_request_result_delegate_bridge.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/full_card_request_result_delegate_bridge.h
@@ -43,7 +43,8 @@ const autofill::payments::FullCardRequest& full_card_request, const autofill::CreditCard& card, const base::string16& cvc) override; - void OnFullCardRequestFailed() override; + void OnFullCardRequestFailed( + autofill::payments::FullCardRequest::FailureType failure_type) override; __weak id<FullCardRequestResultDelegateObserving> delegate_ = nil; base::WeakPtrFactory<FullCardRequestResultDelegateBridge> weak_ptr_factory_;
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/full_card_request_result_delegate_bridge.mm b/ios/chrome/browser/ui/autofill/manual_fill/full_card_request_result_delegate_bridge.mm index 5aa41ed..06a0907 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/full_card_request_result_delegate_bridge.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/full_card_request_result_delegate_bridge.mm
@@ -32,6 +32,7 @@ [delegate_ onFullCardRequestSucceeded:card]; } -void FullCardRequestResultDelegateBridge::OnFullCardRequestFailed() { +void FullCardRequestResultDelegateBridge::OnFullCardRequestFailed( + autofill::payments::FullCardRequest::FailureType /* failure_type */) { [delegate_ onFullCardRequestFailed]; }
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester_unittest.mm b/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester_unittest.mm index f8bb7ec6..326b4b9 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester_unittest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester_unittest.mm
@@ -46,7 +46,9 @@ const autofill::CreditCard& card, const base::string16& cvc) override {} - void OnFullCardRequestFailed() override {} + void OnFullCardRequestFailed( + autofill::payments::FullCardRequest::FailureType /* failure_type */) + override {} base::WeakPtr<FakeResultDelegate> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr();
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm index 24b1605..ef480f30 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm
@@ -254,8 +254,7 @@ assertWithMatcher:grey_nil()]; } -// TODO(crbug.com/1037651): Test fails. -- (void)DISABLED_testCloseNTPWhenSwitching { +- (void)testCloseNTPWhenSwitching { // Open the first page. GURL URL1 = self.testServer->GetURL(kPage1URL); [ChromeEarlGrey loadURL:URL1];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_view_controller.mm index d0ccb1b..b240302 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_view_controller.mm
@@ -27,7 +27,6 @@ // Default image insets for the new tab button. const CGFloat kNewTabButtonLeadingImageInset = -10.0; const CGFloat kNewTabButtonBottomImageInset = -2.0; - } // namespace @interface TabStripViewController () <TabStripCellDelegate> @@ -40,6 +39,9 @@ @property(nonatomic, copy) NSString* selectedItemID; // Index of the selected item in |items|. @property(nonatomic, readonly) NSUInteger selectedIndex; +// Constraints that are used when the button needs to be kept next to the last +// cell. +@property NSLayoutConstraint* lastCellConstraint; @end @@ -72,7 +74,7 @@ [self.view addSubview:self.buttonNewTab]; [NSLayoutConstraint activateConstraints:@[ [self.buttonNewTab.trailingAnchor - constraintEqualToAnchor:self.view.trailingAnchor], + constraintLessThanOrEqualToAnchor:self.view.trailingAnchor], [self.buttonNewTab.topAnchor constraintEqualToAnchor:self.view.topAnchor], [self.buttonNewTab.heightAnchor constraintEqualToAnchor:self.view.heightAnchor], @@ -80,6 +82,11 @@ constraintEqualToConstant:kNewTabButtonWidth], ]]; + self.lastCellConstraint = [self.buttonNewTab.leadingAnchor + constraintEqualToAnchor:self.view.trailingAnchor]; + self.lastCellConstraint.priority = UILayoutPriorityDefaultHigh; + self.lastCellConstraint.active = YES; + [self.buttonNewTab addTarget:self action:@selector(sendNewTabCommand) forControlEvents:UIControlEventTouchUpInside]; @@ -110,6 +117,29 @@ return cell; } +- (void)collectionView:(UICollectionView*)collectionView + willDisplayCell:(UICollectionViewCell*)cell + forItemAtIndexPath:(NSIndexPath*)indexPath { + NSInteger numberOfItems = [self collectionView:collectionView + numberOfItemsInSection:indexPath.section]; + if (indexPath.row == numberOfItems - 1) { + // Adding a constant to the button's contraints to keep it next to the last + // cell using the given collectionView and cell. + CGFloat newConstant = -(collectionView.bounds.size.width - + (cell.frame.origin.x + cell.frame.size.width)); + self.lastCellConstraint.constant = newConstant; + } +} + +- (void)scrollViewDidScroll:(UIScrollView*)scrollView { + // Adding a constant to the button's contraints to keep it next to the last + // cell while scrolling with given scrollView. + CGFloat newConstant = scrollView.contentSize.width - + scrollView.contentOffset.x - + scrollView.bounds.size.width; + self.lastCellConstraint.constant = newConstant; +} + #pragma mark - TabStripConsumer - (void)populateItems:(NSArray<TabSwitcherItem*>*)items
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 index 0b9a5cc8..0b11282 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -e8cc68e7f0a9462e7fe5176f72c0472b0d43f798 \ No newline at end of file +2b3d204e5918d247b8e90f73e12835955dcc58d5 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 index 3a6af793..9e1deefc 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -8b4ba9ac6d9db8818ca21e0da16edf6c9b7596b6 \ No newline at end of file +1315245f706a6c58602a83f60bf2a1ad1220a44d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 index 3cad4a7..b242833 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -07706cc502d4e96f8cd467cc21928fac20f2ad5e \ No newline at end of file +1389d75fb3829ebedeae6955b19b41a21dcd93e1 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 index 7e6a680..ea84dcf 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -196af581649bc19a3ec986a79f3dea7785abbf3d \ No newline at end of file +2980294d0e3dcd2d0bf77b9d0141398d109b0246 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 index 521ef566..04bd590 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -2794e08bd996f366ef29661aec67b2ac55f1d36d \ No newline at end of file +9453ec87331f63de623d0482efa16c3036c7ca86 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 index 173fe76..68ca5c1a 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -9f82383e0b823c90af30e49bee1b0f175d24f72d \ No newline at end of file +5dfe95b60108c50d96450b9b22a1b997b7dd8ca7 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 index 5b2b871..6596e1c 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -5cc00d13e041eddf6ecb6d24097c1d3680c6fba1 \ No newline at end of file +0a0913037c289c2a95507ace0e373259b847fc2f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 index b30de96..4c6355b 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -f2a5782397ad41a258e4d1a4fe6c5ac3449c9ed7 \ No newline at end of file +ce6382cadc89ca61b10f8e6b2ab2c18b88af2b5f \ No newline at end of file
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index b789187..be4e0f6 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -428,6 +428,13 @@ const base::Feature kUnifiedAutoplay{"UnifiedAutoplay", base::FEATURE_ENABLED_BY_DEFAULT}; +#if (defined(OS_LINUX) || defined(OS_FREEBSD)) && !defined(OS_CHROMEOS) +// Enable vaapi video decoding on linux. This is already enabled by default on +// chromeos, but needs an experiment on linux. +const base::Feature kVaapiVideoDecodeLinux{"VaapiVideoDecoder", + base::FEATURE_DISABLED_BY_DEFAULT}; +#endif // (defined(OS_LINUX) || defined(OS_FREEBSD)) && !defined(OS_CHROMEOS) + // Enable VA-API hardware decode acceleration for AV1. const base::Feature kVaapiAV1Decoder{"VaapiAV1Decoder", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index f83346d..1b6792e 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -171,6 +171,9 @@ MEDIA_EXPORT extern const base::Feature kUseMediaHistoryStore; MEDIA_EXPORT extern const base::Feature kUseR16Texture; MEDIA_EXPORT extern const base::Feature kUseSodaForLiveCaption; +#if (defined(OS_LINUX) || defined(OS_FREEBSD)) && !defined(OS_CHROMEOS) +MEDIA_EXPORT extern const base::Feature kVaapiVideoDecodeLinux; +#endif // (defined(OS_LINUX) || defined(OS_FREEBSD)) && !defined(OS_CHROMEOS) MEDIA_EXPORT extern const base::Feature kVaapiAV1Decoder; MEDIA_EXPORT extern const base::Feature kVaapiLowPowerEncoderGen9x; MEDIA_EXPORT extern const base::Feature kVaapiEnforceVideoMinMaxResolution;
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index ed32389..ed4238b 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -456,7 +456,23 @@ DCHECK_LE(bytes_per_row, std::abs(dest_stride_uv)); DCHECK_EQ(0, first_row % 2); DCHECK(source_frame->format() == PIXEL_FORMAT_I420 || - source_frame->format() == PIXEL_FORMAT_YV12); + source_frame->format() == PIXEL_FORMAT_YV12 || + source_frame->format() == PIXEL_FORMAT_NV12); + if (source_frame->format() == PIXEL_FORMAT_NV12) { + libyuv::CopyPlane(source_frame->visible_data(VideoFrame::kYPlane) + + first_row * source_frame->stride(VideoFrame::kYPlane), + source_frame->stride(VideoFrame::kYPlane), + dest_y + first_row * dest_stride_y, dest_stride_y, + bytes_per_row, rows); + libyuv::CopyPlane( + source_frame->visible_data(VideoFrame::kUVPlane) + + first_row / 2 * source_frame->stride(VideoFrame::kUVPlane), + source_frame->stride(VideoFrame::kUVPlane), + dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, bytes_per_row, + rows / 2); + + return; + } libyuv::I420ToNV12( source_frame->visible_data(VideoFrame::kYPlane) + first_row * source_frame->stride(VideoFrame::kYPlane), @@ -642,6 +658,12 @@ if (!IOSurfaceCanSetColorSpace(video_frame->ColorSpace())) passthrough = true; #endif + + if (!video_frame->IsMappable()) { + // Already a hardware frame. + passthrough = true; + } + if (output_format_ == GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED) passthrough = true; switch (pixel_format) { @@ -650,11 +672,11 @@ case PIXEL_FORMAT_I420: case PIXEL_FORMAT_YUV420P10: case PIXEL_FORMAT_I420A: + case PIXEL_FORMAT_NV12: break; // Unsupported cases. case PIXEL_FORMAT_I422: case PIXEL_FORMAT_I444: - case PIXEL_FORMAT_NV12: case PIXEL_FORMAT_NV21: case PIXEL_FORMAT_UYVY: case PIXEL_FORMAT_YUY2:
diff --git a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc index e9821951..6ffe20d 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
@@ -116,6 +116,30 @@ return video_frame; } + static scoped_refptr<VideoFrame> CreateTestNV12VideoFrame(int dimension) { + const int kDimension = 10; + static uint8_t y_data[kDimension * kDimension] = {0}; + // Subsampled by 2x2, two components. + static uint8_t uv_data[kDimension * kDimension / 2] = {0}; + + const VideoPixelFormat format = PIXEL_FORMAT_NV12; + DCHECK_LE(dimension, kDimension); + const gfx::Size size(dimension, dimension); + + scoped_refptr<VideoFrame> video_frame = + VideoFrame::WrapExternalYuvData(format, // format + size, // coded_size + gfx::Rect(size), // visible_rect + size, // natural_size + size.width(), // y_stride + size.width(), // uv_stride + y_data, // y_data + uv_data, // uv_data + base::TimeDelta()); // timestamp + EXPECT_TRUE(video_frame); + return video_frame; + } + // Note, the X portion is set to 1 since it may use ARGB instead of // XRGB on some platforms. uint32_t as_xr30(uint32_t r, uint32_t g, uint32_t b) { @@ -304,6 +328,22 @@ EXPECT_TRUE(frame->metadata()->read_lock_fences_enabled); } +TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareFrameForNV12Input) { + scoped_refptr<VideoFrame> software_frame = CreateTestNV12VideoFrame(10); + scoped_refptr<VideoFrame> frame; + mock_gpu_factories_->SetVideoFrameOutputFormat( + media::GpuVideoAcceleratorFactories::OutputFormat::NV12_DUAL_GMB); + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::BindOnce(MaybeCreateHardwareFrameCallback, &frame)); + + RunUntilIdle(); + + EXPECT_NE(software_frame.get(), frame.get()); + EXPECT_EQ(PIXEL_FORMAT_NV12, frame->format()); + EXPECT_EQ(2u, frame->NumTextures()); + EXPECT_EQ(2u, sii_->shared_image_count()); +} + TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareXR30Frame) { scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10, 10); scoped_refptr<VideoFrame> frame;
diff --git a/media/video/vpx_video_encoder.cc b/media/video/vpx_video_encoder.cc index 7e23a78..15f6c948 100644 --- a/media/video/vpx_video_encoder.cc +++ b/media/video/vpx_video_encoder.cc
@@ -228,6 +228,7 @@ } options_ = options; + originally_configured_size_ = options.frame_size; output_cb_ = BindToCurrentLoop(std::move(output_cb)); codec_ = std::move(codec); std::move(done_cb).Run(Status()); @@ -356,18 +357,42 @@ return; } - auto old_area = options_.frame_size.GetCheckedArea(); - auto new_area = options.frame_size.GetCheckedArea(); - DCHECK(old_area.IsValid()); - - // Libvpx doesn't support reconfiguring in a way that enlarges frame area. - // https://bugs.chromium.org/p/webm/issues/detail?id=1642 - if (!new_area.IsValid() || new_area.ValueOrDie() > old_area.ValueOrDie()) { - auto status = - Status(StatusCode::kEncoderUnsupportedConfig, - "libvpx doesn't support dynamically increasing frame area"); - std::move(done_cb).Run(std::move(status)); - return; + // Libvpx is very peculiar about encoded frame size changes, + // - VP8: As long as the frame area doesn't increase, internal codec + // structures don't need to be reallocated and codec can be simply + // reconfigured. + // - VP9: The codec cannot increase encoded width or height larger than their + // initial values. + // + // Mind the difference between old frame sizes: + // - |originally_configured_size_| is set only once when the vpx_codec_ctx_t + // is created. + // - |options_.frame_size| changes every time ChangeOptions() is called. + // More info can be found here: + // https://bugs.chromium.org/p/webm/issues/detail?id=1642 + // https://bugs.chromium.org/p/webm/issues/detail?id=912 + if (profile_ == VP8PROFILE_ANY) { + // VP8 resize restrictions + auto old_area = originally_configured_size_.GetCheckedArea(); + auto new_area = options.frame_size.GetCheckedArea(); + DCHECK(old_area.IsValid()); + if (!new_area.IsValid() || new_area.ValueOrDie() > old_area.ValueOrDie()) { + auto status = Status( + StatusCode::kEncoderUnsupportedConfig, + "libvpx/VP8 doesn't support dynamically increasing frame area"); + std::move(done_cb).Run(std::move(status)); + return; + } + } else { + // VP9 resize restrictions + if (options.frame_size.width() > originally_configured_size_.width() || + options.frame_size.height() > originally_configured_size_.height()) { + auto status = Status( + StatusCode::kEncoderUnsupportedConfig, + "libvpx/VP9 doesn't support dynamically increasing frame dimentions"); + std::move(done_cb).Run(std::move(status)); + return; + } } vpx_codec_enc_cfg_t new_config = codec_config_;
diff --git a/media/video/vpx_video_encoder.h b/media/video/vpx_video_encoder.h index eee7a1d..cd5a17b 100644 --- a/media/video/vpx_video_encoder.h +++ b/media/video/vpx_video_encoder.h
@@ -44,6 +44,7 @@ bool is_vp9_ = false; vpx_codec_enc_cfg_t codec_config_ = {}; vpx_image_t vpx_image_ = {}; + gfx::Size originally_configured_size_; base::TimeDelta last_frame_timestamp_; VideoCodecProfile profile_ = VIDEO_CODEC_PROFILE_UNKNOWN; Options options_;
diff --git a/remoting/codec/webrtc_video_encoder_gpu.cc b/remoting/codec/webrtc_video_encoder_gpu.cc index 30958ed..28ff19b 100644 --- a/remoting/codec/webrtc_video_encoder_gpu.cc +++ b/remoting/codec/webrtc_video_encoder_gpu.cc
@@ -275,6 +275,17 @@ // static bool WebrtcVideoEncoderGpu::IsSupportedByH264( const WebrtcVideoEncoderSelector::Profile& profile) { +#if defined(OS_WIN) + // This object is required by Chromium to ensure proper init/uninit of COM on + // this thread. The guidance is to match the lifetime of this object to the + // lifetime of the thread if possible. Since we are still experimenting with + // H.264 and run the encoder on a different thread, we use a locally scoped + // object for now. + // TODO(joedow): Use a COMscoped Autothread (or run in a separate process) if + // H.264 becomes a common use case for us. + base::win::ScopedCOMInitializer scoped_com_initializer; +#endif + media::VideoEncodeAccelerator::SupportedProfiles profiles = media::GpuVideoEncodeAcceleratorFactory::GetSupportedProfiles( CreateGpuPreferences(), CreateGpuWorkarounds());
diff --git a/remoting/codec/webrtc_video_encoder_gpu.h b/remoting/codec/webrtc_video_encoder_gpu.h index e862647..bbcfdc7 100644 --- a/remoting/codec/webrtc_video_encoder_gpu.h +++ b/remoting/codec/webrtc_video_encoder_gpu.h
@@ -7,11 +7,16 @@ #include "base/memory/shared_memory_mapping.h" #include "base/memory/unsafe_shared_memory_region.h" +#include "build/build_config.h" #include "media/video/video_encode_accelerator.h" #include "remoting/codec/encoder_bitrate_filter.h" #include "remoting/codec/webrtc_video_encoder.h" #include "remoting/codec/webrtc_video_encoder_selector.h" +#if defined(OS_WIN) +#include "base/win/scoped_com_initializer.h" +#endif + namespace remoting { // A WebrtcVideoEncoder implementation utilizing the VideoEncodeAccelerator @@ -72,6 +77,17 @@ void RunAnyPendingEncode(); +#if defined(OS_WIN) + // This object is required by Chromium to ensure proper init/uninit of COM on + // this thread. The guidance is to match the lifetime of this object to the + // lifetime of the thread if possible. Since we are still experimenting with + // H.264 and run the encoder on a different thread, we use an object-lifetime + // scoped instance for now. + // TODO(joedow): Use a COMscoped Autothread (or run in a separate process) if + // H.264 becomes a common use case for us. + base::win::ScopedCOMInitializer scoped_com_initializer_; +#endif + State state_; // Only after the first encode request do we know how large the incoming
diff --git a/services/media_session/public/cpp/test/mock_media_session.cc b/services/media_session/public/cpp/test/mock_media_session.cc index 28fc9fb..1ac3d61 100644 --- a/services/media_session/public/cpp/test/mock_media_session.cc +++ b/services/media_session/public/cpp/test/mock_media_session.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" namespace media_session { @@ -66,10 +67,14 @@ expected_controllable_ == session_info_->is_controllable) { run_loop_->Quit(); expected_controllable_.reset(); - } else if (wanted_state_ == session_info_->state || - session_info_->playback_state == wanted_playback_state_ || - session_info_->audio_video_state == wanted_audio_video_state_) { - run_loop_->Quit(); + } else { + if (wanted_state_ == session_info_->state || + session_info_->playback_state == wanted_playback_state_ || + (wanted_audio_video_states_ && + base::ranges::is_permutation(*session_info_->audio_video_states, + *wanted_audio_video_states_))) { + run_loop_->Quit(); + } } } @@ -151,12 +156,14 @@ StartWaiting(); } -void MockMediaSessionMojoObserver::WaitForAudioVideoState( - mojom::MediaAudioVideoState wanted_state) { - if (session_info_ && session_info_->audio_video_state == wanted_state) +void MockMediaSessionMojoObserver::WaitForAudioVideoStates( + const std::vector<mojom::MediaAudioVideoState>& wanted_states) { + if (session_info_ && base::ranges::is_permutation( + *session_info_->audio_video_states, wanted_states)) { return; + } - wanted_audio_video_state_ = wanted_state; + wanted_audio_video_states_ = wanted_states; StartWaiting(); }
diff --git a/services/media_session/public/cpp/test/mock_media_session.h b/services/media_session/public/cpp/test/mock_media_session.h index f1401bc..878ca1f 100644 --- a/services/media_session/public/cpp/test/mock_media_session.h +++ b/services/media_session/public/cpp/test/mock_media_session.h
@@ -50,7 +50,12 @@ void WaitForState(mojom::MediaSessionInfo::SessionState wanted_state); void WaitForPlaybackState(mojom::MediaPlaybackState wanted_state); - void WaitForAudioVideoState(mojom::MediaAudioVideoState wanted_state); + + // Blocks until the set of audio/video states for the players in the media + // session matches |wanted_states|. The order is not important. + void WaitForAudioVideoStates( + const std::vector<mojom::MediaAudioVideoState>& wanted_states); + void WaitForControllable(bool is_controllable); void WaitForEmptyMetadata(); @@ -116,7 +121,8 @@ base::Optional<mojom::MediaSessionInfo::SessionState> wanted_state_; base::Optional<mojom::MediaPlaybackState> wanted_playback_state_; - base::Optional<mojom::MediaAudioVideoState> wanted_audio_video_state_; + base::Optional<std::vector<mojom::MediaAudioVideoState>> + wanted_audio_video_states_; std::unique_ptr<base::RunLoop> run_loop_; mojo::Receiver<mojom::MediaSessionObserver> receiver_{this};
diff --git a/services/media_session/public/mojom/media_session.mojom b/services/media_session/public/mojom/media_session.mojom index bec4b5f8..f3a833a 100644 --- a/services/media_session/public/mojom/media_session.mojom +++ b/services/media_session/public/mojom/media_session.mojom
@@ -9,7 +9,7 @@ import "ui/gfx/geometry/mojom/geometry.mojom"; import "url/mojom/url.mojom"; -// Next MinVersion: 10 +// Next MinVersion: 11 [Stable, Extensible] enum MediaPlaybackState { @@ -51,9 +51,12 @@ [Stable, Extensible] enum MediaAudioVideoState { - kUnknown, + // Unused as of version 10, see |audio_video_states|. + kDeprecatedUnknown, + kAudioOnly, kAudioVideo, + [MinVersion=10] kVideoOnly, }; // Album art in MediaMetadata @@ -151,12 +154,16 @@ [MinVersion=7] MediaPictureInPictureState picture_in_picture_state; // The audio/video state of the Media Session (if known). - [MinVersion=8] MediaAudioVideoState audio_video_state; + // DEPRECATED, use |audio_video_states| instead. + [MinVersion=8] MediaAudioVideoState deprecated_audio_video_state; // The audio_sink_id tells the client the device_id of the audio output device // being used for this media session. A null audio_sink_id implies that the // default device is being used. [MinVersion=9] string? audio_sink_id; + + // The audio/video states of all the players in the Media Session (if known). + [MinVersion=10] array<MediaAudioVideoState>? audio_video_states; }; // Contains debugging information about a MediaSession. This will be displayed
diff --git a/services/network/public/cpp/content_security_policy/content_security_policy.cc b/services/network/public/cpp/content_security_policy/content_security_policy.cc index 3e0d759..84aeebcd 100644 --- a/services/network/public/cpp/content_security_policy/content_security_policy.cc +++ b/services/network/public/cpp/content_security_policy/content_security_policy.cc
@@ -214,7 +214,7 @@ // ensure that these are not transmitted between different cross-origin // renderers. GURL blocked_url = (directive_name == CSPDirectiveName::FrameAncestors) - ? GURL(ToString(context->self_source())) + ? GURL(ToString(*policy->self_origin)) : url; auto safe_source_location = source_location ? source_location->Clone() : mojom::SourceLocation::New(); @@ -842,6 +842,20 @@ } } +mojom::CSPSourcePtr ComputeSelfOrigin(const GURL& url) { + if (url.scheme() == url::kFileScheme) { + // Forget the host for file schemes. Host can anyway only be `localhost` or + // empty and this is platform dependent. + // + // TODO(antoniosartori): Consider returning mojom::CSPSource::New() for + // file: urls, so that 'self' for file: would match nothing. + return mojom::CSPSource::New(url::kFileScheme, "", url::PORT_UNSPECIFIED, + "", false, false); + } + return mojom::CSPSource::New(url.scheme(), url.host(), url.EffectiveIntPort(), + "", false, false); +} + void AddContentSecurityPolicyFromHeader(base::StringPiece header, mojom::ContentSecurityPolicyType type, const GURL& base_url, @@ -849,6 +863,7 @@ DirectivesMap directives = ParseHeaderValue(header); out->header = mojom::ContentSecurityPolicyHeader::New( header.as_string(), type, mojom::ContentSecurityPolicySource::kHTTP); + out->self_origin = ComputeSelfOrigin(base_url); for (auto directive : directives) { if (!base::ranges::all_of(directive.first, IsDirectiveNameCharacter)) { @@ -1116,6 +1131,8 @@ CSPContext* context, const mojom::SourceLocationPtr& source_location, bool is_form_submission) { + DCHECK(policy->self_origin); + if (ShouldBypassContentSecurityPolicy(context, directive_name, url)) return true; @@ -1135,7 +1152,7 @@ continue; const auto& source_list = directive->second; - bool allowed = CheckCSPSourceList(source_list, url, context, + bool allowed = CheckCSPSourceList(*source_list, url, *(policy->self_origin), has_followed_redirect, is_response_check); if (!allowed) { @@ -1189,7 +1206,6 @@ bool IsValidRequiredCSPAttr( const std::vector<mojom::ContentSecurityPolicyPtr>& policy, const mojom::ContentSecurityPolicy* context, - const url::Origin& origin, std::string& error_message) { DCHECK(policy.size() == 1); if (!policy[0]) @@ -1203,14 +1219,18 @@ return false; } - if (!policy[0]->report_endpoints.empty()) { + if (!policy[0]->report_endpoints.empty() || + // We really don't want any report directives, even with invalid/missing + // endpoints. + policy[0]->raw_directives.contains(mojom::CSPDirectiveName::ReportURI) || + policy[0]->raw_directives.contains(mojom::CSPDirectiveName::ReportTo)) { error_message = "The csp attribute cannot contain the directives 'report-to' or " "'report-uri'."; return false; } - if (context && !Subsumes(*context, policy, origin)) { + if (context && !Subsumes(*context, policy)) { error_message = "The csp attribute Content-Security-Policy is not subsumed by the " "frame's parent csp attribute Content-Security-Policy."; @@ -1221,8 +1241,7 @@ } bool Subsumes(const mojom::ContentSecurityPolicy& policy_a, - const std::vector<mojom::ContentSecurityPolicyPtr>& policies_b, - const url::Origin& origin_b) { + const std::vector<mojom::ContentSecurityPolicyPtr>& policies_b) { if (policy_a.header->type == mojom::ContentSecurityPolicyType::kReport) return true; @@ -1234,6 +1253,9 @@ if (policies_b.empty()) return false; + // All policies in |policies_b| must have the same self_origin. + mojom::CSPSource* origin_b = policies_b[0]->self_origin.get(); + // A list of directives that we consider for subsumption. // See more about source lists here: // https://w3c.github.io/webappsec-csp/#framework-directive-source-list
diff --git a/services/network/public/cpp/content_security_policy/content_security_policy.h b/services/network/public/cpp/content_security_policy/content_security_policy.h index 3f2eaa6..80b967e 100644 --- a/services/network/public/cpp/content_security_policy/content_security_policy.h +++ b/services/network/public/cpp/content_security_policy/content_security_policy.h
@@ -11,10 +11,6 @@ class GURL; -namespace url { -class Origin; -} - namespace net { class HttpResponseHeaders; } @@ -83,16 +79,13 @@ bool IsValidRequiredCSPAttr( const std::vector<mojom::ContentSecurityPolicyPtr>& policy, const mojom::ContentSecurityPolicy* context, - const url::Origin& url, std::string& error_message); -// Checks whether |policy_a| subsumes the policy list -// |policies_b| with origin |origin_b| according to the algorithm -// https://w3c.github.io/webappsec-cspee/#subsume-policy-list. +// Checks whether |policy_a| subsumes the policy list |policies_b| according to +// the algorithm https://w3c.github.io/webappsec-cspee/#subsume-policy-list. COMPONENT_EXPORT(NETWORK_CPP) bool Subsumes(const mojom::ContentSecurityPolicy& policy_a, - const std::vector<mojom::ContentSecurityPolicyPtr>& policies_b, - const url::Origin& origin_b); + const std::vector<mojom::ContentSecurityPolicyPtr>& policies_b); COMPONENT_EXPORT(NETWORK_CPP) mojom::CSPDirectiveName ToCSPDirectiveName(const std::string& name);
diff --git a/services/network/public/cpp/content_security_policy/content_security_policy_unittest.cc b/services/network/public/cpp/content_security_policy/content_security_policy_unittest.cc index 5fd66f4..ecb2239 100644 --- a/services/network/public/cpp/content_security_policy/content_security_policy_unittest.cc +++ b/services/network/public/cpp/content_security_policy/content_security_policy_unittest.cc
@@ -114,6 +114,8 @@ mojom::ContentSecurityPolicyPtr EmptyCSP() { auto policy = mojom::ContentSecurityPolicy::New(); policy->header = mojom::ContentSecurityPolicyHeader::New(); + policy->self_origin = network::mojom::CSPSource::New( + "", "", url::PORT_UNSPECIFIED, "", false, false); return policy; } @@ -880,6 +882,40 @@ } } +TEST(ContentSecurityPolicy, ParseStoresSelfOrigin) { + struct { + const char* url; + network::mojom::CSPSourcePtr self_origin; + } testCases[]{ + { + "https://example.com", + network::mojom::CSPSource::New("https", "example.com", 443, "", false, + false), + }, + { + "http://example.com/main/index.html", + network::mojom::CSPSource::New("http", "example.com", 80, "", false, + false), + }, + { + "file://localhost/var/www/index.html", + network::mojom::CSPSource::New("file", "", url::PORT_UNSPECIFIED, "", + false, false), + }, + }; + + for (const auto& testCase : testCases) { + scoped_refptr<net::HttpResponseHeaders> headers( + new net::HttpResponseHeaders("HTTP/1.1 200 OK")); + headers->SetHeader("Content-Security-Policy", "default-src 'none'"); + std::vector<mojom::ContentSecurityPolicyPtr> policies; + AddContentSecurityPolicyFromHeaders(*headers, GURL(testCase.url), + &policies); + + EXPECT_TRUE(testCase.self_origin.Equals(policies[0]->self_origin)); + } +} + // Check URL are upgraded iif "upgrade-insecure-requests" directive is defined. TEST(ContentSecurityPolicy, ShouldUpgradeInsecureRequest) { std::vector<mojom::ContentSecurityPolicyPtr> policies; @@ -1135,7 +1171,6 @@ csp->allow_response_redirects = true; return csp; }; - context.SetSelf(source_a()); struct TestCase { mojom::CSPSourceListPtr navigate_to_list; @@ -1174,6 +1209,7 @@ for (auto& test : cases) { auto policy = EmptyCSP(); + policy->self_origin = source_a().Clone(); policy->directives[CSPDirectiveName::NavigateTo] = std::move(test.navigate_to_list); @@ -1407,10 +1443,7 @@ AddContentSecurityPolicyFromHeaders(*required_csp_headers, GURL("https://example.com/"), &csp); std::string out; - EXPECT_EQ( - test.expected, - IsValidRequiredCSPAttr( - csp, nullptr, url::Origin::Create(GURL("https://a.com")), out)); + EXPECT_EQ(test.expected, IsValidRequiredCSPAttr(csp, nullptr, out)); EXPECT_EQ(test.expected_error, out); } } @@ -1460,9 +1493,7 @@ std::vector<mojom::ContentSecurityPolicyPtr> returned_csp; AddContentSecurityPolicyFromHeaders( *returned_csp_headers, GURL("https://example.com/"), &returned_csp); - EXPECT_EQ(test.expected, - Subsumes(*required_csp[0], returned_csp, - url::Origin::Create(GURL("https://a.com")))) + EXPECT_EQ(test.expected, Subsumes(*required_csp[0], returned_csp)) << test.name; } } @@ -1526,16 +1557,13 @@ for (const auto& test : cases) { std::vector<mojom::ContentSecurityPolicyPtr> policies_b = ParseCSP(test.policies); - EXPECT_EQ(Subsumes(*policy_a[0], policies_b, - url::Origin::Create(GURL("https://a.com"))), - test.expected) + EXPECT_EQ(Subsumes(*policy_a[0], policies_b), test.expected) << csp_a << " should " << (test.expected ? "" : "not ") << "subsume " << test.policies; if (!policies_b.empty()) { // Check if first policy of `listB` subsumes `A`. - EXPECT_EQ(Subsumes(*policies_b[0], policy_a, - url::Origin::Create(GURL("https://a.com"))), + EXPECT_EQ(Subsumes(*policies_b[0], policy_a), test.expected_first_policy_opposite) << csp_a << " should " << (test.expected_first_policy_opposite ? "" : "not ") << "subsume " @@ -1624,9 +1652,7 @@ ParseCSP(test.policy_a); std::vector<mojom::ContentSecurityPolicyPtr> policies_b = ParseCSP(test.policies_b); - EXPECT_EQ(Subsumes(*policy_a[0], policies_b, - url::Origin::Create(GURL("https://a.com"))), - test.expected) + EXPECT_EQ(Subsumes(*policy_a[0], policies_b), test.expected) << test.policy_a << " should " << (test.expected ? "" : "not ") << "subsume " << test.policies_b; } @@ -1696,9 +1722,7 @@ ParseCSP(test.policy_a); std::vector<mojom::ContentSecurityPolicyPtr> policies_b = ParseCSP(test.policies_b); - EXPECT_EQ(Subsumes(*policy_a[0], policies_b, - url::Origin::Create(GURL("https://a.com"))), - test.expected) + EXPECT_EQ(Subsumes(*policy_a[0], policies_b), test.expected) << test.policy_a << " should " << (test.expected ? "" : "not ") << "subsume " << test.policies_b; }
diff --git a/services/network/public/cpp/content_security_policy/csp_context.cc b/services/network/public/cpp/content_security_policy/csp_context.cc index ee5a5d5..c9d24fa6 100644 --- a/services/network/public/cpp/content_security_policy/csp_context.cc +++ b/services/network/public/cpp/content_security_policy/csp_context.cc
@@ -5,8 +5,6 @@ #include "services/network/public/cpp/content_security_policy/csp_context.h" #include "services/network/public/cpp/content_security_policy/content_security_policy.h" -#include "url/origin.h" - namespace network { namespace { @@ -53,32 +51,6 @@ return allow; } -void CSPContext::SetSelf(const url::Origin& origin) { - self_source_.reset(); - - // When the origin is unique, no URL should match with 'self'. That's why - // |self_source_| stays undefined here. - if (origin.opaque()) - return; - - if (origin.scheme() == url::kFileScheme) { - self_source_ = mojom::CSPSource::New( - url::kFileScheme, "", url::PORT_UNSPECIFIED, "", false, false); - return; - } - - self_source_ = mojom::CSPSource::New( - origin.scheme(), origin.host(), - origin.port() == 0 ? url::PORT_UNSPECIFIED : origin.port(), "", false, - false); - - DCHECK_NE("", self_source_->scheme); -} - -void CSPContext::SetSelf(mojom::CSPSourcePtr self_source) { - self_source_ = std::move(self_source); -} - bool CSPContext::SchemeShouldBypassCSP(const base::StringPiece& scheme) { return false; }
diff --git a/services/network/public/cpp/content_security_policy/csp_context.h b/services/network/public/cpp/content_security_policy/csp_context.h index 968b39d..485dddc 100644 --- a/services/network/public/cpp/content_security_policy/csp_context.h +++ b/services/network/public/cpp/content_security_policy/csp_context.h
@@ -9,10 +9,6 @@ class GURL; -namespace url { -class Origin; -} - namespace network { // A CSPContext represents the Document where the Content-Security-Policy are @@ -87,20 +83,8 @@ return policies_; } - void SetSelf(const url::Origin& origin); - void SetSelf(mojom::CSPSourcePtr self_source); - - // When a CSPSourceList contains 'self', the url is allowed when it match the - // CSPSource returned by this function. - // Sometimes there is no 'self' source. It means that the current origin is - // unique and no urls will match 'self' whatever they are. - // Note: When there is a 'self' source, its scheme is guaranteed to be - // non-empty. - const mojom::CSPSourcePtr& self_source() { return self_source_; } - private: // TODO(arthursonzogni): This is an interface. Stop storing object in it. - mojom::CSPSourcePtr self_source_; // Nullable. std::vector<mojom::ContentSecurityPolicyPtr> policies_; };
diff --git a/services/network/public/cpp/content_security_policy/csp_context_unittest.cc b/services/network/public/cpp/content_security_policy/csp_context_unittest.cc index 39168c0b..151bec3 100644 --- a/services/network/public/cpp/content_security_policy/csp_context_unittest.cc +++ b/services/network/public/cpp/content_security_policy/csp_context_unittest.cc
@@ -66,19 +66,22 @@ } // Build a new policy made of only one directive and no report endpoints. -mojom::ContentSecurityPolicyPtr BuildPolicy(CSPDirectiveName directive_name, +mojom::ContentSecurityPolicyPtr BuildPolicy(mojom::CSPSourcePtr self_source, + CSPDirectiveName directive_name, mojom::CSPSourcePtr source) { auto source_list = mojom::CSPSourceList::New(); source_list->sources.push_back(std::move(source)); auto policy = EmptyCSP(); policy->directives[directive_name] = std::move(source_list); + policy->self_origin = std::move(self_source); return policy; } // Build a new policy made of only one directive and no report endpoints. -mojom::ContentSecurityPolicyPtr BuildPolicy(CSPDirectiveName directive_name, +mojom::ContentSecurityPolicyPtr BuildPolicy(mojom::CSPSourcePtr self_source, + CSPDirectiveName directive_name, mojom::CSPSourcePtr source_1, mojom::CSPSourcePtr source_2) { auto source_list = mojom::CSPSourceList::New(); @@ -87,6 +90,7 @@ auto policy = EmptyCSP(); policy->directives[directive_name] = std::move(source_list); + policy->self_origin = std::move(self_source); return policy; } @@ -104,8 +108,11 @@ TEST(CSPContextTest, SchemeShouldBypassCSP) { CSPContextTest context; - context.AddContentSecurityPolicy(BuildPolicy( - CSPDirectiveName::DefaultSrc, BuildCSPSource("", "example.com"))); + auto self_source = network::mojom::CSPSource::New("http", "example.com", 80, + "", false, false); + context.AddContentSecurityPolicy( + BuildPolicy(self_source.Clone(), CSPDirectiveName::DefaultSrc, + BuildCSPSource("", "example.com"))); EXPECT_FALSE(context.IsAllowedByCsp( CSPDirectiveName::FrameSrc, GURL("data:text/html,<html></html>"), false, @@ -120,14 +127,15 @@ TEST(CSPContextTest, MultiplePolicies) { CSPContextTest context; - context.SetSelf(url::Origin::Create(GURL("http://example.com"))); + auto self_source = network::mojom::CSPSource::New("http", "example.com", 80, + "", false, false); - context.AddContentSecurityPolicy(BuildPolicy(CSPDirectiveName::FrameSrc, - BuildCSPSource("", "a.com"), - BuildCSPSource("", "b.com"))); - context.AddContentSecurityPolicy(BuildPolicy(CSPDirectiveName::FrameSrc, - BuildCSPSource("", "a.com"), - BuildCSPSource("", "c.com"))); + context.AddContentSecurityPolicy( + BuildPolicy(self_source.Clone(), CSPDirectiveName::FrameSrc, + BuildCSPSource("", "a.com"), BuildCSPSource("", "b.com"))); + context.AddContentSecurityPolicy( + BuildPolicy(self_source.Clone(), CSPDirectiveName::FrameSrc, + BuildCSPSource("", "a.com"), BuildCSPSource("", "c.com"))); EXPECT_TRUE(context.IsAllowedByCsp( CSPDirectiveName::FrameSrc, GURL("http://a.com"), false, false, @@ -145,11 +153,12 @@ TEST(CSPContextTest, SanitizeDataForUseInCspViolation) { CSPContextTest context; - context.SetSelf(url::Origin::Create(GURL("http://a.com"))); + auto self_source = + network::mojom::CSPSource::New("http", "a.com", 80, "", false, false); // Content-Security-Policy: frame-src "a.com/iframe" context.AddContentSecurityPolicy( - BuildPolicy(CSPDirectiveName::FrameSrc, + BuildPolicy(self_source.Clone(), CSPDirectiveName::FrameSrc, mojom::CSPSource::New("", "a.com", url::PORT_UNSPECIFIED, "/iframe", false, false))); @@ -196,14 +205,18 @@ // When several policies are infringed, all of them must be reported. TEST(CSPContextTest, MultipleInfringement) { CSPContextTest context; - context.SetSelf(url::Origin::Create(GURL("http://example.com"))); + auto self_source = network::mojom::CSPSource::New("http", "example.com", 80, + "", false, false); - context.AddContentSecurityPolicy( - BuildPolicy(CSPDirectiveName::FrameSrc, BuildCSPSource("", "a.com"))); - context.AddContentSecurityPolicy( - BuildPolicy(CSPDirectiveName::FrameSrc, BuildCSPSource("", "b.com"))); - context.AddContentSecurityPolicy( - BuildPolicy(CSPDirectiveName::FrameSrc, BuildCSPSource("", "c.com"))); + context.AddContentSecurityPolicy(BuildPolicy(self_source.Clone(), + CSPDirectiveName::FrameSrc, + BuildCSPSource("", "a.com"))); + context.AddContentSecurityPolicy(BuildPolicy(self_source.Clone(), + CSPDirectiveName::FrameSrc, + BuildCSPSource("", "b.com"))); + context.AddContentSecurityPolicy(BuildPolicy(self_source.Clone(), + CSPDirectiveName::FrameSrc, + BuildCSPSource("", "c.com"))); EXPECT_FALSE(context.IsAllowedByCsp( CSPDirectiveName::FrameSrc, GURL("http://c.com"), false, false, @@ -222,13 +235,17 @@ // Tests that the CheckCSPDisposition parameter is obeyed. TEST(CSPContextTest, CheckCSPDisposition) { CSPContextTest context; + auto self_source = network::mojom::CSPSource::New("http", "example.com", 80, + "", false, false); // Add an enforced policy. - auto enforce_csp = BuildPolicy(CSPDirectiveName::FrameSrc, - BuildCSPSource("", "example.com")); + auto enforce_csp = + BuildPolicy(self_source.Clone(), CSPDirectiveName::FrameSrc, + BuildCSPSource("", "example.com")); // Add a report-only policy. - auto report_only_csp = BuildPolicy(CSPDirectiveName::DefaultSrc, - BuildCSPSource("", "example.com")); + auto report_only_csp = + BuildPolicy(self_source.Clone(), CSPDirectiveName::DefaultSrc, + BuildCSPSource("", "example.com")); report_only_csp->header->type = mojom::ContentSecurityPolicyType::kReport; context.AddContentSecurityPolicy(std::move(enforce_csp));
diff --git a/services/network/public/cpp/content_security_policy/csp_source.cc b/services/network/public/cpp/content_security_policy/csp_source.cc index 70a11e6..3fe19c7 100644 --- a/services/network/public/cpp/content_security_policy/csp_source.cc +++ b/services/network/public/cpp/content_security_policy/csp_source.cc
@@ -9,7 +9,6 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "services/network/public/cpp/content_security_policy/content_security_policy.h" -#include "services/network/public/cpp/content_security_policy/csp_context.h" #include "services/network/public/mojom/content_security_policy.mojom.h" #include "url/url_canon.h" #include "url/url_util.h" @@ -18,8 +17,8 @@ namespace { -bool HasHost(const mojom::CSPSourcePtr& source) { - return !source->host.empty() || source->is_host_wildcard; +bool HasHost(const mojom::CSPSource& source) { + return !source.host.empty() || source.is_host_wildcard; } bool DecodePath(const base::StringPiece& path, std::string* output) { @@ -55,66 +54,65 @@ return SchemeMatchingResult::NotMatching; } -SchemeMatchingResult SourceAllowScheme(const mojom::CSPSourcePtr& source, +SchemeMatchingResult SourceAllowScheme(const mojom::CSPSource& source, const GURL& url, - CSPContext* context) { + const mojom::CSPSource& self_source) { // The source doesn't specify a scheme and the current origin is unique. In // this case, the url doesn't match regardless of its scheme. - if (source->scheme.empty() && !context->self_source()) + if (source.scheme.empty() && self_source.scheme.empty()) return SchemeMatchingResult::NotMatching; // |allowed_scheme| is guaranteed to be non-empty. const std::string& allowed_scheme = - source->scheme.empty() ? context->self_source()->scheme : source->scheme; + source.scheme.empty() ? self_source.scheme : source.scheme; return MatchScheme(allowed_scheme, url.scheme()); } -bool SourceAllowHost(const mojom::CSPSourcePtr& source, - const std::string& host) { - if (source->is_host_wildcard) { - if (source->host.empty()) +bool SourceAllowHost(const mojom::CSPSource& source, const std::string& host) { + if (source.is_host_wildcard) { + if (source.host.empty()) return true; // TODO(arthursonzogni): Chrome used to, incorrectly, match *.x.y to x.y. // The renderer version of this function counts how many times it happens. // It might be useful to do it outside of blink too. // See third_party/blink/renderer/core/frame/csp/csp_source.cc - return base::EndsWith(host, '.' + source->host, + return base::EndsWith(host, '.' + source.host, base::CompareCase::INSENSITIVE_ASCII); } else { - return base::EqualsCaseInsensitiveASCII(host, source->host); + return base::EqualsCaseInsensitiveASCII(host, source.host); } } -bool SourceAllowHost(const mojom::CSPSourcePtr& source, const GURL& url) { +bool SourceAllowHost(const mojom::CSPSource& source, const GURL& url) { return SourceAllowHost(source, url.host()); } -PortMatchingResult SourceAllowPort(const mojom::CSPSourcePtr& source, +PortMatchingResult SourceAllowPort(const mojom::CSPSource& source, int port, const std::string& scheme) { - if (source->is_port_wildcard) + if (source.is_port_wildcard) return PortMatchingResult::MatchingWildcard; - if (source->port == port) { - if (source->port == url::PORT_UNSPECIFIED) + if (source.port == port) { + if (source.port == url::PORT_UNSPECIFIED) return PortMatchingResult::MatchingWildcard; return PortMatchingResult::MatchingExact; } - if (source->port == url::PORT_UNSPECIFIED) { + if (source.port == url::PORT_UNSPECIFIED) { if (DefaultPortForScheme(scheme) == port) return PortMatchingResult::MatchingWildcard; } if (port == url::PORT_UNSPECIFIED) { - if (source->port == DefaultPortForScheme(scheme)) + if (source.port == DefaultPortForScheme(scheme)) return PortMatchingResult::MatchingWildcard; } - int source_port = source->port; + int source_port = source.port; if (source_port == url::PORT_UNSPECIFIED) - source_port = DefaultPortForScheme(source->scheme); + source_port = DefaultPortForScheme(source.scheme); if (port == url::PORT_UNSPECIFIED) port = DefaultPortForScheme(scheme); @@ -125,13 +123,12 @@ return PortMatchingResult::NotMatching; } -PortMatchingResult SourceAllowPort(const mojom::CSPSourcePtr& source, +PortMatchingResult SourceAllowPort(const mojom::CSPSource& source, const GURL& url) { return SourceAllowPort(source, url.EffectiveIntPort(), url.scheme()); } -bool SourceAllowPath(const mojom::CSPSourcePtr& source, - const std::string& path) { +bool SourceAllowPath(const mojom::CSPSource& source, const std::string& path) { std::string path_decoded; if (!DecodePath(path, &path_decoded)) { // TODO(arthursonzogni): try to figure out if that could happen and how to @@ -139,20 +136,20 @@ return false; } - if (source->path.empty() || (source->path == "/" && path_decoded.empty())) + if (source.path.empty() || (source.path == "/" && path_decoded.empty())) return true; // If the path represents a directory. - if (base::EndsWith(source->path, "/", base::CompareCase::SENSITIVE)) { - return base::StartsWith(path_decoded, source->path, + if (base::EndsWith(source.path, "/", base::CompareCase::SENSITIVE)) { + return base::StartsWith(path_decoded, source.path, base::CompareCase::SENSITIVE); } // The path represents a file. - return source->path == path_decoded; + return source.path == path_decoded; } -bool SourceAllowPath(const mojom::CSPSourcePtr& source, +bool SourceAllowPath(const mojom::CSPSource& source, const GURL& url, bool has_followed_redirect) { if (has_followed_redirect) @@ -180,20 +177,21 @@ } // namespace -bool CSPSourceIsSchemeOnly(const mojom::CSPSourcePtr& source) { +bool CSPSourceIsSchemeOnly(const mojom::CSPSource& source) { return !HasHost(source); } -bool CheckCSPSource(const mojom::CSPSourcePtr& source, +bool CheckCSPSource(const mojom::CSPSource& source, const GURL& url, - CSPContext* context, + const mojom::CSPSource& self_source, bool has_followed_redirect) { if (CSPSourceIsSchemeOnly(source)) { - return SourceAllowScheme(source, url, context) != + return SourceAllowScheme(source, url, self_source) != SchemeMatchingResult::NotMatching; } PortMatchingResult portResult = SourceAllowPort(source, url); - SchemeMatchingResult schemeResult = SourceAllowScheme(source, url, context); + SchemeMatchingResult schemeResult = + SourceAllowScheme(source, url, self_source); if (requiresUpgrade(schemeResult) && !canUpgrade(portResult)) return false; if (requiresUpgrade(portResult) && !canUpgrade(schemeResult)) @@ -204,71 +202,71 @@ SourceAllowPath(source, url, has_followed_redirect); } -mojom::CSPSourcePtr CSPSourcesIntersect(const mojom::CSPSourcePtr& source_a, - const mojom::CSPSourcePtr& source_b) { +mojom::CSPSourcePtr CSPSourcesIntersect(const mojom::CSPSource& source_a, + const mojom::CSPSource& source_b) { // If the original source expressions didn't have a scheme, we should have // filled that already with origin's scheme. - DCHECK(!source_a->scheme.empty()); - DCHECK(!source_b->scheme.empty()); + DCHECK(!source_a.scheme.empty()); + DCHECK(!source_b.scheme.empty()); auto result = mojom::CSPSource::New(); - if (MatchScheme(source_a->scheme, source_b->scheme) != + if (MatchScheme(source_a.scheme, source_b.scheme) != SchemeMatchingResult::NotMatching) { - result->scheme = source_b->scheme; - } else if (MatchScheme(source_b->scheme, source_a->scheme) != + result->scheme = source_b.scheme; + } else if (MatchScheme(source_b.scheme, source_a.scheme) != SchemeMatchingResult::NotMatching) { - result->scheme = source_a->scheme; + result->scheme = source_a.scheme; } else { return nullptr; } if (CSPSourceIsSchemeOnly(source_a)) { - auto new_result = source_b->Clone(); + auto new_result = source_b.Clone(); new_result->scheme = result->scheme; return new_result; } else if (CSPSourceIsSchemeOnly(source_b)) { - auto new_result = source_a->Clone(); + auto new_result = source_a.Clone(); new_result->scheme = result->scheme; return new_result; } const std::string host_a = - (source_a->is_host_wildcard ? "*." : "") + source_a->host; + (source_a.is_host_wildcard ? "*." : "") + source_a.host; const std::string host_b = - (source_b->is_host_wildcard ? "*." : "") + source_b->host; + (source_b.is_host_wildcard ? "*." : "") + source_b.host; if (SourceAllowHost(source_a, host_b)) { - result->host = source_b->host; - result->is_host_wildcard = source_b->is_host_wildcard; + result->host = source_b.host; + result->is_host_wildcard = source_b.is_host_wildcard; } else if (SourceAllowHost(source_b, host_a)) { - result->host = source_a->host; - result->is_host_wildcard = source_a->is_host_wildcard; + result->host = source_a.host; + result->is_host_wildcard = source_a.is_host_wildcard; } else { return nullptr; } - if (source_b->is_port_wildcard) { - result->port = source_a->port; - result->is_port_wildcard = source_a->is_port_wildcard; - } else if (source_a->is_port_wildcard) { - result->port = source_b->port; - } else if (SourceAllowPort(source_a, source_b->port, source_b->scheme) != + if (source_b.is_port_wildcard) { + result->port = source_a.port; + result->is_port_wildcard = source_a.is_port_wildcard; + } else if (source_a.is_port_wildcard) { + result->port = source_b.port; + } else if (SourceAllowPort(source_a, source_b.port, source_b.scheme) != PortMatchingResult::NotMatching && // If port_a is explicitly specified but port_b is omitted, then we // should take port_a instead of port_b, since port_a is stricter. - !(source_a->port != url::PORT_UNSPECIFIED && - source_b->port == url::PORT_UNSPECIFIED)) { - result->port = source_b->port; - } else if (SourceAllowPort(source_b, source_a->port, source_a->scheme) != + !(source_a.port != url::PORT_UNSPECIFIED && + source_b.port == url::PORT_UNSPECIFIED)) { + result->port = source_b.port; + } else if (SourceAllowPort(source_b, source_a.port, source_a.scheme) != PortMatchingResult::NotMatching) { - result->port = source_a->port; + result->port = source_a.port; } else { return nullptr; } - if (SourceAllowPath(source_a, source_b->path)) - result->path = source_b->path; - else if (SourceAllowPath(source_b, source_a->path)) - result->path = source_a->path; + if (SourceAllowPath(source_a, source_b.path)) + result->path = source_b.path; + else if (SourceAllowPath(source_b, source_a.path)) + result->path = source_a.path; else return nullptr; @@ -276,14 +274,14 @@ } // Check whether |source_a| subsumes |source_b|. -bool CSPSourceSubsumes(const mojom::CSPSourcePtr& source_a, - const mojom::CSPSourcePtr& source_b) { +bool CSPSourceSubsumes(const mojom::CSPSource& source_a, + const mojom::CSPSource& source_b) { // If the original source expressions didn't have a scheme, we should have // filled that already with origin's scheme. - DCHECK(!source_a->scheme.empty()); - DCHECK(!source_b->scheme.empty()); + DCHECK(!source_a.scheme.empty()); + DCHECK(!source_b.scheme.empty()); - if (MatchScheme(source_a->scheme, source_b->scheme) == + if (MatchScheme(source_a.scheme, source_b.scheme) == SchemeMatchingResult::NotMatching) { return false; } @@ -293,51 +291,51 @@ if (CSPSourceIsSchemeOnly(source_b)) return false; - if (!SourceAllowHost(source_a, (source_b->is_host_wildcard ? "*." : "") + - source_b->host)) { + if (!SourceAllowHost( + source_a, (source_b.is_host_wildcard ? "*." : "") + source_b.host)) { return false; } - if (source_b->is_port_wildcard && !source_a->is_port_wildcard) + if (source_b.is_port_wildcard && !source_a.is_port_wildcard) return false; PortMatchingResult port_matching = - SourceAllowPort(source_a, source_b->port, source_b->scheme); + SourceAllowPort(source_a, source_b.port, source_b.scheme); if (port_matching == PortMatchingResult::NotMatching) return false; - if (!SourceAllowPath(source_a, source_b->path)) + if (!SourceAllowPath(source_a, source_b.path)) return false; return true; } -std::string ToString(const mojom::CSPSourcePtr& source) { +std::string ToString(const mojom::CSPSource& source) { // scheme if (CSPSourceIsSchemeOnly(source)) - return source->scheme + ":"; + return source.scheme + ":"; std::stringstream text; - if (!source->scheme.empty()) - text << source->scheme << "://"; + if (!source.scheme.empty()) + text << source.scheme << "://"; // host - if (source->is_host_wildcard) { - if (source->host.empty()) + if (source.is_host_wildcard) { + if (source.host.empty()) text << "*"; else - text << "*." << source->host; + text << "*." << source.host; } else { - text << source->host; + text << source.host; } // port - if (source->is_port_wildcard) + if (source.is_port_wildcard) text << ":*"; - if (source->port != url::PORT_UNSPECIFIED) - text << ":" << source->port; + if (source.port != url::PORT_UNSPECIFIED) + text << ":" << source.port; // path - text << source->path; + text << source.path; return text.str(); }
diff --git a/services/network/public/cpp/content_security_policy/csp_source.h b/services/network/public/cpp/content_security_policy/csp_source.h index 8e65b49..49f9948 100644 --- a/services/network/public/cpp/content_security_policy/csp_source.h +++ b/services/network/public/cpp/content_security_policy/csp_source.h
@@ -13,34 +13,32 @@ namespace network { -class CSPContext; - // Check if a CSP |source| matches the scheme-source grammar. -bool CSPSourceIsSchemeOnly(const mojom::CSPSourcePtr& source); +bool CSPSourceIsSchemeOnly(const mojom::CSPSource& source); // Check if a |url| matches with a CSP |source| matches. COMPONENT_EXPORT(NETWORK_CPP) -bool CheckCSPSource(const mojom::CSPSourcePtr& source, +bool CheckCSPSource(const mojom::CSPSource& source, const GURL& url, - CSPContext* context, + const mojom::CSPSource& self_source, bool has_followed_redirect = false); // Compute the source intersection of |source_a| and |source_b|. // https://w3c.github.io/webappsec-cspee/#intersection-source-expressions COMPONENT_EXPORT(NETWORK_CPP) -mojom::CSPSourcePtr CSPSourcesIntersect(const mojom::CSPSourcePtr& source_a, - const mojom::CSPSourcePtr& source_b); +mojom::CSPSourcePtr CSPSourcesIntersect(const mojom::CSPSource& source_a, + const mojom::CSPSource& source_b); // Check if |source_a| subsumes |source_b| according to // https://w3c.github.io/webappsec-cspee/#subsume-source-expressions COMPONENT_EXPORT(NETWORK_CPP) -bool CSPSourceSubsumes(const mojom::CSPSourcePtr& source_a, - const mojom::CSPSourcePtr& source_b); +bool CSPSourceSubsumes(const mojom::CSPSource& source_a, + const mojom::CSPSource& source_b); // Serialize the CSPSource |source| as a string. This is used for reporting // violations. COMPONENT_EXPORT(NETWORK_CPP) -std::string ToString(const mojom::CSPSourcePtr& source); +std::string ToString(const mojom::CSPSource& source); } // namespace network
diff --git a/services/network/public/cpp/content_security_policy/csp_source_list.cc b/services/network/public/cpp/content_security_policy/csp_source_list.cc index 60443a74..d20cd47 100644 --- a/services/network/public/cpp/content_security_policy/csp_source_list.cc +++ b/services/network/public/cpp/content_security_policy/csp_source_list.cc
@@ -7,7 +7,6 @@ #include "base/containers/flat_set.h" #include "base/ranges/algorithm.h" #include "services/network/public/cpp/content_security_policy/content_security_policy.h" -#include "services/network/public/cpp/content_security_policy/csp_context.h" #include "services/network/public/cpp/content_security_policy/csp_source.h" namespace network { @@ -18,10 +17,10 @@ bool AllowFromSources(const GURL& url, const std::vector<mojom::CSPSourcePtr>& sources, - CSPContext* context, + const mojom::CSPSource& self_source, bool has_followed_redirect) { for (const auto& source : sources) { - if (CheckCSPSource(source, url, context, has_followed_redirect)) + if (CheckCSPSource(*source, url, self_source, has_followed_redirect)) return true; } return false; @@ -73,14 +72,14 @@ const std::vector<mojom::CSPSourcePtr>& list_b) { base::flat_set<std::string> schemes_a; for (const auto& source_a : list_a) { - if (CSPSourceIsSchemeOnly(source_a)) { + if (CSPSourceIsSchemeOnly(*source_a)) { AddSourceSchemesToSet(schemes_a, source_a.get()); } } base::flat_set<std::string> intersection; for (const auto& source_b : list_b) { - if (CSPSourceIsSchemeOnly(source_b)) { + if (CSPSourceIsSchemeOnly(*source_b)) { if (schemes_a.contains(source_b->scheme)) AddSourceSchemesToSet(intersection, source_b.get()); else if (source_b->scheme == url::kHttpScheme && @@ -98,14 +97,13 @@ std::vector<mojom::CSPSourcePtr> ExpandSchemeStarAndSelf( const mojom::CSPSourceList& source_list, - const mojom::CSPSource& self) { + const mojom::CSPSource* self) { std::vector<mojom::CSPSourcePtr> result; for (const mojom::CSPSourcePtr& item : source_list.sources) { mojom::CSPSourcePtr new_item = item->Clone(); if (new_item->scheme.empty()) { - if (self.scheme.empty()) - continue; - new_item->scheme = self.scheme; + if (self && !self->scheme.empty()) + new_item->scheme = self->scheme; } result.push_back(std::move(new_item)); } @@ -117,15 +115,16 @@ url::kWsScheme, "", url::PORT_UNSPECIFIED, "", false, false)); result.push_back(mojom::CSPSource::New( url::kHttpScheme, "", url::PORT_UNSPECIFIED, "", false, false)); - if (!self.scheme.empty()) { + if (self && !self->scheme.empty()) { result.push_back(mojom::CSPSource::New( - self.scheme, "", url::PORT_UNSPECIFIED, "", false, false)); + self->scheme, "", url::PORT_UNSPECIFIED, "", false, false)); } } - if (source_list.allow_self && !self.scheme.empty() && !self.host.empty()) { + if (source_list.allow_self && self && !self->scheme.empty() && + !self->host.empty()) { // If |self| is an opaque origin we should ignore it. - result.push_back(self.Clone()); + result.push_back(self->Clone()); } return result; } @@ -133,7 +132,7 @@ std::vector<mojom::CSPSourcePtr> IntersectSources( const mojom::CSPSourceList& source_list_a, const std::vector<mojom::CSPSourcePtr>& source_list_b, - const mojom::CSPSource& self) { + const mojom::CSPSource* self) { auto schemes = IntersectSchemesOnly(source_list_a.sources, source_list_b); std::vector<mojom::CSPSourcePtr> normalized; @@ -160,7 +159,7 @@ if (schemes.contains(source_b->scheme)) continue; if (mojom::CSPSourcePtr local_match = - CSPSourcesIntersect(source_a, source_b)) { + CSPSourcesIntersect(*source_a, *source_b)) { normalized.emplace_back(std::move(local_match)); } } @@ -179,21 +178,21 @@ // |source_list_a|. return base::ranges::all_of(source_list_b, [&](const auto& source_b) { return base::ranges::any_of(source_list_a, [&](const auto& source_a) { - return CSPSourceSubsumes(source_a, source_b); + return CSPSourceSubsumes(*source_a, *source_b); }); }); } } // namespace -bool CheckCSPSourceList(const mojom::CSPSourceListPtr& source_list, +bool CheckCSPSourceList(const mojom::CSPSourceList& source_list, const GURL& url, - CSPContext* context, + const mojom::CSPSource& self_source, bool has_followed_redirect, bool is_response_check) { // If the source list allows all redirects, the decision can't be made until // the response is received. - if (source_list->allow_response_redirects && !is_response_check) + if (source_list.allow_response_redirects && !is_response_check) return true; // Wildcards match network schemes ('http', 'https', 'ftp', 'ws', 'wss'), and @@ -201,22 +200,21 @@ // https://w3c.github.io/webappsec-csp/#match-url-to-source-expression. Other // schemes, including custom schemes, must be explicitly listed in a source // list. - if (source_list->allow_star) { + if (source_list.allow_star) { if (url.SchemeIsHTTPOrHTTPS() || url.SchemeIsWSOrWSS() || url.SchemeIs("ftp")) { return true; } - if (context->self_source() && url.SchemeIs(context->self_source()->scheme)) + if (!self_source.scheme.empty() && url.SchemeIs(self_source.scheme)) return true; } - if (source_list->allow_self && context->self_source() && - CheckCSPSource(context->self_source(), url, context, - has_followed_redirect)) { + if (source_list.allow_self && + CheckCSPSource(self_source, url, self_source, has_followed_redirect)) { return true; } - return AllowFromSources(url, source_list->sources, context, + return AllowFromSources(url, source_list.sources, self_source, has_followed_redirect); } @@ -224,7 +222,7 @@ const mojom::CSPSourceList& source_list_a, const std::vector<const mojom::CSPSourceList*>& source_list_b, CSPDirectiveName directive, - const url::Origin& origin_b) { + const mojom::CSPSource* origin_b) { if (source_list_b.empty()) return false; @@ -239,10 +237,8 @@ base::flat_set<std::string> nonces_b((*it)->nonces); base::flat_set<mojom::CSPHashSourcePtr> hashes_b(mojo::Clone((*it)->hashes)); - auto origin_b_as_csp_source = mojom::CSPSource::New( - origin_b.scheme(), origin_b.host(), origin_b.port(), "", false, false); std::vector<mojom::CSPSourcePtr> normalized_sources_b = - ExpandSchemeStarAndSelf(**it, *origin_b_as_csp_source); + ExpandSchemeStarAndSelf(**it, origin_b); ++it; for (; it != source_list_b.end(); ++it) { @@ -262,7 +258,7 @@ mojo::Clone((*it)->hashes)); IntersectHashes(hashes_b, item_hashes); normalized_sources_b = - IntersectSources(**it, normalized_sources_b, *origin_b_as_csp_source); + IntersectSources(**it, normalized_sources_b, origin_b); } // If source_list_b enforces some nonce, then source_list_a must contain @@ -310,7 +306,7 @@ // If embedding CSP specifies `self`, `self` refers to the embedee's origin. std::vector<mojom::CSPSourcePtr> normalized_sources_a = - ExpandSchemeStarAndSelf(source_list_a, *origin_b_as_csp_source); + ExpandSchemeStarAndSelf(source_list_a, origin_b); return UrlSourceListSubsumes(normalized_sources_a, normalized_sources_b); } @@ -332,7 +328,7 @@ for (const auto& source : source_list->sources) { if (!is_empty) text << " "; - text << ToString(source); + text << ToString(*source); is_empty = false; }
diff --git a/services/network/public/cpp/content_security_policy/csp_source_list.h b/services/network/public/cpp/content_security_policy/csp_source_list.h index d2bc974..141b233d 100644 --- a/services/network/public/cpp/content_security_policy/csp_source_list.h +++ b/services/network/public/cpp/content_security_policy/csp_source_list.h
@@ -13,22 +13,17 @@ class GURL; -namespace url { -class Origin; -} - namespace network { -class CSPContext; COMPONENT_EXPORT(NETWORK_CPP) std::string ToString(const mojom::CSPSourceListPtr& source_list); // Return true when at least one source in the |source_list| matches the -// |url| for a given |context|. +// |url|. COMPONENT_EXPORT(NETWORK_CPP) -bool CheckCSPSourceList(const mojom::CSPSourceListPtr& source_list, +bool CheckCSPSourceList(const mojom::CSPSourceList& source_list, const GURL& url, - CSPContext* context, + const mojom::CSPSource& self_source, bool has_followed_redirect = false, bool is_response_check = false); @@ -40,7 +35,7 @@ const mojom::CSPSourceList& source_list_a, const std::vector<const mojom::CSPSourceList*>& source_list_b, mojom::CSPDirectiveName directive, - const url::Origin& origin_b); + const mojom::CSPSource* origin_b); } // namespace network #endif // SERVICES_NETWORK_PUBLIC_CPP_CONTENT_SECURITY_POLICY_CSP_SOURCE_LIST_H_
diff --git a/services/network/public/cpp/content_security_policy/csp_source_list_unittest.cc b/services/network/public/cpp/content_security_policy/csp_source_list_unittest.cc index 7831ed6..4f9c329 100644 --- a/services/network/public/cpp/content_security_policy/csp_source_list_unittest.cc +++ b/services/network/public/cpp/content_security_policy/csp_source_list_unittest.cc
@@ -6,7 +6,6 @@ #include "base/strings/stringprintf.h" #include "net/http/http_response_headers.h" #include "services/network/public/cpp/content_security_policy/content_security_policy.h" -#include "services/network/public/cpp/content_security_policy/csp_context.h" #include "services/network/public/mojom/content_security_policy.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/origin.h" @@ -19,10 +18,10 @@ // test expectations on one line. bool Allow(const mojom::CSPSourceListPtr& source_list, const GURL& url, - CSPContext* context, + const mojom::CSPSource& self, bool is_redirect = false, bool is_response_check = false) { - return CheckCSPSourceList(source_list, url, context, is_redirect, + return CheckCSPSourceList(*source_list, url, self, is_redirect, is_response_check); } @@ -77,8 +76,8 @@ } // namespace TEST(CSPSourceList, MultipleSource) { - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("http://example.com"))); + auto self = network::mojom::CSPSource::New("http", "example.com", 80, "", + false, false); std::vector<mojom::CSPSourcePtr> sources; sources.push_back(mojom::CSPSource::New("", "a.com", url::PORT_UNSPECIFIED, "", false, false)); @@ -86,92 +85,96 @@ "", false, false)); auto source_list = mojom::CSPSourceList::New(); source_list->sources = std::move(sources); - EXPECT_TRUE(Allow(source_list, GURL("http://a.com"), &context)); - EXPECT_TRUE(Allow(source_list, GURL("http://b.com"), &context)); - EXPECT_FALSE(Allow(source_list, GURL("http://c.com"), &context)); + EXPECT_TRUE(Allow(source_list, GURL("http://a.com"), *self)); + EXPECT_TRUE(Allow(source_list, GURL("http://b.com"), *self)); + EXPECT_FALSE(Allow(source_list, GURL("http://c.com"), *self)); } TEST(CSPSourceList, AllowStar) { - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("http://example.com"))); + auto self = network::mojom::CSPSource::New("http", "example.com", 80, "", + false, false); auto source_list = mojom::CSPSourceList::New(); source_list->allow_star = true; - EXPECT_TRUE(Allow(source_list, GURL("http://not-example.com"), &context)); - EXPECT_TRUE(Allow(source_list, GURL("https://not-example.com"), &context)); - EXPECT_TRUE(Allow(source_list, GURL("ws://not-example.com"), &context)); - EXPECT_TRUE(Allow(source_list, GURL("wss://not-example.com"), &context)); - EXPECT_TRUE(Allow(source_list, GURL("ftp://not-example.com"), &context)); + EXPECT_TRUE(Allow(source_list, GURL("http://not-example.com"), *self)); + EXPECT_TRUE(Allow(source_list, GURL("https://not-example.com"), *self)); + EXPECT_TRUE(Allow(source_list, GURL("ws://not-example.com"), *self)); + EXPECT_TRUE(Allow(source_list, GURL("wss://not-example.com"), *self)); + EXPECT_TRUE(Allow(source_list, GURL("ftp://not-example.com"), *self)); - EXPECT_FALSE(Allow(source_list, GURL("file://not-example.com"), &context)); - EXPECT_FALSE(Allow(source_list, GURL("applewebdata://a.test"), &context)); + EXPECT_FALSE(Allow(source_list, GURL("file://not-example.com"), *self)); + EXPECT_FALSE(Allow(source_list, GURL("applewebdata://a.test"), *self)); - // With a protocol of 'file', '*' allow 'file:' - context.SetSelf(url::Origin::Create(GURL("file://example.com"))); - EXPECT_TRUE(Allow(source_list, GURL("file://not-example.com"), &context)); - EXPECT_FALSE(Allow(source_list, GURL("applewebdata://a.test"), &context)); + { + // With a protocol of 'file', '*' allow 'file:' + auto self = network::mojom::CSPSource::New( + "file", "example.com", url::PORT_UNSPECIFIED, "", false, false); + EXPECT_TRUE(Allow(source_list, GURL("file://not-example.com"), *self)); + EXPECT_FALSE(Allow(source_list, GURL("applewebdata://a.test"), *self)); + } } TEST(CSPSourceList, AllowSelf) { - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("http://example.com"))); + auto self = network::mojom::CSPSource::New("http", "example.com", 80, "", + false, false); auto source_list = mojom::CSPSourceList::New(); source_list->allow_self = true; - EXPECT_TRUE(Allow(source_list, GURL("http://example.com"), &context)); - EXPECT_FALSE(Allow(source_list, GURL("http://not-example.com"), &context)); - EXPECT_TRUE(Allow(source_list, GURL("https://example.com"), &context)); - EXPECT_FALSE(Allow(source_list, GURL("ws://example.com"), &context)); + EXPECT_TRUE(Allow(source_list, GURL("http://example.com"), *self)); + EXPECT_FALSE(Allow(source_list, GURL("http://not-example.com"), *self)); + EXPECT_TRUE(Allow(source_list, GURL("https://example.com"), *self)); + EXPECT_FALSE(Allow(source_list, GURL("ws://example.com"), *self)); } TEST(CSPSourceList, AllowStarAndSelf) { - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("https://a.com"))); + auto self = + network::mojom::CSPSource::New("https", "a.com", 443, "", false, false); auto source_list = mojom::CSPSourceList::New(); // If the request is allowed by {*} and not by {'self'} then it should be // allowed by the union {*,'self'}. source_list->allow_self = true; source_list->allow_star = false; - EXPECT_FALSE(Allow(source_list, GURL("http://b.com"), &context)); + EXPECT_FALSE(Allow(source_list, GURL("http://b.com"), *self)); source_list->allow_self = false; source_list->allow_star = true; - EXPECT_TRUE(Allow(source_list, GURL("http://b.com"), &context)); + EXPECT_TRUE(Allow(source_list, GURL("http://b.com"), *self)); source_list->allow_self = true; source_list->allow_star = true; - EXPECT_TRUE(Allow(source_list, GURL("http://b.com"), &context)); + EXPECT_TRUE(Allow(source_list, GURL("http://b.com"), *self)); } TEST(CSPSourceList, AllowSelfWithUnspecifiedPort) { - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("https://example.com/"))); + auto self = network::mojom::CSPSource::New("https", "example.com", 443, "", + false, false); auto source_list = mojom::CSPSourceList::New(); source_list->allow_self = true; - EXPECT_TRUE( - Allow(source_list, GURL("https://example.com/print.pdf"), &context)); + EXPECT_TRUE(Allow(source_list, GURL("https://example.com/print.pdf"), *self)); } TEST(CSPSourceList, AllowNone) { - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("http://example.com"))); + auto self = network::mojom::CSPSource::New("http", "example.com", 80, "", + false, false); auto source_list = mojom::CSPSourceList::New(); - EXPECT_FALSE(Allow(source_list, GURL("http://example.com"), &context)); - EXPECT_FALSE(Allow(source_list, GURL("https://example.test/"), &context)); + EXPECT_FALSE(Allow(source_list, GURL("http://example.com"), *self)); + EXPECT_FALSE(Allow(source_list, GURL("https://example.test/"), *self)); } TEST(CSPSourceTest, SelfIsUnique) { // Policy: 'self' auto source_list = mojom::CSPSourceList::New(); source_list->allow_self = true; - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("http://a.com"))); - EXPECT_TRUE(Allow(source_list, GURL("http://a.com"), &context)); - EXPECT_FALSE(Allow(source_list, GURL("data:text/html,hello"), &context)); + auto self = + network::mojom::CSPSource::New("http", "a.com", 80, "", false, false); + EXPECT_TRUE(Allow(source_list, GURL("http://a.com"), *self)); + EXPECT_FALSE(Allow(source_list, GURL("data:text/html,hello"), *self)); - context.SetSelf( - url::Origin::Create(GURL("data:text/html,<iframe src=[...]>"))); - EXPECT_FALSE(Allow(source_list, GURL("http://a.com"), &context)); - EXPECT_FALSE(Allow(source_list, GURL("data:text/html,hello"), &context)); + // Self doesn't match anything. + auto no_self_source = network::mojom::CSPSource::New( + "", "", url::PORT_UNSPECIFIED, "", false, false); + EXPECT_FALSE(Allow(source_list, GURL("http://a.com"), *no_self_source)); + EXPECT_FALSE( + Allow(source_list, GURL("data:text/html,hello"), *no_self_source)); } TEST(CSPSourceList, Subsume) { @@ -257,6 +260,8 @@ {{"http://*", "http://*.com http://*.example3.com:*/bar/"}, false}, }; + auto origin_b = + mojom::CSPSource::New("https", "frame.test", 443, "", false, false); for (const auto& test : cases) { auto response_sources = ParseToVectorOfSourceLists( mojom::CSPDirectiveName::ScriptSrc, test.response_csp); @@ -264,8 +269,7 @@ EXPECT_EQ(test.expected, CSPSourceListSubsumes( *required_sources, ToRawPointers(response_sources), - mojom::CSPDirectiveName::ScriptSrc, - url::Origin::Create(GURL("https://frame.test")))) + mojom::CSPDirectiveName::ScriptSrc, origin_b.get())) << required << " should " << (test.expected ? "" : "not ") << "subsume " << base::JoinString(test.response_csp, ", "); } @@ -383,11 +387,14 @@ auto response_sources = ParseToVectorOfSourceLists( mojom::CSPDirectiveName::ScriptSrc, test.response_csp); + GURL parsed_test_origin(test.origin); + auto origin_b = mojom::CSPSource::New( + parsed_test_origin.scheme(), parsed_test_origin.host(), + parsed_test_origin.EffectiveIntPort(), "", false, false); EXPECT_EQ(test.expected, - CSPSourceListSubsumes(*required_sources, - ToRawPointers(response_sources), - mojom::CSPDirectiveName::ScriptSrc, - url::Origin::Create(GURL(test.origin)))) + CSPSourceListSubsumes( + *required_sources, ToRawPointers(response_sources), + mojom::CSPDirectiveName::ScriptSrc, origin_b.get())) << required << "from origin " << test.origin << " should " << (test.expected ? "" : "not ") << "subsume " << base::JoinString(test.response_csp, ", "); @@ -489,17 +496,18 @@ true}, }; + auto origin_b = + mojom::CSPSource::New("https", "frame.test", 443, "", false, false); for (const auto& test : cases) { mojom::CSPSourceListPtr required_sources = ParseToSourceList(test.directive, test.required); auto response_sources = ParseToVectorOfSourceLists(test.directive, test.response_csp); - EXPECT_EQ( - test.expected, - CSPSourceListSubsumes(*required_sources, - ToRawPointers(response_sources), test.directive, - url::Origin::Create(GURL("https://frame.test")))) + EXPECT_EQ(test.expected, + CSPSourceListSubsumes(*required_sources, + ToRawPointers(response_sources), + test.directive, origin_b.get())) << test.required << " should " << (test.expected ? "" : "not ") << "subsume " << base::JoinString(test.response_csp, ", "); } @@ -576,17 +584,18 @@ false}, }; + auto origin_b = + mojom::CSPSource::New("https", "frame.test", 443, "", false, false); for (const auto& test : cases) { mojom::CSPSourceListPtr required_sources = ParseToSourceList(test.directive, test.required); auto response_sources = ParseToVectorOfSourceLists(test.directive, test.response_csp); - EXPECT_EQ( - test.expected, - CSPSourceListSubsumes(*required_sources, - ToRawPointers(response_sources), test.directive, - url::Origin::Create(GURL("https://frame.test")))) + EXPECT_EQ(test.expected, + CSPSourceListSubsumes(*required_sources, + ToRawPointers(response_sources), + test.directive, origin_b.get())) << test.required << " should " << (test.expected ? "" : "not ") << "subsume " << base::JoinString(test.response_csp, ", "); } @@ -728,17 +737,18 @@ false}, }; + auto origin_b = + mojom::CSPSource::New("https", "frame.test", 443, "", false, false); for (const auto& test : cases) { mojom::CSPSourceListPtr required_sources = ParseToSourceList(test.directive, test.required); auto response_sources = ParseToVectorOfSourceLists(test.directive, test.response_csp); - EXPECT_EQ( - test.expected, - CSPSourceListSubsumes(*required_sources, - ToRawPointers(response_sources), test.directive, - url::Origin::Create(GURL("https://frame.test")))) + EXPECT_EQ(test.expected, + CSPSourceListSubsumes(*required_sources, + ToRawPointers(response_sources), + test.directive, origin_b.get())) << test.required << " should " << (test.expected ? "" : "not ") << "subsume " << base::JoinString(test.response_csp, ", "); } @@ -911,17 +921,18 @@ false}, }; + auto origin_b = + mojom::CSPSource::New("https", "frame.test", 443, "", false, false); for (const auto& test : cases) { mojom::CSPSourceListPtr required_sources = ParseToSourceList(test.directive, test.required); auto response_sources = ParseToVectorOfSourceLists(test.directive, test.response_csp); - EXPECT_EQ( - test.expected, - CSPSourceListSubsumes(*required_sources, - ToRawPointers(response_sources), test.directive, - url::Origin::Create(GURL("https://frame.test")))) + EXPECT_EQ(test.expected, + CSPSourceListSubsumes(*required_sources, + ToRawPointers(response_sources), + test.directive, origin_b.get())) << test.required << " should " << (test.expected ? "" : "not ") << "subsume " << base::JoinString(test.response_csp, ", "); } @@ -982,6 +993,8 @@ false}, }; + auto origin_b = + mojom::CSPSource::New("https", "another.test", 443, "", false, false); for (const auto& test : cases) { mojom::CSPSourceListPtr required_sources = ParseToSourceList(mojom::CSPDirectiveName::ScriptSrc, test.required); @@ -991,33 +1004,36 @@ EXPECT_EQ(test.expected, CSPSourceListSubsumes( *required_sources, ToRawPointers(response_sources), - mojom::CSPDirectiveName::ScriptSrc, - url::Origin::Create(GURL("https://another.test/image.png")))) + mojom::CSPDirectiveName::ScriptSrc, origin_b.get())) << test.required << " should " << (test.expected ? "" : "not ") << "subsume " << base::JoinString(test.response_csp, ", "); } } TEST(CSPSourceList, SubsumeListNoScheme) { + auto origin_http = + mojom::CSPSource::New("http", "example.org", 80, "", false, false); + auto origin_https = + mojom::CSPSource::New("https", "example.org", 443, "", false, false); struct TestCase { std::string required; std::vector<std::string> response_csp; - std::string origin; + mojom::CSPSource* origin; bool expected; } cases[] = { - {"http://a.com", {"a.com"}, "https://example.org", true}, - {"https://a.com", {"a.com"}, "https://example.org", true}, - {"https://a.com", {"a.com"}, "http://example.org", false}, - {"data://a.com", {"a.com"}, "https://example.org", false}, - {"a.com", {"a.com"}, "https://example.org", true}, - {"a.com", {"a.com"}, "http://example.org", true}, - {"a.com", {"https://a.com"}, "http://example.org", true}, - {"a.com", {"https://a.com"}, "https://example.org", true}, - {"a.com", {"http://a.com"}, "https://example.org", false}, - {"https:", {"a.com"}, "http://example.org", false}, - {"http:", {"a.com"}, "http://example.org", true}, - {"https:", {"a.com", "https:"}, "http://example.org", true}, - {"https:", {"a.com"}, "https://example.org", true}, + {"http://a.com", {"a.com"}, origin_https.get(), true}, + {"https://a.com", {"a.com"}, origin_https.get(), true}, + {"https://a.com", {"a.com"}, origin_http.get(), false}, + {"data://a.com", {"a.com"}, origin_https.get(), false}, + {"a.com", {"a.com"}, origin_https.get(), true}, + {"a.com", {"a.com"}, origin_http.get(), true}, + {"a.com", {"https://a.com"}, origin_http.get(), true}, + {"a.com", {"https://a.com"}, origin_https.get(), true}, + {"a.com", {"http://a.com"}, origin_https.get(), false}, + {"https:", {"a.com"}, origin_http.get(), false}, + {"http:", {"a.com"}, origin_http.get(), true}, + {"https:", {"a.com", "https:"}, origin_http.get(), true}, + {"https:", {"a.com"}, origin_https.get(), true}, }; for (const auto& test : cases) { @@ -1027,12 +1043,11 @@ mojom::CSPDirectiveName::ScriptSrc, test.response_csp); EXPECT_EQ(test.expected, - CSPSourceListSubsumes(*required_sources, - ToRawPointers(response_sources), - mojom::CSPDirectiveName::ScriptSrc, - url::Origin::Create(GURL(test.origin)))) - << test.required << " on origin " << test.origin << " should " - << (test.expected ? "" : "not ") << "subsume " + CSPSourceListSubsumes( + *required_sources, ToRawPointers(response_sources), + mojom::CSPDirectiveName::ScriptSrc, test.origin)) + << test.required << " on origin with scheme " << test.origin->scheme + << " should " << (test.expected ? "" : "not ") << "subsume " << base::JoinString(test.response_csp, ", "); } }
diff --git a/services/network/public/cpp/content_security_policy/csp_source_unittest.cc b/services/network/public/cpp/content_security_policy/csp_source_unittest.cc index 88f4e53..7ee11c20 100644 --- a/services/network/public/cpp/content_security_policy/csp_source_unittest.cc +++ b/services/network/public/cpp/content_security_policy/csp_source_unittest.cc
@@ -5,7 +5,6 @@ #include "services/network/public/cpp/content_security_policy/csp_source.h" #include "net/http/http_response_headers.h" #include "services/network/public/cpp/content_security_policy/content_security_policy.h" -#include "services/network/public/cpp/content_security_policy/csp_context.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/origin.h" @@ -15,11 +14,11 @@ // Allow() is an abbreviation of CSPSource::Allow(). Useful for writing test // expectations on one line. -bool Allow(const network::mojom::CSPSourcePtr& source, +bool Allow(const network::mojom::CSPSource& source, const GURL& url, - CSPContext* context, + const network::mojom::CSPSource& self_source, bool is_redirect = false) { - return CheckCSPSource(source, url, context, is_redirect); + return CheckCSPSource(source, url, self_source, is_redirect); } network::mojom::CSPSourcePtr CSPSource(const std::string& raw) { @@ -36,261 +35,291 @@ } // namespace TEST(CSPSourceTest, BasicMatching) { - CSPContext context; - auto source = network::mojom::CSPSource::New("http", "example.com", 8000, "/foo/", false, false); - EXPECT_TRUE(Allow(source, GURL("http://example.com:8000/foo/"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://example.com:8000/foo/bar"), &context)); - EXPECT_TRUE(Allow(source, GURL("HTTP://EXAMPLE.com:8000/foo/BAR"), &context)); + // Self doesn't match anything. + auto self_source = network::mojom::CSPSource::New( + "", "", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_FALSE(Allow(source, GURL("http://example.com:8000/bar/"), &context)); - EXPECT_FALSE(Allow(source, GURL("https://example.com:8000/bar/"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://example.com:9000/bar/"), &context)); + EXPECT_TRUE( + Allow(*source, GURL("http://example.com:8000/foo/"), *self_source)); + EXPECT_TRUE( + Allow(*source, GURL("http://example.com:8000/foo/bar"), *self_source)); + EXPECT_TRUE( + Allow(*source, GURL("HTTP://EXAMPLE.com:8000/foo/BAR"), *self_source)); + EXPECT_FALSE( - Allow(source, GURL("HTTP://example.com:8000/FOO/bar"), &context)); + Allow(*source, GURL("http://example.com:8000/bar/"), *self_source)); EXPECT_FALSE( - Allow(source, GURL("HTTP://example.com:8000/FOO/BAR"), &context)); + Allow(*source, GURL("https://example.com:8000/bar/"), *self_source)); + EXPECT_FALSE( + Allow(*source, GURL("http://example.com:9000/bar/"), *self_source)); + EXPECT_FALSE( + Allow(*source, GURL("HTTP://example.com:8000/FOO/bar"), *self_source)); + EXPECT_FALSE( + Allow(*source, GURL("HTTP://example.com:8000/FOO/BAR"), *self_source)); } TEST(CSPSourceTest, AllowScheme) { - CSPContext context; + // Self doesn't match anything. + auto no_self_source = network::mojom::CSPSource::New( + "", "", url::PORT_UNSPECIFIED, "", false, false); // http -> {http, https}. { auto source = network::mojom::CSPSource::New( "http", "", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com"), *no_self_source)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com"), *no_self_source)); // This passes because the source is "scheme only" so the upgrade is // allowed. - EXPECT_TRUE(Allow(source, GURL("https://a.com:80"), &context)); - EXPECT_FALSE(Allow(source, GURL("ftp://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("ws://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("wss://a.com"), &context)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com:80"), *no_self_source)); + EXPECT_FALSE(Allow(*source, GURL("ftp://a.com"), *no_self_source)); + EXPECT_FALSE(Allow(*source, GURL("ws://a.com"), *no_self_source)); + EXPECT_FALSE(Allow(*source, GURL("wss://a.com"), *no_self_source)); } // ws -> {ws, wss}. { auto source = network::mojom::CSPSource::New( "ws", "", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("https://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("ftp://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("ws://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("wss://a.com"), &context)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *no_self_source)); + EXPECT_FALSE(Allow(*source, GURL("https://a.com"), *no_self_source)); + EXPECT_FALSE(Allow(*source, GURL("ftp://a.com"), *no_self_source)); + EXPECT_TRUE(Allow(*source, GURL("ws://a.com"), *no_self_source)); + EXPECT_TRUE(Allow(*source, GURL("wss://a.com"), *no_self_source)); } // Exact matches required (ftp) { auto source = network::mojom::CSPSource::New( "ftp", "", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_TRUE(Allow(source, GURL("ftp://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); + EXPECT_TRUE(Allow(*source, GURL("ftp://a.com"), *no_self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *no_self_source)); } // Exact matches required (https) { auto source = network::mojom::CSPSource::New( "https", "", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com"), *no_self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *no_self_source)); } // Exact matches required (wss) { auto source = network::mojom::CSPSource::New( "wss", "", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_TRUE(Allow(source, GURL("wss://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("ws://a.com"), &context)); + EXPECT_TRUE(Allow(*source, GURL("wss://a.com"), *no_self_source)); + EXPECT_FALSE(Allow(*source, GURL("ws://a.com"), *no_self_source)); } // Scheme is empty (ProtocolMatchesSelf). { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *no_self_source)); - // Self's scheme is http. - context.SetSelf(url::Origin::Create(GURL("http://a.com"))); - EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("ftp://a.com"), &context)); + { + // Self's scheme is http. + auto self_source = + network::mojom::CSPSource::New("http", "a.com", 80, "", false, false); + EXPECT_TRUE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("ftp://a.com"), *self_source)); + } - // Self's is https. - context.SetSelf(url::Origin::Create(GURL("https://a.com"))); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("ftp://a.com"), &context)); + { + // Self's is https. + auto self_source = network::mojom::CSPSource::New("https", "a.com", 443, + "", false, false); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("ftp://a.com"), *self_source)); + } - // Self's scheme is not in the http familly. - context.SetSelf(url::Origin::Create(GURL("ftp://a.com/"))); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("ftp://a.com"), &context)); + { + // Self's scheme is not in the http family. + auto self_source = + network::mojom::CSPSource::New("ftp", "a.com", 21, "", false, false); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("ftp://a.com"), *self_source)); + } - // Self's scheme is unique (non standard scheme). - context.SetSelf(url::Origin::Create(GURL("non-standard-scheme://a.com"))); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("non-standard-scheme://a.com"), &context)); + { + // Self's scheme is unique (non standard scheme). + auto self_source = network::mojom::CSPSource::New( + "non-standard-scheme", "a.com", url::PORT_UNSPECIFIED, "", false, + false); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_FALSE( + Allow(*source, GURL("non-standard-scheme://a.com"), *self_source)); + } - // Self's scheme is unique (data-url). - context.SetSelf( - url::Origin::Create(GURL("data:text/html,<iframe src=[...]>"))); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("data:text/html,hello"), &context)); + // Self's scheme is unique (e.g. data-url). + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *no_self_source)); + EXPECT_FALSE(Allow(*source, GURL("data:text/html,hello"), *no_self_source)); } } TEST(CSPSourceTest, AllowHost) { - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("http://example.com"))); + auto self_source = network::mojom::CSPSource::New("http", "example.com", 80, + "", false, false); + + // Self doesn't match anything. + auto no_self_source = network::mojom::CSPSource::New( + "", "", url::PORT_UNSPECIFIED, "", false, false); // Host is * (source-expression = "http://*") { auto source = network::mojom::CSPSource::New( "http", "", url::PORT_UNSPECIFIED, "", true, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://."), &context)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://."), *self_source)); } // Host is *.foo.bar { auto source = network::mojom::CSPSource::New( "", "foo.bar", url::PORT_UNSPECIFIED, "", true, false); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://bar"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://foo.bar"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://o.bar"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://*.foo.bar"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://sub.foo.bar"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://sub.sub.foo.bar"), &context)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://bar"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://foo.bar"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://o.bar"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://*.foo.bar"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://sub.foo.bar"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://sub.sub.foo.bar"), *self_source)); // Please see http://crbug.com/692505 - EXPECT_TRUE(Allow(source, GURL("http://.foo.bar"), &context)); + EXPECT_TRUE(Allow(*source, GURL("http://.foo.bar"), *self_source)); } // Host is exact. { auto source = network::mojom::CSPSource::New( "", "foo.bar", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_TRUE(Allow(source, GURL("http://foo.bar"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://sub.foo.bar"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://bar"), &context)); + EXPECT_TRUE(Allow(*source, GURL("http://foo.bar"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://sub.foo.bar"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://bar"), *self_source)); // Please see http://crbug.com/692505 - EXPECT_FALSE(Allow(source, GURL("http://.foo.bar"), &context)); + EXPECT_FALSE(Allow(*source, GURL("http://.foo.bar"), *self_source)); } } TEST(CSPSourceTest, AllowPort) { - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("http://example.com"))); + auto self_source = network::mojom::CSPSource::New("http", "example.com", 80, + "", false, false); // Source's port unspecified. { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com:80"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com:8080"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com:443"), &context)); - EXPECT_FALSE(Allow(source, GURL("https://a.com:80"), &context)); - EXPECT_FALSE(Allow(source, GURL("https://a.com:8080"), &context)); - EXPECT_TRUE(Allow(source, GURL("https://a.com:443"), &context)); - EXPECT_FALSE(Allow(source, GURL("unknown://a.com:80"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com:80"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com:8080"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com:443"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("https://a.com:80"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("https://a.com:8080"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com:443"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("unknown://a.com:80"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com"), *self_source)); } // Source's port is "*". { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "", false, true); - EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com:80"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com:8080"), &context)); - EXPECT_TRUE(Allow(source, GURL("https://a.com:8080"), &context)); - EXPECT_TRUE(Allow(source, GURL("https://a.com:0"), &context)); - EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com:80"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com:8080"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com:8080"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com:0"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com"), *self_source)); } // Source has a port. { auto source = network::mojom::CSPSource::New("", "a.com", 80, "", false, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com:80"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com:8080"), &context)); - EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com:80"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com:8080"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com"), *self_source)); } // Allow upgrade from :80 to :443 { auto source = network::mojom::CSPSource::New("", "a.com", 80, "", false, false); - EXPECT_TRUE(Allow(source, GURL("https://a.com:443"), &context)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com:443"), *self_source)); // Should not allow scheme upgrades unless both port and scheme are // upgraded. - EXPECT_FALSE(Allow(source, GURL("http://a.com:443"), &context)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com:443"), *self_source)); } // Host is * but port is specified { auto source = network::mojom::CSPSource::New("http", "", 111, "", true, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com:111"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com:222"), &context)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com:111"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com:222"), *self_source)); } } TEST(CSPSourceTest, AllowPath) { - CSPContext context; - context.SetSelf(url::Origin::Create(GURL("http://example.com"))); + auto self_source = network::mojom::CSPSource::New("http", "example.com", 80, + "", false, false); // Path to a file { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "/path/to/file", false, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com/path/to/file"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com/path/to/"), &context)); + EXPECT_TRUE( + Allow(*source, GURL("http://a.com/path/to/file"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com/path/to/"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com/path/to/file/subpath"), + *self_source)); EXPECT_FALSE( - Allow(source, GURL("http://a.com/path/to/file/subpath"), &context)); - EXPECT_FALSE( - Allow(source, GURL("http://a.com/path/to/something"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com/"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); + Allow(*source, GURL("http://a.com/path/to/something"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com/"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *self_source)); } // Path to a directory { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "/path/to/", false, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com/path/to/file"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com/path/to/"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com/path/"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com/path/to"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com/path/to"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com/"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context)); + EXPECT_TRUE( + Allow(*source, GURL("http://a.com/path/to/file"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com/path/to/"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com/path/"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com/path/to"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com/path/to"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com/"), *self_source)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com"), *self_source)); } // Empty path { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com/path/to/file"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com/path/to/"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com/"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context)); + EXPECT_TRUE( + Allow(*source, GURL("http://a.com/path/to/file"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com/path/to/"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com/"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com"), *self_source)); } // Almost empty path { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "/", false, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com/path/to/file"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com/path/to/"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com/"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context)); + EXPECT_TRUE( + Allow(*source, GURL("http://a.com/path/to/file"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com/path/to/"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com/"), *self_source)); + EXPECT_TRUE(Allow(*source, GURL("http://a.com"), *self_source)); } // Path encoded. @@ -298,29 +327,39 @@ auto source = network::mojom::CSPSource::New( "http", "a.com", url::PORT_UNSPECIFIED, "/Hello Günter", false, false); EXPECT_TRUE( - Allow(source, GURL("http://a.com/Hello%20G%C3%BCnter"), &context)); - EXPECT_TRUE(Allow(source, GURL("http://a.com/Hello Günter"), &context)); + Allow(*source, GURL("http://a.com/Hello%20G%C3%BCnter"), *self_source)); + EXPECT_TRUE( + Allow(*source, GURL("http://a.com/Hello Günter"), *self_source)); } // Host is * but path is specified. { auto source = network::mojom::CSPSource::New( "http", "", url::PORT_UNSPECIFIED, "/allowed-path", true, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com/allowed-path"), &context)); - EXPECT_FALSE(Allow(source, GURL("http://a.com/disallowed-path"), &context)); + EXPECT_TRUE( + Allow(*source, GURL("http://a.com/allowed-path"), *self_source)); + EXPECT_FALSE( + Allow(*source, GURL("http://a.com/disallowed-path"), *self_source)); } } TEST(CSPSourceTest, RedirectMatching) { - CSPContext context; auto source = network::mojom::CSPSource::New("http", "a.com", 8000, "/bar/", false, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com:8000/"), &context, true)); - EXPECT_TRUE(Allow(source, GURL("http://a.com:8000/foo"), &context, true)); - EXPECT_FALSE(Allow(source, GURL("https://a.com:8000/foo"), &context, true)); + + // Self doesn't match anything. + auto self_source = network::mojom::CSPSource::New( + "", "", url::PORT_UNSPECIFIED, "", false, false); + + EXPECT_TRUE(Allow(*source, GURL("http://a.com:8000/"), *self_source, true)); + EXPECT_TRUE( + Allow(*source, GURL("http://a.com:8000/foo"), *self_source, true)); EXPECT_FALSE( - Allow(source, GURL("http://not-a.com:8000/foo"), &context, true)); - EXPECT_FALSE(Allow(source, GURL("http://a.com:9000/foo/"), &context, false)); + Allow(*source, GURL("https://a.com:8000/foo"), *self_source, true)); + EXPECT_FALSE( + Allow(*source, GURL("http://not-a.com:8000/foo"), *self_source, true)); + EXPECT_FALSE( + Allow(*source, GURL("http://a.com:9000/foo/"), *self_source, false)); } TEST(CSPSourceTest, Intersect) { @@ -373,14 +412,14 @@ auto a = CSPSource(test.a); auto b = CSPSource(test.b); - auto a_intersect_b = CSPSourcesIntersect(a, b); - auto b_intersect_a = CSPSourcesIntersect(b, a); + auto a_intersect_b = CSPSourcesIntersect(*a, *b); + auto b_intersect_a = CSPSourcesIntersect(*b, *a); if (test.intersection) { - EXPECT_EQ(test.intersection, ToString(a_intersect_b)) + EXPECT_EQ(test.intersection, ToString(*a_intersect_b)) << "The intersection of " << test.a << " and " << test.b << " should be " << test.intersection; // Intersection should be symmetric. - EXPECT_EQ(test.intersection, ToString(b_intersect_a)) + EXPECT_EQ(test.intersection, ToString(*b_intersect_a)) << "The intersection of " << test.b << " and " << test.a << " should be " << test.intersection; } else { @@ -416,9 +455,9 @@ auto a = CSPSource(test.a); auto b = CSPSource(test.b); - EXPECT_FALSE(CSPSourceSubsumes(a, b)) + EXPECT_FALSE(CSPSourceSubsumes(*a, *b)) << test.a << " should not subsume " << test.b; - EXPECT_FALSE(CSPSourceSubsumes(b, a)) + EXPECT_FALSE(CSPSourceSubsumes(*b, *a)) << test.b << " should not subsume " << test.a; } } @@ -466,22 +505,22 @@ auto a = CSPSource(test.a); auto b = CSPSource(test.b); - EXPECT_EQ(CSPSourceSubsumes(a, b), test.expected_a_subsumes_b) + EXPECT_EQ(CSPSourceSubsumes(*a, *b), test.expected_a_subsumes_b) << test.a << " subsumes " << test.b << " should return " << test.expected_a_subsumes_b; - EXPECT_EQ(CSPSourceSubsumes(b, a), test.expected_b_subsumes_a) + EXPECT_EQ(CSPSourceSubsumes(*b, *a), test.expected_b_subsumes_a) << test.b << " subsumes " << test.a << " should return " << test.expected_b_subsumes_a; a->is_host_wildcard = true; - EXPECT_FALSE(CSPSourceSubsumes(b, a)) - << test.b << " should not subsume " << ToString(a); + EXPECT_FALSE(CSPSourceSubsumes(*b, *a)) + << test.b << " should not subsume " << ToString(*a); // If also |b| has a wildcard host, then the result should be the expected // one. b->is_host_wildcard = true; - EXPECT_EQ(CSPSourceSubsumes(b, a), test.expected_b_subsumes_a) - << ToString(b) << " subsumes " << ToString(a) << " should return " + EXPECT_EQ(CSPSourceSubsumes(*b, *a), test.expected_b_subsumes_a) + << ToString(*b) << " subsumes " << ToString(*a) << " should return " << test.expected_b_subsumes_a; } } @@ -498,21 +537,21 @@ auto source_d = CSPSource(d); // *.example.com subsumes www.example.com. - EXPECT_TRUE(CSPSourceSubsumes(source_a, source_b)) + EXPECT_TRUE(CSPSourceSubsumes(*source_a, *source_b)) << a << " should subsume " << b; - EXPECT_FALSE(CSPSourceSubsumes(source_b, source_a)) + EXPECT_FALSE(CSPSourceSubsumes(*source_b, *source_a)) << b << " should not subsume " << a; // *.example.com and example.com have no relations. - EXPECT_FALSE(CSPSourceSubsumes(source_a, source_c)) + EXPECT_FALSE(CSPSourceSubsumes(*source_a, *source_c)) << a << " should not subsume " << c; - EXPECT_FALSE(CSPSourceSubsumes(source_c, source_a)) + EXPECT_FALSE(CSPSourceSubsumes(*source_c, *source_a)) << c << " should not subsume " << a; // https://*.example.com and http://www.example.com have no relations. - EXPECT_FALSE(CSPSourceSubsumes(source_d, source_b)) + EXPECT_FALSE(CSPSourceSubsumes(*source_d, *source_b)) << d << " should not subsume " << b; - EXPECT_FALSE(CSPSourceSubsumes(source_b, source_d)) + EXPECT_FALSE(CSPSourceSubsumes(*source_b, *source_d)) << b << " should not subsume " << d; } @@ -525,15 +564,15 @@ auto source_b = CSPSource(b); auto source_c = CSPSource(c); - EXPECT_TRUE(CSPSourceSubsumes(source_a, source_b)) + EXPECT_TRUE(CSPSourceSubsumes(*source_a, *source_b)) << a << " should subsume " << b; - EXPECT_FALSE(CSPSourceSubsumes(source_b, source_a)) + EXPECT_FALSE(CSPSourceSubsumes(*source_b, *source_a)) << b << " should not subsume " << a; // https://example.com:* and http://example.com have no relations. - EXPECT_FALSE(CSPSourceSubsumes(source_b, source_c)) + EXPECT_FALSE(CSPSourceSubsumes(*source_b, *source_c)) << b << " should not subsume " << c; - EXPECT_FALSE(CSPSourceSubsumes(source_c, source_b)) + EXPECT_FALSE(CSPSourceSubsumes(*source_c, *source_b)) << c << " should not subsume " << b; } @@ -564,7 +603,7 @@ for (const auto& test : cases) { auto source_a = CSPSource(test.a); auto source_b = CSPSource(test.b); - EXPECT_EQ(CSPSourceSubsumes(source_a, source_b), test.expected) + EXPECT_EQ(CSPSourceSubsumes(*source_a, *source_b), test.expected) << test.a << " subsumes " << test.b << " should return " << test.expected; } @@ -574,54 +613,58 @@ { auto source = network::mojom::CSPSource::New( "http", "", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_EQ("http:", ToString(source)); + EXPECT_EQ("http:", ToString(*source)); } { auto source = network::mojom::CSPSource::New( "http", "a.com", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_EQ("http://a.com", ToString(source)); + EXPECT_EQ("http://a.com", ToString(*source)); } { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "", false, false); - EXPECT_EQ("a.com", ToString(source)); + EXPECT_EQ("a.com", ToString(*source)); } { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "", true, false); - EXPECT_EQ("*.a.com", ToString(source)); + EXPECT_EQ("*.a.com", ToString(*source)); } { auto source = network::mojom::CSPSource::New("", "", url::PORT_UNSPECIFIED, "", true, false); - EXPECT_EQ("*", ToString(source)); + EXPECT_EQ("*", ToString(*source)); } { auto source = network::mojom::CSPSource::New("", "a.com", 80, "", false, false); - EXPECT_EQ("a.com:80", ToString(source)); + EXPECT_EQ("a.com:80", ToString(*source)); } { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "", false, true); - EXPECT_EQ("a.com:*", ToString(source)); + EXPECT_EQ("a.com:*", ToString(*source)); } { auto source = network::mojom::CSPSource::New( "", "a.com", url::PORT_UNSPECIFIED, "/path", false, false); - EXPECT_EQ("a.com/path", ToString(source)); + EXPECT_EQ("a.com/path", ToString(*source)); } } TEST(CSPSourceTest, UpgradeRequests) { - CSPContext context; auto source = network::mojom::CSPSource::New("http", "a.com", 80, "", false, false); - EXPECT_TRUE(Allow(source, GURL("http://a.com:80"), &context, true)); - EXPECT_FALSE(Allow(source, GURL("https://a.com:80"), &context, true)); - EXPECT_FALSE(Allow(source, GURL("http://a.com:443"), &context, true)); - EXPECT_TRUE(Allow(source, GURL("https://a.com:443"), &context, true)); - EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context, true)); + + // Self doesn't match anything. + auto self_source = network::mojom::CSPSource::New( + "", "", url::PORT_UNSPECIFIED, "", false, false); + + EXPECT_TRUE(Allow(*source, GURL("http://a.com:80"), *self_source, true)); + EXPECT_FALSE(Allow(*source, GURL("https://a.com:80"), *self_source, true)); + EXPECT_FALSE(Allow(*source, GURL("http://a.com:443"), *self_source, true)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com:443"), *self_source, true)); + EXPECT_TRUE(Allow(*source, GURL("https://a.com"), *self_source, true)); } } // namespace content
diff --git a/services/network/public/cpp/is_potentially_trustworthy_unittest.cc b/services/network/public/cpp/is_potentially_trustworthy_unittest.cc index 7f00f0c..2d77ed7 100644 --- a/services/network/public/cpp/is_potentially_trustworthy_unittest.cc +++ b/services/network/public/cpp/is_potentially_trustworthy_unittest.cc
@@ -21,7 +21,11 @@ return IsOriginAllowlisted(url::Origin::Create(GURL(str))); } -bool IsPotentiallyTrustworthy(const char* str) { +bool IsOriginPotentiallyTrustworthy(const char* str) { + return IsOriginPotentiallyTrustworthy(url::Origin::Create(GURL(str))); +} + +bool IsUrlPotentiallyTrustworthy(const char* str) { return IsUrlPotentiallyTrustworthy(GURL(str)); } @@ -32,7 +36,7 @@ allowlist, rejected_patterns); } -TEST(IsPotentiallyTrustworthy, MainTest) { +TEST(IsPotentiallyTrustworthy, Origin) { const url::Origin unique_origin; EXPECT_FALSE(IsOriginPotentiallyTrustworthy(unique_origin)); const url::Origin opaque_origin = @@ -40,85 +44,95 @@ .DeriveNewOpaqueOrigin(); EXPECT_FALSE(IsOriginPotentiallyTrustworthy(opaque_origin)); - EXPECT_TRUE(IsPotentiallyTrustworthy("about:blank")); - EXPECT_TRUE(IsPotentiallyTrustworthy("about:blank?x=2")); - EXPECT_TRUE(IsPotentiallyTrustworthy("about:blank#ref")); - EXPECT_TRUE(IsPotentiallyTrustworthy("about:blank?x=2#ref")); + EXPECT_FALSE(IsOriginPotentiallyTrustworthy("about:blank")); + EXPECT_FALSE(IsOriginPotentiallyTrustworthy("about:blank#ref")); + EXPECT_FALSE(IsOriginPotentiallyTrustworthy("about:srcdoc")); + EXPECT_FALSE(IsOriginPotentiallyTrustworthy("javascript:alert('blah')")); + EXPECT_FALSE(IsOriginPotentiallyTrustworthy("data:test/plain;blah")); +} - EXPECT_TRUE(IsPotentiallyTrustworthy("about:srcdoc")); - EXPECT_TRUE(IsPotentiallyTrustworthy("about:srcdoc?x=2")); - EXPECT_TRUE(IsPotentiallyTrustworthy("about:srcdoc#ref")); - EXPECT_TRUE(IsPotentiallyTrustworthy("about:srcdoc?x=2#ref")); +TEST(IsPotentiallyTrustworthy, Url) { + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:blank")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:blank?x=2")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:blank#ref")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:blank?x=2#ref")); - EXPECT_FALSE(IsPotentiallyTrustworthy("about:about")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:srcdoc")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:srcdoc?x=2")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:srcdoc#ref")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("about:srcdoc?x=2#ref")); + + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("about:about")); // TODO(https://crbug.com/1119740): Should return true for data: URLs. - EXPECT_FALSE(IsPotentiallyTrustworthy("data:test/plain;blah")); - EXPECT_FALSE(IsPotentiallyTrustworthy("javascript:alert('blah')")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("data:test/plain;blah")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("javascript:alert('blah')")); - EXPECT_TRUE(IsPotentiallyTrustworthy("file:///test/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("file:///test/")); - EXPECT_TRUE(IsPotentiallyTrustworthy("file://localhost/test/")); - EXPECT_TRUE(IsPotentiallyTrustworthy("file://otherhost/test/")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("file:///test/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("file:///test/")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("file://localhost/test/")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("file://otherhost/test/")); - EXPECT_TRUE(IsPotentiallyTrustworthy("https://example.com/fun.html")); - EXPECT_FALSE(IsPotentiallyTrustworthy("http://example.com/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("https://example.com/fun.html")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://example.com/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("wss://example.com/fun.html")); - EXPECT_FALSE(IsPotentiallyTrustworthy("ws://example.com/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("wss://example.com/fun.html")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("ws://example.com/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("http://localhost/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("http://localhost./fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("http://pumpkin.localhost/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://localhost/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://localhost./fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://pumpkin.localhost/fun.html")); EXPECT_TRUE( - IsPotentiallyTrustworthy("http://crumpet.pumpkin.localhost/fun.html")); + IsUrlPotentiallyTrustworthy("http://crumpet.pumpkin.localhost/fun.html")); EXPECT_TRUE( - IsPotentiallyTrustworthy("http://pumpkin.localhost:8080/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy( + IsUrlPotentiallyTrustworthy("http://pumpkin.localhost:8080/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy( "http://crumpet.pumpkin.localhost:3000/fun.html")); - EXPECT_FALSE(IsPotentiallyTrustworthy("http://localhost.com/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("https://localhost.com/fun.html")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://localhost.com/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("https://localhost.com/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("http://127.0.0.1/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("ftp://127.0.0.1/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("http://127.3.0.1/fun.html")); - EXPECT_FALSE(IsPotentiallyTrustworthy("http://127.example.com/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("https://127.example.com/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://127.0.0.1/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("ftp://127.0.0.1/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://127.3.0.1/fun.html")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://127.example.com/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("https://127.example.com/fun.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("http://[::1]/fun.html")); - EXPECT_FALSE(IsPotentiallyTrustworthy("http://[::2]/fun.html")); - EXPECT_FALSE(IsPotentiallyTrustworthy("http://[::1].example.com/fun.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://[::1]/fun.html")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://[::2]/fun.html")); + EXPECT_FALSE( + IsUrlPotentiallyTrustworthy("http://[::1].example.com/fun.html")); // IPv4 mapped IPv6 literals for loopback. - EXPECT_FALSE(IsPotentiallyTrustworthy("http://[::ffff:127.0.0.1]/")); - EXPECT_FALSE(IsPotentiallyTrustworthy("http://[::ffff:7f00:1]")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://[::ffff:127.0.0.1]/")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://[::ffff:7f00:1]")); // IPv4 compatible IPv6 literal for loopback. - EXPECT_FALSE(IsPotentiallyTrustworthy("http://[::127.0.0.1]")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://[::127.0.0.1]")); - EXPECT_FALSE(IsPotentiallyTrustworthy("http://loopback")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://loopback")); // TODO(https://crbug.com/1153337): Return false? - EXPECT_TRUE(IsPotentiallyTrustworthy("http://localhost6")); - EXPECT_TRUE(IsPotentiallyTrustworthy("ftp://localhost6.localdomain6")); - EXPECT_TRUE(IsPotentiallyTrustworthy("http://localhost.localdomain")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://localhost6")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("ftp://localhost6.localdomain6")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://localhost.localdomain")); - EXPECT_FALSE( - IsPotentiallyTrustworthy("filesystem:http://www.example.com/temporary/")); - EXPECT_FALSE( - IsPotentiallyTrustworthy("filesystem:ftp://www.example.com/temporary/")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy( + "filesystem:http://www.example.com/temporary/")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy( + "filesystem:ftp://www.example.com/temporary/")); EXPECT_TRUE( - IsPotentiallyTrustworthy("filesystem:ftp://127.0.0.1/temporary/")); - EXPECT_TRUE(IsPotentiallyTrustworthy( + IsUrlPotentiallyTrustworthy("filesystem:ftp://127.0.0.1/temporary/")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy( "filesystem:https://www.example.com/temporary/")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy( + "blob:http://www.example.com/guid-goes-here")); EXPECT_FALSE( - IsPotentiallyTrustworthy("blob:http://www.example.com/guid-goes-here")); - EXPECT_FALSE( - IsPotentiallyTrustworthy("blob:ftp://www.example.com/guid-goes-here")); - EXPECT_TRUE(IsPotentiallyTrustworthy("blob:ftp://127.0.0.1/guid-goes-here")); + IsUrlPotentiallyTrustworthy("blob:ftp://www.example.com/guid-goes-here")); EXPECT_TRUE( - IsPotentiallyTrustworthy("blob:https://www.example.com/guid-goes-here")); + IsUrlPotentiallyTrustworthy("blob:ftp://127.0.0.1/guid-goes-here")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy( + "blob:https://www.example.com/guid-goes-here")); } class SecureOriginAllowlistTest : public testing::Test { @@ -131,8 +145,8 @@ TEST_F(SecureOriginAllowlistTest, UnsafelyTreatInsecureOriginAsSecure) { EXPECT_FALSE(IsOriginAllowlisted("http://example.com/a.html")); EXPECT_FALSE(IsOriginAllowlisted("http://127.example.com/a.html")); - EXPECT_FALSE(IsPotentiallyTrustworthy("http://example.com/a.html")); - EXPECT_FALSE(IsPotentiallyTrustworthy("http://127.example.com/a.html")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://example.com/a.html")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://127.example.com/a.html")); // Add http://example.com and http://127.example.com to allowlist by // command-line and see if they are now considered secure origins. @@ -146,13 +160,13 @@ // They should be now allow-listed. EXPECT_TRUE(IsOriginAllowlisted("http://example.com/a.html")); EXPECT_TRUE(IsOriginAllowlisted("http://127.example.com/a.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("http://example.com/a.html")); - EXPECT_TRUE(IsPotentiallyTrustworthy("http://127.example.com/a.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://example.com/a.html")); + EXPECT_TRUE(IsUrlPotentiallyTrustworthy("http://127.example.com/a.html")); // Check that similarly named sites are not considered secure. - EXPECT_FALSE(IsPotentiallyTrustworthy("http://128.example.com/a.html")); + EXPECT_FALSE(IsUrlPotentiallyTrustworthy("http://128.example.com/a.html")); EXPECT_FALSE( - IsPotentiallyTrustworthy("http://foobar.127.example.com/a.html")); + IsUrlPotentiallyTrustworthy("http://foobar.127.example.com/a.html")); // When port is not specified, default port is assumed. EXPECT_TRUE(IsOriginAllowlisted("http://example.com:80/a.html")); @@ -209,7 +223,8 @@ GURL input_url(test.test_input); url::Origin input_origin = url::Origin::Create(input_url); EXPECT_EQ(test.expected_secure, IsOriginAllowlisted(input_origin)); - EXPECT_EQ(test.expected_secure, IsPotentiallyTrustworthy(test.test_input)); + EXPECT_EQ(test.expected_secure, + IsUrlPotentiallyTrustworthy(test.test_input)); } }
diff --git a/services/network/public/mojom/content_security_policy.mojom b/services/network/public/mojom/content_security_policy.mojom index 03e4c4c..c4cc0c8 100644 --- a/services/network/public/mojom/content_security_policy.mojom +++ b/services/network/public/mojom/content_security_policy.mojom
@@ -148,6 +148,10 @@ }; struct ContentSecurityPolicy { + // The origin used for matching the 'self' keyword. + // https://w3c.github.io/webappsec-csp/#framework-policy + CSPSource self_origin; + // The raw, unparsed values of the specified CSP directives. Needed for // reporting. map<CSPDirectiveName, string> raw_directives;
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 8499cb5..ae51d21 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -2714,9 +2714,6 @@ "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" }, { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter" - ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4407,9 +4404,6 @@ "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" }, { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter" - ], "isolate_profile_data": true, "merge": { "args": [],
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 36b110a7..07227be4 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -8516,8 +8516,7 @@ }, { "args": [ - "--test-launcher-print-test-stdio=always", - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter" + "--test-launcher-print-test-stdio=always" ], "merge": { "args": [], @@ -10482,8 +10481,7 @@ }, { "args": [ - "--test-launcher-print-test-stdio=always", - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter" + "--test-launcher-print-test-stdio=always" ], "merge": { "args": [],
diff --git a/testing/buildbot/filters/chromeos.unit_tests.filter b/testing/buildbot/filters/chromeos.unit_tests.filter index fec4cb0..31510467 100644 --- a/testing/buildbot/filters/chromeos.unit_tests.filter +++ b/testing/buildbot/filters/chromeos.unit_tests.filter
@@ -1,4 +1,2 @@ -# TODO(crbug.com/970790): Enable this. --InputMethodManagerImplTest.SetLoginDefaultWithAllowedKeyboardLayouts # TODO(crbug.com/970806): Enable this. -KeyboardShortcutViewerMetadataTest.ModifyAcceleratorShouldUpdateMetadata
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index c649fc908..1ffce50b 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2707,9 +2707,6 @@ }, }, 'Linux Chromium OS ASan LSan Tests (1)': { - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter', - ], # These are slow on the ASAN trybot for some reason. # crbug.com/794372 'swarming': { @@ -2717,9 +2714,6 @@ }, }, 'Linux ChromiumOS MSan Tests': { - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter', - ], # These are very slow on the Chrome OS MSAN trybot for some reason. # crbug.com/865455 'swarming': { @@ -2752,17 +2746,11 @@ ], }, 'linux-chromeos-dbg': { - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter', - ], 'swarming': { 'shards': 2, }, }, 'linux-chromeos-rel': { - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter', - ], 'swarming': { 'shards': 2, },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 407c1f3d..8b2879e 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -4864,7 +4864,8 @@ "OmniboxMaxZeroSuggestMatches", "OmniboxOnFocusSuggestionsContextualWebOnContent", "OmniboxTrendingZeroPrefixSuggestionsOnNTP", - "OmniboxUIExperimentMaxAutocompleteMatches" + "OmniboxUIExperimentMaxAutocompleteMatches", + "OmniboxZeroSuggestCaching" ] } ]
diff --git a/third_party/android_deps/fetch_all.py b/third_party/android_deps/fetch_all.py index 1fdb6eb2..b5f0c77 100755 --- a/third_party/android_deps/fetch_all.py +++ b/third_party/android_deps/fetch_all.py
@@ -540,9 +540,6 @@ Copy(_CHROMIUM_SRC, list(copied_paths.keys()), build_dir, list(copied_paths.values())) - if debug: - gradle_cmd.append('--debug') - if not args.ignore_vulnerabilities: report_dst = os.path.join(abs_android_deps_dir, 'vulnerability_reports')
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index c86612d..082d0b5 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3062,6 +3062,8 @@ kCrossOriginJsonTypeForScript = 3738, kSameOriginStrictNosniffWouldBlock = 3739, kCrossOriginStrictNosniffWouldBlock = 3740, + kCSSSelectorPseudoDir = 3741, + kCrossOriginSubframeWithoutEmbeddingControl = 3742, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/web_content_security_policy_struct.h b/third_party/blink/public/platform/web_content_security_policy_struct.h index d4d20a59..e971bd6 100644 --- a/third_party/blink/public/platform/web_content_security_policy_struct.h +++ b/third_party/blink/public/platform/web_content_security_policy_struct.h
@@ -91,6 +91,7 @@ struct WebContentSecurityPolicy { network::mojom::ContentSecurityPolicyType disposition; network::mojom::ContentSecurityPolicySource source; + WebContentSecurityPolicySourceExpression self_origin; WebVector<WebContentSecurityPolicyRawDirective> raw_directives; WebVector<WebContentSecurityPolicyDirective> directives; bool upgrade_insecure_requests;
diff --git a/third_party/blink/public/web/web_navigation_params.h b/third_party/blink/public/web/web_navigation_params.h index 92fc4cca..13a9508d 100644 --- a/third_party/blink/public/web/web_navigation_params.h +++ b/third_party/blink/public/web/web_navigation_params.h
@@ -143,10 +143,6 @@ // checks. WebVector<WebContentSecurityPolicy> initiator_csp; - // The navigation initiator source to be used when comparing an URL against - // 'self'. - WebContentSecurityPolicySourceExpression initiator_self_source; - // The navigation initiator, if any. CrossVariantMojoRemote<mojom::NavigationInitiatorInterfaceBase> navigation_initiator_remote;
diff --git a/third_party/blink/renderer/bindings/core/v8/generated.gni b/third_party/blink/renderer/bindings/core/v8/generated.gni index 3cffd6d..01938ee0 100644 --- a/third_party/blink/renderer/bindings/core/v8/generated.gni +++ b/third_party/blink/renderer/bindings/core/v8/generated.gni
@@ -76,6 +76,8 @@ "$bindings_core_v8_output_dir/node_or_string_or_trusted_script.h", "$bindings_core_v8_output_dir/radio_node_list_or_element.cc", "$bindings_core_v8_output_dir/radio_node_list_or_element.h", + "$bindings_core_v8_output_dir/readable_stream_default_controller_or_readable_byte_stream_controller.cc", + "$bindings_core_v8_output_dir/readable_stream_default_controller_or_readable_byte_stream_controller.h", "$bindings_core_v8_output_dir/readable_stream_default_reader_or_readable_stream_byob_reader.cc", "$bindings_core_v8_output_dir/readable_stream_default_reader_or_readable_stream_byob_reader.h", "$bindings_core_v8_output_dir/request_or_usv_string.cc",
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni index 3053c0b..7c07269 100644 --- a/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -57,6 +57,12 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_callback.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_state_callback.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_state_callback.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source_cancel_callback.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source_cancel_callback.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source_pull_callback.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source_pull_callback.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source_start_callback.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source_start_callback.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_void_function.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_void_function.h", ] @@ -333,6 +339,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ua_data_values.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ui_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ui_event_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_validity_state_flags.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_validity_state_flags.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_wheel_event_init.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni index 91b90a0..394b33d 100644 --- a/third_party/blink/renderer/bindings/idl_in_core.gni +++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -502,7 +502,11 @@ "//third_party/blink/renderer/core/streams/transform_stream.idl", "//third_party/blink/renderer/core/streams/transform_stream_default_controller.idl", "//third_party/blink/renderer/core/streams/underlying_sink_base.idl", + "//third_party/blink/renderer/core/streams/underlying_source.idl", "//third_party/blink/renderer/core/streams/underlying_source_base.idl", + "//third_party/blink/renderer/core/streams/underlying_source_cancel_callback.idl", + "//third_party/blink/renderer/core/streams/underlying_source_pull_callback.idl", + "//third_party/blink/renderer/core/streams/underlying_source_start_callback.idl", "//third_party/blink/renderer/core/streams/writable_stream.idl", "//third_party/blink/renderer/core/streams/writable_stream_default_controller.idl", "//third_party/blink/renderer/core/streams/writable_stream_default_writer.idl",
diff --git a/third_party/blink/renderer/core/OWNERS b/third_party/blink/renderer/core/OWNERS index b3dab08..ef6c5dd 100644 --- a/third_party/blink/renderer/core/OWNERS +++ b/third_party/blink/renderer/core/OWNERS
@@ -25,6 +25,7 @@ fs@opera.com fserb@chromium.org futhark@chromium.org +fwang@igalia.com haraken@chromium.org hayato@chromium.org hiroshige@chromium.org
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni index ff73bfb..5210c5af 100644 --- a/third_party/blink/renderer/core/core_idl_files.gni +++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -617,6 +617,9 @@ "dom/function_string_callback.idl", "dom/idle_request_callback.idl", "dom/void_function.idl", + "streams/underlying_source_cancel_callback.idl", + "streams/underlying_source_pull_callback.idl", + "streams/underlying_source_start_callback.idl", ], "abspath") @@ -749,6 +752,7 @@ "streams/readable_stream_get_reader_options.idl", "streams/readable_writable_pair.idl", "streams/stream_pipe_options.idl", + "streams/underlying_source.idl", "streams/queuing_strategy_init.idl", "timing/measure_memory/memory_measurement.idl", "timing/measure_memory/memory_breakdown_entry.idl",
diff --git a/third_party/blink/renderer/core/css/css_selector.cc b/third_party/blink/renderer/core/css/css_selector.cc index eae5a8d1..2fe23d0 100644 --- a/third_party/blink/renderer/core/css/css_selector.cc +++ b/third_party/blink/renderer/core/css/css_selector.cc
@@ -289,6 +289,7 @@ case kPseudoIndeterminate: case kPseudoTarget: case kPseudoLang: + case kPseudoDir: case kPseudoNot: case kPseudoRoot: case kPseudoScope: @@ -456,6 +457,7 @@ const static NameToPseudoStruct kPseudoTypeWithArgumentsMap[] = { {"-webkit-any", CSSSelector::kPseudoAny}, {"cue", CSSSelector::kPseudoCue}, + {"dir", CSSSelector::kPseudoDir}, {"host", CSSSelector::kPseudoHost}, {"host-context", CSSSelector::kPseudoHostContext}, {"is", CSSSelector::kPseudoIs}, @@ -501,6 +503,10 @@ if (match == pseudo_type_map_end || match->string != name.GetString()) return CSSSelector::kPseudoUnknown; + if (match->type == CSSSelector::kPseudoDir && + !RuntimeEnabledFeatures::CSSPseudoDirEnabled()) + return CSSSelector::kPseudoUnknown; + if (match->type == CSSSelector::kPseudoFocusVisible && !RuntimeEnabledFeatures::CSSFocusVisibleEnabled()) return CSSSelector::kPseudoUnknown; @@ -667,6 +673,7 @@ case kPseudoDefault: case kPseudoDefined: case kPseudoDisabled: + case kPseudoDir: case kPseudoDoubleButton: case kPseudoDrag: case kPseudoEmpty: @@ -836,6 +843,7 @@ builder.Append(')'); break; } + case kPseudoDir: case kPseudoLang: case kPseudoState: builder.Append('(');
diff --git a/third_party/blink/renderer/core/css/css_selector.h b/third_party/blink/renderer/core/css/css_selector.h index f92f728b..7333575b 100644 --- a/third_party/blink/renderer/core/css/css_selector.h +++ b/third_party/blink/renderer/core/css/css_selector.h
@@ -272,6 +272,7 @@ kPseudoVideoPersistent, kPseudoVideoPersistentAncestor, kPseudoTargetText, + kPseudoDir, }; enum class AttributeMatchType {
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc index c6e016e..37e92d0 100644 --- a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc +++ b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
@@ -762,6 +762,7 @@ selector->SetSelectorList(std::move(selector_list)); return selector; } + case CSSSelector::kPseudoDir: case CSSSelector::kPseudoState: { const CSSParserToken& ident = block.ConsumeIncludingWhitespace(); if (ident.GetType() != kIdentToken || !block.AtEnd()) @@ -1323,6 +1324,10 @@ case CSSSelector::kPseudoReadWrite: feature = WebFeature::kCSSSelectorPseudoReadWrite; break; + case CSSSelector::kPseudoDir: + DCHECK(RuntimeEnabledFeatures::CSSPseudoDirEnabled()); + feature = WebFeature::kCSSSelectorPseudoDir; + break; default: break; }
diff --git a/third_party/blink/renderer/core/css/rule_feature_set.cc b/third_party/blink/renderer/core/css/rule_feature_set.cc index aa23290..c7dad52 100644 --- a/third_party/blink/renderer/core/css/rule_feature_set.cc +++ b/third_party/blink/renderer/core/css/rule_feature_set.cc
@@ -128,6 +128,7 @@ case CSSSelector::kPseudoModal: case CSSSelector::kPseudoBackdrop: case CSSSelector::kPseudoLang: + case CSSSelector::kPseudoDir: case CSSSelector::kPseudoNot: case CSSSelector::kPseudoPlaceholder: case CSSSelector::kPseudoResizer: @@ -595,6 +596,7 @@ case CSSSelector::kPseudoIndeterminate: case CSSSelector::kPseudoTarget: case CSSSelector::kPseudoLang: + case CSSSelector::kPseudoDir: case CSSSelector::kPseudoFullScreen: case CSSSelector::kPseudoFullScreenAncestor: case CSSSelector::kPseudoFullscreen:
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc index a63926d..6b48bbf 100644 --- a/third_party/blink/renderer/core/css/selector_checker.cc +++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -1070,6 +1070,24 @@ break; return true; } + case CSSSelector::kPseudoDir: { + const AtomicString& argument = selector.Argument(); + if (argument.IsEmpty()) + break; + + TextDirection direction; + if (EqualIgnoringASCIICase(argument, "ltr")) + direction = TextDirection::kLtr; + else if (EqualIgnoringASCIICase(argument, "rtl")) + direction = TextDirection::kRtl; + else + break; + + if (auto* html_element = DynamicTo<HTMLElement>(element)) { + return html_element->ComputeInheritedDirectionality() == direction; + } + break; + } case CSSSelector::kPseudoFullscreen: // fall through case CSSSelector::kPseudoFullScreen:
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index cd498e84..04e9904 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -1965,13 +1965,36 @@ return initial_data_; } -void StyleEngine::RecalcStyle() { +void StyleEngine::UpdateStyleAndLayoutTreeForContainer(Element& container) { + DCHECK(!style_recalc_root_.GetRootNode()); + DCHECK(!container.NeedsStyleRecalc()); + DCHECK(!in_container_query_style_recalc_); + + base::AutoReset<bool> cq_recalc(&in_container_query_style_recalc_, true); + + style_recalc_root_.Update(nullptr, &container); + RecalcStyle({StyleRecalcChange::kRecalcContainerQueryDependent}); + + if (container.ChildNeedsReattachLayoutTree()) { + DCHECK(layout_tree_rebuild_root_.GetRootNode()); + if (layout_tree_rebuild_root_.GetRootNode()->IsDocumentNode()) { + // Avoid traversing from outside the container root. We know none of the + // elements outside the subtree should be marked dirty in this pass, but + // we may have fallen back to the document root. + layout_tree_rebuild_root_.Clear(); + layout_tree_rebuild_root_.Update(nullptr, &container); + } + RebuildLayoutTree(); + } +} + +void StyleEngine::RecalcStyle(StyleRecalcChange change) { DCHECK(GetDocument().documentElement()); Element* root_element = &style_recalc_root_.RootElement(); Element* parent = root_element->ParentOrShadowHostElement(); SelectorFilterRootScope filter_scope(parent); - root_element->RecalcStyle({}); + root_element->RecalcStyle(change); for (ContainerNode* ancestor = root_element->GetStyleRecalcParent(); ancestor; ancestor = ancestor->GetStyleRecalcParent()) { @@ -2003,7 +2026,7 @@ void StyleEngine::RebuildLayoutTree() { DCHECK(GetDocument().documentElement()); DCHECK(!InRebuildLayoutTree()); - in_layout_tree_rebuild_ = true; + base::AutoReset<bool> rebuild_scope(&in_layout_tree_rebuild_, true); // We need a root scope here in case we recalc style for ::first-letter // elements as part of UpdateFirstLetterPseudoElement. @@ -2023,7 +2046,6 @@ ancestor->ClearChildNeedsReattachLayoutTree(); } layout_tree_rebuild_root_.Clear(); - in_layout_tree_rebuild_ = false; } void StyleEngine::UpdateStyleAndLayoutTree() { @@ -2108,7 +2130,7 @@ DCHECK(allow_mark_style_dirty_from_recalc_); return; } - DCHECK(!in_layout_tree_rebuild_); + DCHECK(!InRebuildLayoutTree()); if (in_dom_removal_) { ancestor = nullptr; dirty_node = document_;
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index be5762e..58d8d8e7 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -398,10 +398,16 @@ void UpdateViewport(); void UpdateViewportStyle(); void UpdateStyleAndLayoutTree(); - void RecalcStyle(); + // To be called from layout when container queries change for the container. + void UpdateStyleAndLayoutTreeForContainer(Element& container); + void RecalcStyle() { RecalcStyle({}); } + void ClearEnsuredDescendantStyles(Element& element); void RebuildLayoutTree(); bool InRebuildLayoutTree() const { return in_layout_tree_rebuild_; } + bool InContainerQueryStyleRecalc() const { + return in_container_query_style_recalc_; + } void SetColorSchemeFromMeta(const CSSValue* color_scheme); const CSSValue* GetMetaColorSchemeValue() const { return meta_color_scheme_; } @@ -531,6 +537,8 @@ void ViewportDefiningElementDidChange(); void PropagateWritingModeAndDirectionToHTMLRoot(); + void RecalcStyle(StyleRecalcChange); + Member<Document> document_; // True if this StyleEngine is for an HTML Import document. @@ -582,6 +590,7 @@ bool uses_rem_units_{false}; bool in_layout_tree_rebuild_{false}; + bool in_container_query_style_recalc_{false}; bool in_dom_removal_{false}; bool viewport_style_dirty_{false}; bool fonts_need_update_{false};
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index f410045f..3242875 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -3764,4 +3764,67 @@ ClearUseCounter(WebFeature::kCSSPseudoHostDynamicSpecificity); } +namespace { + +void SetDependsOnContainerQueries(HTMLCollection& affected) { + for (Element* element : affected) { + if (const ComputedStyle* style = element->GetComputedStyle()) { + scoped_refptr<ComputedStyle> cloned_style = ComputedStyle::Clone(*style); + cloned_style->SetDependsOnContainerQueries(true); + element->SetComputedStyle(cloned_style); + } + } +} + +} // namespace + +TEST_F(StyleEngineTest, UpdateStyleAndLayoutTreeForContainer) { + GetDocument().body()->setInnerHTML(R"HTML( + <div id="container1" style="contain:layout"> + <span class="affected"></span> + <div id="container2" style="contain:layout" class="affected"> + <span class="affected"></span> + <span></span> + <span class="affected"></span> + <span></span> + <span class="affected"></span> + <div style="display:none" class="affected"> + <span class="affected"></span> + </div> + <div style="display:none"> + <span class="affected"></span> + <span class="affected"></span> + </div> + </div> + <span></span> + <div id="container3" style="contain:layout"> + <span class="affected"></span> + <span class="affected"></span> + </div> + </div> + )HTML"); + + UpdateAllLifecyclePhases(); + + auto* container1 = GetDocument().getElementById("container1"); + auto* container2 = GetDocument().getElementById("container2"); + auto* affected = GetDocument().getElementsByClassName("affected"); + ASSERT_TRUE(container1); + ASSERT_TRUE(container2); + ASSERT_TRUE(affected); + SetDependsOnContainerQueries(*affected); + + unsigned start_count = GetStyleEngine().StyleForElementCount(); + GetStyleEngine().UpdateStyleAndLayoutTreeForContainer(*container1); + + // The first span.affected child and #container2 + EXPECT_EQ(2u, GetStyleEngine().StyleForElementCount() - start_count); + + start_count = GetStyleEngine().StyleForElementCount(); + GetStyleEngine().UpdateStyleAndLayoutTreeForContainer(*container2); + + // Three direct span.affected children, and the two display:none elements. + EXPECT_EQ(5u, GetStyleEngine().StyleForElementCount() - start_count); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/style_recalc.cc b/third_party/blink/renderer/core/css/style_recalc.cc index 757a6a7..1c6a42c 100644 --- a/third_party/blink/renderer/core/css/style_recalc.cc +++ b/third_party/blink/renderer/core/css/style_recalc.cc
@@ -9,12 +9,13 @@ namespace blink { -bool StyleRecalcChange::TraverseChildren(const Node& node) const { - return RecalcChildren() || node.ChildNeedsStyleRecalc(); +bool StyleRecalcChange::TraverseChildren(const Element& element) const { + return RecalcChildren() || RecalcContainerQueryDependent() || + element.ChildNeedsStyleRecalc(); } -bool StyleRecalcChange::TraversePseudoElements(const Node& node) const { - return UpdatePseudoElements() || node.ChildNeedsStyleRecalc(); +bool StyleRecalcChange::TraversePseudoElements(const Element& element) const { + return UpdatePseudoElements() || element.ChildNeedsStyleRecalc(); } bool StyleRecalcChange::TraverseChild(const Node& node) const { @@ -28,11 +29,19 @@ return true; if (node.GetForceReattachLayoutTree()) return true; - if (propagate_ != kClearEnsured) + // Early exit before getting the computed style. + if (propagate_ != kClearEnsured && !RecalcContainerQueryDependent()) return false; - if (const ComputedStyle* old_style = node.GetComputedStyle()) - return old_style->IsEnsuredInDisplayNone(); - return false; + if (const ComputedStyle* old_style = node.GetComputedStyle()) { + return (propagate_ == kClearEnsured && + old_style->IsEnsuredInDisplayNone()) || + (RecalcContainerQueryDependent() && + old_style->DependsOnContainerQueries()); + } + // Container queries may affect display:none elements, and we since we store + // that dependency on ComputedStyle we need to recalc style for display:none + // subtree roots. + return RecalcContainerQueryDependent(); } bool StyleRecalcChange::ShouldUpdatePseudoElement( @@ -40,4 +49,19 @@ return UpdatePseudoElements() || pseudo_element.NeedsStyleRecalc(); } +bool StyleRecalcChange::RecalcContainerQueryDependentChildren( + const Element& element) const { + // We are at the container root for a container query recalc. + if (propagate_ == kRecalcContainerQueryDependent) + return true; + if (!RecalcContainerQueryDependent()) + return false; + // Don't traverse into children if we hit a descendant container while + // recalculating container queries. If the queries for this container also + // changes, we will enter another container query recalc for this subtree from + // layout. + const ComputedStyle* style = element.GetComputedStyle(); + return style && !style->IsContainerForContainerQueries(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/style_recalc.h b/third_party/blink/renderer/core/css/style_recalc.h index 6fb3c21..3b014d1 100644 --- a/third_party/blink/renderer/core/css/style_recalc.h +++ b/third_party/blink/renderer/core/css/style_recalc.h
@@ -7,6 +7,7 @@ namespace blink { +class Element; class Node; class PseudoElement; @@ -21,6 +22,11 @@ // Need to traverse children in display:none or non-slotted/distributed // children of shadow hosts to clear ensured computed styles. kClearEnsured, + // Need to traverse descendants to invalidate style for container queries. + // This value is passed in for the container itself, it will translate into + // recalc_container_query_dependent_=true for descendants. We should not + // recalc style for the container itself. + kRecalcContainerQueryDependent, // Need to update existence and style for pseudo elements. kUpdatePseudoElements, // Need to recalculate style for children for inheritance. All changed @@ -37,24 +43,25 @@ StyleRecalcChange(const StyleRecalcChange&) = default; StyleRecalcChange(Propagate propagate) : propagate_(propagate) {} - StyleRecalcChange ForChildren() const { - return {RecalcDescendants() ? kRecalcDescendants : kNo, reattach_}; + StyleRecalcChange ForChildren(const Element& element) const { + return {RecalcDescendants() ? kRecalcDescendants : kNo, reattach_, + RecalcContainerQueryDependentChildren(element)}; } StyleRecalcChange ForPseudoElement() const { if (propagate_ == kUpdatePseudoElements) - return {kRecalcChildren, reattach_}; + return {kRecalcChildren, reattach_, recalc_container_query_dependent_}; return *this; } StyleRecalcChange EnsureAtLeast(Propagate propagate) const { if (propagate > propagate_) - return {propagate, reattach_}; - return {propagate_, reattach_}; + return {propagate, reattach_, recalc_container_query_dependent_}; + return {propagate_, reattach_, recalc_container_query_dependent_}; } StyleRecalcChange ForceRecalcDescendants() const { - return {kRecalcDescendants, reattach_}; + return {kRecalcDescendants, reattach_, recalc_container_query_dependent_}; } StyleRecalcChange ForceReattachLayoutTree() const { - return {propagate_, true}; + return {propagate_, true, recalc_container_query_dependent_}; } bool ReattachLayoutTree() const { return reattach_; } @@ -62,20 +69,31 @@ bool RecalcDescendants() const { return propagate_ == kRecalcDescendants; } bool UpdatePseudoElements() const { return propagate_ != kNo; } bool IndependentInherit() const { return propagate_ == kIndependentInherit; } - bool TraverseChildren(const Node&) const; + bool TraverseChildren(const Element&) const; bool TraverseChild(const Node&) const; - bool TraversePseudoElements(const Node&) const; + bool TraversePseudoElements(const Element&) const; bool ShouldRecalcStyleFor(const Node&) const; bool ShouldUpdatePseudoElement(const PseudoElement&) const; private: - StyleRecalcChange(Propagate propagate, bool reattach) - : propagate_(propagate), reattach_(reattach) {} + StyleRecalcChange(Propagate propagate, + bool reattach, + bool recalc_container_query_dependent) + : propagate_(propagate), + reattach_(reattach), + recalc_container_query_dependent_(recalc_container_query_dependent) {} + + bool RecalcContainerQueryDependent() const { + return recalc_container_query_dependent_; + } + bool RecalcContainerQueryDependentChildren(const Element&) const; // To what extent do we need to update style for children. Propagate propagate_ = kNo; // Need to reattach layout tree if true. bool reattach_ = false; + // Force recalc of elements depending on container queries. + bool recalc_container_query_dependent_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index ffa8263..5681b9e 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2086,6 +2086,8 @@ // recalc. if (lifecycle_.GetState() == DocumentLifecycle::kInPreLayout) return false; + if (lifecycle_.GetState() == DocumentLifecycle::kInPerformLayout) + return false; if (!ShouldScheduleLayout()) return false; return true; @@ -8546,6 +8548,11 @@ return find_in_page_active_match_node_; } +bool Document::InStyleRecalc() const { + return lifecycle_.GetState() == DocumentLifecycle::kInStyleRecalc || + style_engine_->InContainerQueryStyleRecalc(); +} + template class CORE_TEMPLATE_EXPORT Supplement<Document>; } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index d74249f..815f14c 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -1345,9 +1345,7 @@ void DidLoadAllPendingParserBlockingStylesheets(); void DidRemoveAllPendingStylesheets(); - bool InStyleRecalc() const { - return lifecycle_.GetState() == DocumentLifecycle::kInStyleRecalc; - } + bool InStyleRecalc() const; // Return a Locale for the default locale if the argument is null or empty. Locale& GetCachedLocale(const AtomicString& locale = g_null_atom);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 16c47ad..5ffe395 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2880,7 +2880,7 @@ if (HasCustomStyleCallbacks()) WillRecalcStyle(change); - StyleRecalcChange child_change = change.ForChildren(); + StyleRecalcChange child_change = change.ForChildren(*this); if (change.ShouldRecalcStyleFor(*this)) { child_change = RecalcOwnStyle(change); if (GetStyleChangeType() == kSubtreeStyleChange) @@ -3029,7 +3029,7 @@ scoped_refptr<ComputedStyle> new_style; scoped_refptr<const ComputedStyle> old_style = GetComputedStyle(); - StyleRecalcChange child_change = change.ForChildren(); + StyleRecalcChange child_change = change.ForChildren(*this); if (ParentComputedStyle()) { if (old_style && change.IndependentInherit()) { @@ -4960,6 +4960,32 @@ return style.Display() == EDisplay::kContents; } +bool Element::ComputeInheritedDirPseudoClass(TextDirection direction) const { + const Node* n = this; + // The dir property is inherited, so we iterate over the parents to find + // the first dir attribute. + do { + if (auto* element_node = DynamicTo<Element>(n)) { + AtomicString dir_attribute_value = + element_node->FastGetAttribute(html_names::kDirAttr); + if ((IsA<HTMLBDIElement>(*element_node) && !dir_attribute_value) || + (IsHTMLElement() && + EqualIgnoringASCIICase(dir_attribute_value, "auto"))) { + return element_node->MatchesDirPseudoClassForDirAutoAttribute( + direction); + } + + if (EqualIgnoringASCIICase(dir_attribute_value, "ltr")) + return IsLtr(direction); + else if (EqualIgnoringASCIICase(dir_attribute_value, "rtl")) + return IsRtl(direction); + } + n = n->ParentOrShadowHostNode(); + } while (n); + + return IsLtr(direction); +} + AtomicString Element::ComputeInheritedLanguage() const { const Node* n = this; AtomicString value;
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 528fcab..f1a350b 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -40,6 +40,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string_table.h" @@ -609,6 +610,12 @@ return GetV0CustomElementState() == kV0WaitingForUpgrade; } + bool ComputeInheritedDirPseudoClass(TextDirection direction) const; + virtual bool MatchesDirPseudoClassForDirAutoAttribute( + TextDirection direction) const { + return false; + } + AtomicString ComputeInheritedLanguage() const; Locale& GetLocale() const;
diff --git a/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc b/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc index ac21aee..a8c0df80 100644 --- a/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc +++ b/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc
@@ -274,7 +274,8 @@ "frame-ancestors 'none'"); mojom::blink::FetchAPIResponsePtr fetch_api_response = - internal_response->PopulateFetchAPIResponse(KURL()); + internal_response->PopulateFetchAPIResponse( + KURL("https://www.example.org")); auto& csp = fetch_api_response->parsed_headers->content_security_policy; EXPECT_EQ(csp.size(), 2U);
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc index c45df56..edc386b 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -1431,6 +1431,10 @@ auto policy = network::mojom::blink::ContentSecurityPolicy::New(); + policy->self_origin = + policy_->GetSelfSource() + ? policy_->GetSelfSource()->ExposeForNavigationalChecks() + : nullptr; policy->use_reporting_api = use_reporting_api_; policy->report_endpoints = report_endpoints_; policy->header = network::mojom::blink::ContentSecurityPolicyHeader::New(
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h index 40cb1dab2..f84f726 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -167,7 +167,6 @@ const base::Optional<WebImpression>& impression, WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> initiator_csp, - network::mojom::blink::CSPSourcePtr initiator_self_source, network::mojom::IPAddressSpace, mojo::PendingRemote<mojom::blink::NavigationInitiator>) = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc index 2541f527..c7caa0e 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -287,6 +287,7 @@ return {policy->header->type, policy->header->source, + ConvertToPublic(std::move(policy->self_origin)), std::move(raw_directives), std::move(directives), policy->upgrade_insecure_requests, @@ -627,7 +628,6 @@ const String& href_translate, const base::Optional<WebImpression>& impression, WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> initiator_csp, - network::mojom::blink::CSPSourcePtr initiator_self_source, network::mojom::IPAddressSpace initiator_address_space, mojo::PendingRemote<mojom::blink::NavigationInitiator> navigation_initiator) { @@ -657,10 +657,6 @@ navigation_info->initiator_csp.emplace_back( ConvertToPublic(std::move(csp_policy))); } - if (initiator_self_source) { - navigation_info->initiator_self_source = - ConvertToPublic(std::move(initiator_self_source)); - } navigation_info->initiator_address_space = initiator_address_space; navigation_info->navigation_initiator_remote = std::move(navigation_initiator);
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h index 02f98349..cb737778 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
@@ -125,7 +125,6 @@ const base::Optional<WebImpression>& impression, WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> initiator_csp, - network::mojom::blink::CSPSourcePtr initiator_self_source, network::mojom::IPAddressSpace, mojo::PendingRemote<mojom::blink::NavigationInitiator>) override; void DispatchWillSendSubmitEvent(HTMLFormElement*) override;
diff --git a/third_party/blink/renderer/core/frame/use_counter_helper_test.cc b/third_party/blink/renderer/core/frame/use_counter_helper_test.cc index 7a3f3c5..4604d2c 100644 --- a/third_party/blink/renderer/core/frame/use_counter_helper_test.cc +++ b/third_party/blink/renderer/core/frame/use_counter_helper_test.cc
@@ -179,6 +179,17 @@ EXPECT_FALSE(document.IsUseCounted(WebFeature::kCSSSelectorPseudoWhere)); } +TEST_F(UseCounterHelperTest, CSSSelectorPseudoDir) { + auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600)); + Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage()); + Document& document = dummy_page_holder->GetDocument(); + WebFeature feature = WebFeature::kCSSSelectorPseudoDir; + EXPECT_FALSE(document.IsUseCounted(feature)); + document.documentElement()->setInnerHTML( + "<style>:dir(ltr) { color: red; }</style>"); + EXPECT_TRUE(document.IsUseCounted(feature)); +} + TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageColumnIndefiniteWidth) { auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600)); Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index 47525bc..02a4c47 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -1216,13 +1216,31 @@ } } -void HTMLElement::CalculateAndAdjustDirectionality() { +bool HTMLElement::CalculateAndAdjustDirectionality() { TextDirection text_direction = Directionality(); const ComputedStyle* style = GetComputedStyle(); if (style && style->Direction() != text_direction) { SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create( style_change_reason::kWritingModeChange)); + return true; + } + return false; +} + +TextDirection HTMLElement::ComputeInheritedDirectionality() const { + const AtomicString& direction = FastGetAttribute(html_names::kDirAttr); + if (HasDirectionAuto()) { + return Directionality(); + } else if (EqualIgnoringASCIICase(direction, "ltr")) { + return TextDirection::kLtr; + } else if (EqualIgnoringASCIICase(direction, "rtl")) { + return TextDirection::kRtl; + } else { + auto* parent = + DynamicTo<HTMLElement>(FlatTreeTraversal::ParentElement(*this)); + return parent ? parent->ComputeInheritedDirectionality() + : TextDirection::kLtr; } } @@ -1237,7 +1255,13 @@ element_to_adjust = FlatTreeTraversal::ParentElement(*element_to_adjust)) { if (ElementAffectsDirectionality(element_to_adjust)) { - To<HTMLElement>(element_to_adjust)->CalculateAndAdjustDirectionality(); + if (To<HTMLElement>(element_to_adjust) + ->CalculateAndAdjustDirectionality() && + RuntimeEnabledFeatures::CSSPseudoDirEnabled()) { + SetNeedsStyleRecalc(kLocalStyleChange, + StyleChangeReasonForTracing::Create( + style_change_reason::kPseudoClass)); + } return; } } @@ -1583,6 +1607,13 @@ if (EqualIgnoringASCIICase(params.new_value, "auto")) CalculateAndAdjustDirectionality(); + + if (RuntimeEnabledFeatures::CSSPseudoDirEnabled()) { + SetNeedsStyleRecalc( + kSubtreeStyleChange, + StyleChangeReasonForTracing::Create(style_change_reason::kPseudoClass)); + PseudoStateChanged(CSSSelector::kPseudoDir); + } } void HTMLElement::OnFormAttrChanged(const AttributeModificationParams& params) {
diff --git a/third_party/blink/renderer/core/html/html_element.h b/third_party/blink/renderer/core/html/html_element.h index 67e9e66..58e01d96 100644 --- a/third_party/blink/renderer/core/html/html_element.h +++ b/third_party/blink/renderer/core/html/html_element.h
@@ -153,6 +153,8 @@ virtual FormAssociated* ToFormAssociatedOrNull() { return nullptr; } bool IsFormAssociatedCustomElement() const; + TextDirection ComputeInheritedDirectionality() const; + protected: enum AllowPercentage { kDontAllowPercentageValues, kAllowPercentageValues }; enum AllowZero { kDontAllowZeroValues, kAllowZeroValues }; @@ -185,7 +187,7 @@ unsigned ParseBorderWidthAttribute(const AtomicString&) const; void ChildrenChanged(const ChildrenChange&) override; - void CalculateAndAdjustDirectionality(); + bool CalculateAndAdjustDirectionality(); InsertionNotificationRequest InsertedInto(ContainerNode&) override; void RemovedFrom(ContainerNode& insertion_point) override;
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc index 23188bc..cc54e54d 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -409,8 +409,14 @@ String fake_header = "HTTP/1.1 200 OK\nContent-Security-Policy: " + RequiredCsp(); + // ParseHeaders needs a url to resolve report endpoints and for matching the + // keyword 'self'. However, the csp attribute does not allow report + // endpoints. Moreover, in the csp attribute, 'self' should not match the + // owner's url, but rather the frame src url. This is taken care by the + // Content-Security-Policy Embedded Enforcement algorithm, implemented in the + // AncestorThrottle. That's why we pass an empty url here. network::mojom::blink::ParsedHeadersPtr parsed_headers = - ParseHeaders(fake_header, GetDocument().Url()); + ParseHeaders(fake_header, KURL()); DCHECK_LE(parsed_headers->content_security_policy.size(), 1u);
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc index 26d7b21..2a6bc46 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -299,6 +299,7 @@ DEFINE_STRING_MAPPING(PseudoEnabled) DEFINE_STRING_MAPPING(PseudoFullPageMedia) DEFINE_STRING_MAPPING(PseudoDefault) + DEFINE_STRING_MAPPING(PseudoDir) DEFINE_STRING_MAPPING(PseudoDisabled) DEFINE_STRING_MAPPING(PseudoOptional) DEFINE_STRING_MAPPING(PseudoPlaceholderShown)
diff --git a/third_party/blink/renderer/core/loader/empty_clients.cc b/third_party/blink/renderer/core/loader/empty_clients.cc index ea24fab..4124bc72 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.cc +++ b/third_party/blink/renderer/core/loader/empty_clients.cc
@@ -105,7 +105,6 @@ const String&, const base::Optional<WebImpression>&, WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> initiator_csp, - network::mojom::blink::CSPSourcePtr initiator_csp_self, network::mojom::IPAddressSpace, mojo::PendingRemote<mojom::blink::NavigationInitiator>) {}
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h index 0e07fb9..871023f 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.h +++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -274,7 +274,6 @@ const base::Optional<WebImpression>&, WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> initiator_csp, - network::mojom::blink::CSPSourcePtr initiator_self_source, network::mojom::IPAddressSpace, mojo::PendingRemote<mojom::blink::NavigationInitiator>) override;
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 4bfab0f..ab66bd3 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -727,19 +727,11 @@ mojo::PendingRemote<mojom::blink::NavigationInitiator> navigation_initiator; WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> initiator_csp; - network::mojom::blink::CSPSourcePtr initiator_self_source; if (origin_window && origin_window->GetContentSecurityPolicy() ->ExperimentalFeaturesEnabled()) { ContentSecurityPolicy* origin_window_csp = origin_window->GetContentSecurityPolicy(); - CSPSource* origin_window_csp_self_source = - origin_window_csp->GetSelfSource(); - initiator_csp = origin_window_csp->ExposeForNavigationalChecks(); - if (origin_window_csp_self_source) { - initiator_self_source = - origin_window_csp_self_source->ExposeForNavigationalChecks(); - } NavigationInitiatorImpl::From(*origin_window) .BindReceiver(navigation_initiator.InitWithNewPipeAndPassReceiver()); } @@ -839,8 +831,7 @@ request.GetTriggeringEventInfo(), request.Form(), should_check_main_world_csp, request.GetBlobURLToken(), request.GetInputStartTime(), request.HrefTranslate().GetString(), - request.Impression(), std::move(initiator_csp), - std::move(initiator_self_source), initiator_address_space, + request.Impression(), std::move(initiator_csp), initiator_address_space, std::move(navigation_initiator)); }
diff --git a/third_party/blink/renderer/core/streams/miscellaneous_operations.cc b/third_party/blink/renderer/core/streams/miscellaneous_operations.cc index ffaeaa96..eb843c56 100644 --- a/third_party/blink/renderer/core/streams/miscellaneous_operations.cc +++ b/third_party/blink/renderer/core/streams/miscellaneous_operations.cc
@@ -196,6 +196,48 @@ TraceWrapperV8Reference<v8::Value> extra_arg_; }; +class JavaScriptByteStreamStartAlgorithm : public StreamStartAlgorithm { + public: + JavaScriptByteStreamStartAlgorithm(v8::Isolate* isolate, + v8::Local<v8::Function> method, + v8::Local<v8::Object> recv, + v8::Local<v8::Value> controller) + : recv_(isolate, recv), + method_(isolate, method), + controller_(isolate, controller) {} + + v8::MaybeLocal<v8::Promise> Run(ScriptState* script_state, + ExceptionState& exception_state) override { + auto* isolate = script_state->GetIsolate(); + + auto value_maybe = + Call1(script_state, method_.NewLocal(isolate), recv_.NewLocal(isolate), + controller_.NewLocal(isolate), exception_state); + if (exception_state.HadException()) { + return v8::MaybeLocal<v8::Promise>(); + } + + v8::Local<v8::Value> value; + if (!value_maybe.ToLocal(&value)) { + exception_state.ThrowTypeError("internal error"); + return v8::MaybeLocal<v8::Promise>(); + } + return PromiseResolve(script_state, value); + } + + void Trace(Visitor* visitor) const override { + visitor->Trace(recv_); + visitor->Trace(method_); + visitor->Trace(controller_); + StreamStartAlgorithm::Trace(visitor); + } + + private: + TraceWrapperV8Reference<v8::Object> recv_; + TraceWrapperV8Reference<v8::Function> method_; + TraceWrapperV8Reference<v8::Value> controller_; +}; + class JavaScriptStreamStartAlgorithm : public StreamStartAlgorithm { public: JavaScriptStreamStartAlgorithm(v8::Isolate* isolate, @@ -343,10 +385,24 @@ controller); } +CORE_EXPORT StreamStartAlgorithm* CreateByteStreamStartAlgorithm( + ScriptState* script_state, + v8::Local<v8::Object> underlying_object, + v8::Local<v8::Value> method, + v8::Local<v8::Value> controller) { + return MakeGarbageCollected<JavaScriptByteStreamStartAlgorithm>( + script_state->GetIsolate(), method.As<v8::Function>(), underlying_object, + controller); +} + CORE_EXPORT StreamStartAlgorithm* CreateTrivialStartAlgorithm() { return MakeGarbageCollected<TrivialStartAlgorithm>(); } +CORE_EXPORT StreamAlgorithm* CreateTrivialStreamAlgorithm() { + return MakeGarbageCollected<TrivialStreamAlgorithm>(); +} + CORE_EXPORT v8::MaybeLocal<v8::Value> CallOrNoop1( ScriptState* script_state, v8::Local<v8::Object> object, @@ -381,6 +437,21 @@ return result; } +CORE_EXPORT v8::MaybeLocal<v8::Value> Call1(ScriptState* script_state, + v8::Local<v8::Function> method, + v8::Local<v8::Object> object, + v8::Local<v8::Value> arg0, + ExceptionState& exception_state) { + v8::TryCatch try_catch(script_state->GetIsolate()); + v8::MaybeLocal<v8::Value> result = + method->Call(script_state->GetContext(), object, 1, &arg0); + if (result.IsEmpty()) { + exception_state.RethrowV8Exception(try_catch.Exception()); + return v8::MaybeLocal<v8::Value>(); + } + return result; +} + CORE_EXPORT v8::Local<v8::Promise> PromiseCall(ScriptState* script_state, v8::Local<v8::Function> method, v8::Local<v8::Object> recv, @@ -562,4 +633,8 @@ exception_state); } +bool StrategyUnpacker::IsSizeUndefined() const { + return size_->IsUndefined(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/miscellaneous_operations.h b/third_party/blink/renderer/core/streams/miscellaneous_operations.h index 2a58874..70dacef 100644 --- a/third_party/blink/renderer/core/streams/miscellaneous_operations.h +++ b/third_party/blink/renderer/core/streams/miscellaneous_operations.h
@@ -68,10 +68,22 @@ const char* method_name_for_error, v8::Local<v8::Value> controller); +// Create a StreamStartAlgorithm from the "start" method on |underlying_object| +// for readable byte streams. +CORE_EXPORT StreamStartAlgorithm* CreateByteStreamStartAlgorithm( + ScriptState*, + v8::Local<v8::Object> underlying_object, + v8::Local<v8::Value> method, + v8::Local<v8::Value> controller); + // Returns a startAlgorithm that always returns a promise resolved with // undefined. CORE_EXPORT StreamStartAlgorithm* CreateTrivialStartAlgorithm(); +// Returns a streamAlgorithm that always returns a promise resolved with +// undefined. +CORE_EXPORT StreamAlgorithm* CreateTrivialStreamAlgorithm(); + // Used in place of InvokeOrNoop in spec. Always takes 1 argument. // https://streams.spec.whatwg.org/#invoke-or-noop CORE_EXPORT v8::MaybeLocal<v8::Value> CallOrNoop1(ScriptState*, @@ -81,6 +93,15 @@ v8::Local<v8::Value> arg0, ExceptionState&); +// Used in JavaScriptByteStreamStartAlgoirthm to call the method. +// This is a variation of the CallOrNoop1 method where it is given the method +// function already. +CORE_EXPORT v8::MaybeLocal<v8::Value> Call1(ScriptState*, + v8::Local<v8::Function> method, + v8::Local<v8::Object> object, + v8::Local<v8::Value> arg0, + ExceptionState&); + // https://streams.spec.whatwg.org/#promise-call // "PromiseCall(F, V, args)" // "F" is called |method| here @@ -153,6 +174,8 @@ int default_value, ExceptionState&) const; + bool IsSizeUndefined() const; + private: v8::Local<v8::Value> size_; v8::Local<v8::Value> high_water_mark_;
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc index ec76fac..f4f8b6b 100644 --- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc +++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc
@@ -4,51 +4,1306 @@ #include "third_party/blink/renderer/core/streams/readable_byte_stream_controller.h" +#include "base/numerics/checked_math.h" +#include "base/numerics/clamped_math.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h" +#include "third_party/blink/renderer/core/streams/miscellaneous_operations.h" +#include "third_party/blink/renderer/core/streams/promise_handler.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/streams/readable_stream_byob_request.h" +#include "third_party/blink/renderer/core/streams/stream_algorithms.h" #include "third_party/blink/renderer/core/streams/stream_promise_resolver.h" +#include "third_party/blink/renderer/core/streams/underlying_source.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/v8_binding.h" +#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" +#include "v8/include/v8.h" namespace blink { -ReadableStreamBYOBRequest* ReadableByteStreamController::byobRequest( - ExceptionState& exception_state) const { - ThrowUnimplemented(exception_state); - return nullptr; +namespace { + +template <typename DOMType> +DOMArrayBufferView* CreateAsArrayBufferView(DOMArrayBuffer* buffer, + size_t byte_offset, + size_t length) { + return DOMType::Create(buffer, byte_offset, length); } -base::Optional<double> ReadableByteStreamController::desiredSize( - ExceptionState& exception_state) const { - ThrowUnimplemented(exception_state); - return base::nullopt; +} // namespace + +ReadableByteStreamController::QueueEntry::QueueEntry(DOMArrayBuffer* buffer, + size_t byte_offset, + size_t byte_length) + : buffer(buffer), byte_offset(byte_offset), byte_length(byte_length) {} + +void ReadableByteStreamController::QueueEntry::Trace(Visitor* visitor) const { + visitor->Trace(buffer); +} + +ReadableByteStreamController::PullIntoDescriptor::PullIntoDescriptor( + DOMArrayBuffer* buffer, + size_t byte_offset, + size_t byte_length, + size_t bytes_filled, + size_t element_size, + ViewConstructorType view_constructor, + ReaderType reader_type) + : buffer(buffer), + byte_offset(byte_offset), + byte_length(byte_length), + bytes_filled(bytes_filled), + element_size(element_size), + view_constructor(view_constructor), + reader_type(reader_type) {} + +void ReadableByteStreamController::PullIntoDescriptor::Trace( + Visitor* visitor) const { + visitor->Trace(buffer); +} + +// This constructor is used internally; it is not reachable from Javascript. +ReadableByteStreamController::ReadableByteStreamController() + : queue_total_size_(queue_.size()) {} + +ReadableStreamBYOBRequest* ReadableByteStreamController::byobRequest() { + // https://streams.spec.whatwg.org/#rbs-controller-byob-request + // 1. If this.[[byobRequest]] is null and this.[[pendingPullIntos]] is not + // empty, + if (!byob_request_ && !pending_pull_intos_.IsEmpty()) { + // a. Let firstDescriptor be this.[[pendingPullIntos]][0]. + const PullIntoDescriptor* first_descriptor = pending_pull_intos_[0]; + // b. Let view be ! Construct(%Uint8Array%, « firstDescriptor’s buffer, + // firstDescriptor’s byte offset + firstDescriptor’s bytes filled, + // firstDescriptor’s byte length − firstDescriptor’s bytes filled »). + DOMUint8Array* const view = DOMUint8Array::Create( + first_descriptor->buffer, + first_descriptor->byte_offset + first_descriptor->bytes_filled, + first_descriptor->byte_length - first_descriptor->bytes_filled); + // c. Let byobRequest be a new ReadableStreamBYOBRequest. + // d. Set byobRequest.[[controller]] to this. + // e. Set byobRequest.[[view]] to view. + // f. Set this.[[byobRequest]] to byobRequest. + byob_request_ = MakeGarbageCollected<ReadableStreamBYOBRequest>( + this, NotShared<DOMUint8Array>(view)); + } + // 2. Return this.[[byobRequest]]. + return byob_request_; +} + +base::Optional<double> ReadableByteStreamController::desiredSize() { + // https://streams.spec.whatwg.org/#rbs-controller-desired-size + // 1. Return ! ReadableByteStreamControllerGetDesiredSize(this). + return GetDesiredSize(this); +} + +base::Optional<double> ReadableByteStreamController::GetDesiredSize( + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-get-desired-size + // 1. Let state be controller.[[stream]].[[state]]. + switch (controller->controlled_readable_stream_->state_) { + // 2. If state is "errored", return null. + case ReadableStream::kErrored: + return base::nullopt; + + // 3. If state is "closed", return 0. + case ReadableStream::kClosed: + return 0.0; + + case ReadableStream::kReadable: + // 4. Return controller.[[strategyHWM]]] - controller.[[queueTotalSize]]. + return controller->strategy_high_water_mark_ - + controller->queue_total_size_; + } } void ReadableByteStreamController::close(ScriptState* script_state, ExceptionState& exception_state) { - ThrowUnimplemented(exception_state); - return; + // https://streams.spec.whatwg.org/#rbs-controller-close + // 1. If this.[[closeRequested]] is true, throw a TypeError exception. + if (close_requested_) { + exception_state.ThrowTypeError( + "Cannot close a readable stream that has already been requested " + "to be closed"); + return; + } + + // 2. If this.[[stream]].[[state]] is not "readable", throw a TypeError + // exception. + if (controlled_readable_stream_->state_ != ReadableStream::kReadable) { + exception_state.ThrowTypeError( + "Cannot close a readable stream that is not readable"); + return; + } + + // 3. Perform ? ReadableByteStreamControllerClose(this). + Close(script_state, this, exception_state); } void ReadableByteStreamController::enqueue(ScriptState* script_state, NotShared<DOMArrayBufferView> chunk, ExceptionState& exception_state) { - ThrowUnimplemented(exception_state); - return; + // https://streams.spec.whatwg.org/#rbs-controller-enqueue + // 1. If chunk.[[ByteLength]] is 0, throw a TypeError exception. + if (chunk->byteLength() == 0) { + exception_state.ThrowTypeError("chunk is empty"); + return; + } + + // 2. If chunk.[[ViewedArrayBuffer]].[[ArrayBufferByteLength]] is 0, throw a + // TypeError exception. + if (chunk->buffer()->ByteLength() == 0) { + exception_state.ThrowTypeError("chunk's buffer is empty"); + return; + } + + // 3. If this.[[closeRequested]] is true, throw a TypeError exception. + if (close_requested_) { + exception_state.ThrowTypeError("close requested already"); + return; + } + + // 4. If this.[[stream]].[[state]] is not "readable", throw a TypeError + // exception. + if (controlled_readable_stream_->state_ != ReadableStream::kReadable) { + exception_state.ThrowTypeError("stream is not readable"); + return; + } + + // 5. Return ! ReadableByteStreamControllerEnqueue(this, chunk). + Enqueue(script_state, this, chunk, exception_state); +} + +void ReadableByteStreamController::error(ScriptState* script_state) { + error(script_state, ScriptValue(script_state->GetIsolate(), + v8::Undefined(script_state->GetIsolate()))); } void ReadableByteStreamController::error(ScriptState* script_state, - ExceptionState& exception_state) { - ThrowUnimplemented(exception_state); - return; + const ScriptValue& e) { + // https://streams.spec.whatwg.org/#rbs-controller-error + // 1. Perform ! ReadableByteStreamControllerError(this, e). + Error(script_state, this, e.V8Value()); } -void ReadableByteStreamController::error(ScriptState* script_state, - ScriptValue e, - ExceptionState& exception_state) { - ThrowUnimplemented(exception_state); - return; +void ReadableByteStreamController::Close( + ScriptState* script_state, + ReadableByteStreamController* controller, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-close + // 1. Let stream be controller.[[stream]]. + ReadableStream* const stream = controller->controlled_readable_stream_; + + // 2. If controller.[[closeRequested]] is true or stream.[[state]] is not + // "readable", return. + if (controller->close_requested_ || + stream->state_ != ReadableStream::kReadable) { + return; + } + + // 3. If controller.[[queueTotalSize]] > 0, + if (controller->queue_total_size_ > 0) { + // a. Set controller.[[closeRequested]] to true. + controller->close_requested_ = true; + // b. Return. + return; + } + + // 4. If controller.[[pendingPullIntos]] is not empty, + if (!controller->pending_pull_intos_.IsEmpty()) { + // a. Let firstPendingPullInto be controller.[[pendingPullIntos]][0]. + const PullIntoDescriptor* first_pending_pull_into = + controller->pending_pull_intos_[0]; + // b. If firstPendingPullInto’s bytes filled > 0, + if (first_pending_pull_into->bytes_filled > 0) { + // i. Let e be a new TypeError exception. + exception_state.ThrowTypeError("Cannot close while responding"); + v8::Local<v8::Value> e = exception_state.GetException(); + // ii. Perform ! ReadableByteStreamControllerError(controller, e). + Error(script_state, controller, e); + // iii. Throw e. + return; + } + } + + // 5. Perform ! ReadableByteStreamControllerClearAlgorithms(controller). + ClearAlgorithms(controller); + + // 6. Perform ! ReadableStreamClose(stream). + ReadableStream::Close(script_state, stream); +} + +void ReadableByteStreamController::Error( + ScriptState* script_state, + ReadableByteStreamController* controller, + v8::Local<v8::Value> e) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-error + // 1. Let stream by controller.[[stream]]. + ReadableStream* const stream = controller->controlled_readable_stream_; + + // 2. If stream.[[state]] is not "readable", return. + if (stream->state_ != ReadableStream::kReadable) { + return; + } + + // 3. Perform ! ReadableByteStreamControllerClearPendingPullIntos(controller). + ClearPendingPullIntos(controller); + + // 4. Perform ! ResetQueue(controller). + ResetQueue(controller); + + // 5. Perform ! ReadableByteStreamControllerClearAlgorithms(controller). + ClearAlgorithms(controller); + + // 6. Perform ! ReadableStreamError(stream, e). + ReadableStream::Error(script_state, stream, e); +} + +void ReadableByteStreamController::Enqueue( + ScriptState* script_state, + ReadableByteStreamController* controller, + NotShared<DOMArrayBufferView> chunk, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-enqueue + // 1. Let stream be controller.[[stream]].i + ReadableStream* const stream = controller->controlled_readable_stream_; + + // 2. If controller.[[closeRequested]] is true or stream.[[state]] is not + // "readable", return. + if (controller->close_requested_ || + stream->state_ != ReadableStream::kReadable) { + return; + } + + // 3. Let buffer be chunk.[[ViewedArrayBuffer]]. + DOMArrayBuffer* const buffer = chunk->buffer(); + + // 4. Let byteOffset be chunk.[[ByteOffset]]. + const size_t byte_offset = chunk->byteOffset(); + + // 5. Let byteLength be chunk.[[ByteLength]]. + const size_t byte_length = chunk->byteLength(); + + // 6. Let transferredBuffer be ! TransferArrayBuffer(buffer). + DOMArrayBuffer* const transferred_buffer = + TransferArrayBuffer(script_state, buffer, exception_state); + + // 7. If ! ReadableStreamHasDefaultReader(stream) is true + if (ReadableStream::HasDefaultReader(stream)) { + // a. If ! ReadableStreamGetNumReadRequests(stream) is 0, + if (ReadableStream::GetNumReadRequests(stream) == 0) { + // i. Perform ! + // ReadableByteStreamControllerEnqueueChunkToQueue(controller, + // transferredBuffer, byteOffset, byteLength). + EnqueueChunkToQueue(controller, transferred_buffer, byte_offset, + byte_length); + } else { + // b. Otherwise, + // i. Assert: controller.[[queue]] is empty. + DCHECK(controller->queue_.IsEmpty()); + // ii. Let transferredView be ! Construct(%Uint8Array%, « + // transferredBuffer, byteOffset, byteLength »). + v8::Local<v8::Value> const transferred_view = v8::Uint8Array::New( + ToV8(transferred_buffer, script_state).As<v8::ArrayBuffer>(), + byte_offset, byte_length); + // iii. Perform ! ReadableStreamFulfillReadRequest(stream, + // transferredView, false). + ReadableStream::FulfillReadRequest(script_state, stream, transferred_view, + false); + } + } + + // 8. Otherwise, if ! ReadableStreamHasBYOBReader(stream) is true, + else if (ReadableStream::HasBYOBReader(stream)) { + // a. Perform ! + // ReadableByteStreamControllerEnqueueChunkToQueue(controller, + // transferredBuffer, byteOffset, byteLength). + EnqueueChunkToQueue(controller, transferred_buffer, byte_offset, + byte_length); + // b. Perform ! + // ReadableByteStreamControllerProcessPullIntoDescriptorsUsing + // Queue(controller). + ProcessPullIntoDescriptorsUsingQueue(script_state, controller); + } else { + // 9. Otherwise, + // a. Assert: ! IsReadableStreamLocked(stream) is false. + DCHECK(!ReadableStream::IsLocked(stream)); + // b. Perform ! + // ReadableByteStreamControllerEnqueueChunkToQueue(controller, + // transferredBuffer, byteOffset, byteLength). + EnqueueChunkToQueue(controller, transferred_buffer, byte_offset, + byte_length); + } + + // 10. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller). + CallPullIfNeeded(script_state, controller); +} + +void ReadableByteStreamController::EnqueueChunkToQueue( + ReadableByteStreamController* controller, + DOMArrayBuffer* buffer, + size_t byte_offset, + size_t byte_length) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-enqueue-chunk-to-queue + // 1. Append a new readable byte stream queue entry with buffer buffer, byte + // offset byteOffset, and byte length byteLength to controller.[[queue]]. + QueueEntry* const entry = + MakeGarbageCollected<QueueEntry>(buffer, byte_offset, byte_length); + controller->queue_.push_back(entry); + // 2. Set controller.[[queueTotalSize]] to controller.[[queueTotalSize]] + + // byteLength. + controller->queue_total_size_ += byte_length; +} + +void ReadableByteStreamController::ProcessPullIntoDescriptorsUsingQueue( + ScriptState* script_state, + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-process-pull-into-descriptors-using-queue + // 1. Assert: controller.[[closeRequested]] is false. + DCHECK(!controller->close_requested_); + // 2. While controller.[[pendingPullIntos]] is not empty, + while (!controller->pending_pull_intos_.IsEmpty()) { + // a. If controller.[[queueTotalSize]] is 0, return. + if (controller->queue_total_size_ == 0) { + return; + } + // b. Let pullIntoDescriptor be controller.[[pendingPullIntos]][0]. + PullIntoDescriptor* const pull_into_descriptor = + controller->pending_pull_intos_[0]; + // c. If ! ReadableByteStreamControllerFillPullIntoDescriptorFromQueue( + // controller, pullIntoDescriptor) is true, + if (FillPullIntoDescriptorFromQueue(controller, pull_into_descriptor)) { + // i. Perform ! + // ReadableByteStreamControllerShiftPendingPullInto(controller). + ShiftPendingPullInto(controller); + // ii. Perform ! ReadableByteStreamControllerCommitPullIntoDescriptor( + // controller.[[stream]], pullIntoDescriptor). + CommitPullIntoDescriptor(script_state, + controller->controlled_readable_stream_, + pull_into_descriptor); + } + } +} + +void ReadableByteStreamController::CallPullIfNeeded( + ScriptState* script_state, + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-call-pull-if-needed + // 1. Let shouldPull be ! + // ReadableByteStreamControllerShouldCallPull(controller). + const bool should_pull = ShouldCallPull(controller); + // 2. If shouldPull is false, return. + if (!should_pull) { + return; + } + // 3. If controller.[[pulling]] is true, + if (controller->pulling_) { + // a. Set controller.[[pullAgain]] to true. + controller->pull_again_ = true; + // b. Return. + return; + } + // 4. Assert: controller.[[pullAgain]] is false. + DCHECK(!controller->pull_again_); + // 5. Set controller.[[pulling]] to true. + controller->pulling_ = true; + // 6. Let pullPromise be the result of performing + // controller.[[pullAlgorithm]]. + auto pull_promise = + controller->pull_algorithm_->Run(script_state, 0, nullptr); + + class ResolveFunction final : public PromiseHandler { + public: + ResolveFunction(ScriptState* script_state, + ReadableByteStreamController* controller) + : PromiseHandler(script_state), controller_(controller) {} + + void CallWithLocal(v8::Local<v8::Value>) override { + // 7. Upon fulfillment of pullPromise, + // a. Set controller.[[pulling]] to false. + controller_->pulling_ = false; + // b. If controller.[[pullAgain]] is true, + if (controller_->pull_again_) { + // i. Set controller.[[pullAgain]] to false. + controller_->pull_again_ = false; + // ii. Perform ! + // ReadableByteStreamControllerCallPullIfNeeded(controller). + CallPullIfNeeded(GetScriptState(), controller_); + } + } + + void Trace(Visitor* visitor) const override { + visitor->Trace(controller_); + PromiseHandler::Trace(visitor); + } + + private: + const Member<ReadableByteStreamController> controller_; + }; + + class RejectFunction final : public PromiseHandler { + public: + RejectFunction(ScriptState* script_state, + ReadableByteStreamController* controller) + : PromiseHandler(script_state), controller_(controller) {} + + void CallWithLocal(v8::Local<v8::Value> e) override { + // 8. Upon rejection of pullPromise with reason e, + // a. Perform ! ReadableByteStreamControllerError(controller, e). + Error(GetScriptState(), controller_, e); + } + + void Trace(Visitor* visitor) const override { + visitor->Trace(controller_); + PromiseHandler::Trace(visitor); + } + + private: + const Member<ReadableByteStreamController> controller_; + }; + + StreamThenPromise( + script_state->GetContext(), pull_promise, + MakeGarbageCollected<ResolveFunction>(script_state, controller), + MakeGarbageCollected<RejectFunction>(script_state, controller)); +} + +ReadableByteStreamController::PullIntoDescriptor* +ReadableByteStreamController::ShiftPendingPullInto( + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-shift-pending-pull-into + // 1. Let descriptor be controller.[[pendingPullIntos]][0]. + PullIntoDescriptor* const descriptor = controller->pending_pull_intos_[0]; + // 2. Remove descriptor from controller.[[pendingPullIntos]]. + controller->pending_pull_intos_.pop_front(); + // 3. Perform ! ReadableByteStreamControllerInvalidateBYOBRequest(controller). + InvalidateBYOBRequest(controller); + // 4. Return descriptor. + return descriptor; +} + +bool ReadableByteStreamController::ShouldCallPull( + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-should-call-pull + // 1. Let stream be controller.[[stream]]. + ReadableStream* const stream = controller->controlled_readable_stream_; + // 2. If stream.[[state]] is not "readable", return false. + if (stream->state_ != ReadableStream::kReadable) { + return false; + } + // 3. If controller.[[closeRequested]] is true, return false. + if (controller->close_requested_) { + return false; + } + // 4. If controller.[[started]] is false, return false. + if (!controller->started_) { + return false; + } + // 5. If ! ReadableStreamHasDefaultReader(stream) is true and ! + // ReadableStreamGetNumReadRequests(stream) > 0, return true. + if (ReadableStream::HasDefaultReader(stream) && + ReadableStream::GetNumReadRequests(stream) > 0) { + return true; + } + // 6. If ! ReadableStreamHasBYOBReader(stream) is true and ! + // ReadableStreamGetNumReadIntoRequests(stream) > 0, return true. + if (ReadableStream::HasBYOBReader(stream) && + ReadableStream::GetNumReadIntoRequests(stream) > 0) { + return true; + } + // 7. Let desiredSize be ! + // ReadableByteStreamControllerGetDesiredSize(controller). + const base::Optional<double> desired_size = GetDesiredSize(controller); + // 8. Assert: desiredSize is not null. + DCHECK(desired_size); + // 9. If desiredSize > 0, return true. + if (*desired_size > 0) { + return true; + } + // 10. Return false. + return false; +} + +void ReadableByteStreamController::CommitPullIntoDescriptor( + ScriptState* script_state, + ReadableStream* stream, + PullIntoDescriptor* pull_into_descriptor) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-commit-pull-into-descriptor + // 1. Assert: stream.[[state]] is not "errored". + DCHECK_NE(stream->state_, ReadableStream::kErrored); + // 2. Let done be false. + bool done = false; + // 3. If stream.[[state]] is "closed", + if (stream->state_ == ReadableStream::kClosed) { + // a. Assert: pullIntoDescriptor’s bytes filled is 0. + DCHECK_EQ(pull_into_descriptor->bytes_filled, 0u); + // b. Set done to true. + done = true; + } + // 4. Let filledView be ! + // ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor). + auto* filled_view = ConvertPullIntoDescriptor(pull_into_descriptor); + // 5. If pullIntoDescriptor’s reader type is "default", + if (pull_into_descriptor->reader_type == ReaderType::kDefault) { + // a. Perform ! ReadableStreamFulfillReadRequest(stream, filledView, + // done). + ReadableStream::FulfillReadRequest(script_state, stream, + ToV8(filled_view, script_state), done); + } else { + // 6. Otherwise, + // a. Assert: pullIntoDescriptor’s reader type is "byob". + DCHECK_EQ(pull_into_descriptor->reader_type, ReaderType::kBYOB); + // b. Perform ! ReadableStreamFulfillReadIntoRequest(stream, filledView, + // done). + ReadableStream::FulfillReadIntoRequest(script_state, stream, filled_view, + done); + } +} + +DOMArrayBufferView* ReadableByteStreamController::ConvertPullIntoDescriptor( + PullIntoDescriptor* pull_into_descriptor) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-convert-pull-into-descriptor + // 1. Let bytesFilled be pullIntoDescriptor’s bytes filled. + const size_t bytes_filled = pull_into_descriptor->bytes_filled; + // 2. Let elementSize be pullIntoDescriptor’s element size. + const size_t element_size = pull_into_descriptor->element_size; + // 3. Assert: bytesFilled ≤ pullIntoDescriptor’s byte length. + DCHECK_LE(bytes_filled, pull_into_descriptor->byte_length); + // 4. Assert: bytesFilled mod elementSize is 0. + DCHECK_EQ(bytes_filled % element_size, 0u); + // 5. Return ! Construct(pullIntoDescriptor’s view constructor, « + // pullIntoDescriptor’s buffer, pullIntoDescriptor’s byte offset, bytesFilled + // ÷ elementSize »). + return pull_into_descriptor->view_constructor( + pull_into_descriptor->buffer, pull_into_descriptor->byte_offset, + (bytes_filled / element_size)); +} + +void ReadableByteStreamController::ClearPendingPullIntos( + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-clear-pending-pull-intos + // 1. Perform ! ReadableByteStreamControllerInvalidateBYOBRequest(controller). + InvalidateBYOBRequest(controller); + // 2. Set controller.[[pendingPullIntos]] to a new empty list. + controller->pending_pull_intos_.clear(); +} + +void ReadableByteStreamController::ClearAlgorithms( + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-clear-algorithms + // 1. Set controller.[[pullAlgorithm]] to undefined. + controller->pull_algorithm_ = nullptr; + + // 2. Set controller.[[cancelAlgorithm]] to undefined. + controller->cancel_algorithm_ = nullptr; +} + +void ReadableByteStreamController::InvalidateBYOBRequest( + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-invalidate-byob-request + // 1. If controller.[[byobRequest]] is null, return. + if (!controller->byob_request_) { + return; + } + // 2. Set controller.[[byobRequest]].[[controller]] to undefined. + controller->byob_request_->controller_ = nullptr; + // 3. Set controller.[[byobRequest]].[[view]] to null. + controller->byob_request_->view_ = NotShared<DOMArrayBufferView>(nullptr); + // 4. Set controller.[[byobRequest]] to null. + controller->byob_request_ = nullptr; +} + +void ReadableByteStreamController::SetUp( + ScriptState* script_state, + ReadableStream* stream, + ReadableByteStreamController* controller, + StreamStartAlgorithm* start_algorithm, + StreamAlgorithm* pull_algorithm, + StreamAlgorithm* cancel_algorithm, + double high_water_mark, + size_t auto_allocate_chunk_size, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#set-up-readable-byte-stream-controller + // 1. Assert: stream.[[controller]] is undefined. + DCHECK(!stream->readable_stream_controller_); + // 2. If autoAllocateChunkSize is not undefined, + if (auto_allocate_chunk_size) { + // a. Assert: ! IsInteger(autoAllocateChunkSize) is true. + // b. Assert: autoAllocateChunkSize is positive. + // Due to autoAllocateChunkSize having the [EnforceRange] attribute, it + // can never be negative. + DCHECK_GT(auto_allocate_chunk_size, 0u); + } + // 3. Set controller.[[stream]] to stream. + controller->controlled_readable_stream_ = stream; + // 4. Set controller.[[pullAgain]] and controller.[[pulling]] to false. + DCHECK(!controller->pull_again_); + DCHECK(!controller->pulling_); + // 5. Set controller.[[byobRequest]] to null. + DCHECK(!controller->byob_request_); + // 6. Perform ! ResetQueue(controller). + ResetQueue(controller); + // 7. Set controller.[[closeRequested]] and controller.[[started]] to false. + DCHECK(!controller->close_requested_); + DCHECK(!controller->started_); + // 8. Set controller.[[strategyHWM]] to highWaterMark. + controller->strategy_high_water_mark_ = high_water_mark; + // 9. Set controller.[[pullAlgorithm]] to pullAlgorithm. + controller->pull_algorithm_ = pull_algorithm; + // 10. Set controller.[[cancelAlgorithm]] to cancelAlgorithm. + controller->cancel_algorithm_ = cancel_algorithm; + // 11. Set controller.[[autoAllocateChunkSize]] to autoAllocateChunkSize. + controller->auto_allocate_chunk_size_ = auto_allocate_chunk_size; + // 12. Set controller.[[pendingPullIntos]] to a new empty list. + DCHECK(controller->pending_pull_intos_.IsEmpty()); + // 13. Set stream.[[controller]] to controller. + stream->readable_stream_controller_ = controller; + // 14. Let startResult be the result of performing startAlgorithm. + // 15. Let startPromise be a promise resolved with startResult. + // The conversion of startResult to a promise happens inside start_algorithm + // in this implementation. + v8::Local<v8::Promise> start_promise; + if (!start_algorithm->Run(script_state, exception_state) + .ToLocal(&start_promise)) { + if (!exception_state.HadException()) { + exception_state.ThrowException( + static_cast<int>(DOMExceptionCode::kInvalidStateError), + "start algorithm failed with no exception thrown"); + } + return; + } + DCHECK(!exception_state.HadException()); + + class ResolveFunction final : public PromiseHandler { + public: + ResolveFunction(ScriptState* script_state, + ReadableByteStreamController* controller) + : PromiseHandler(script_state), controller_(controller) {} + + void CallWithLocal(v8::Local<v8::Value>) override { + // 16. Upon fulfillment of startPromise, + // a. Set controller.[[started]] to true. + controller_->started_ = true; + // b. Assert: controller.[[pulling]] is false. + DCHECK(!controller_->pulling_); + // c. Assert: controller.[[pullAgain]] is false. + DCHECK(!controller_->pull_again_); + // d. Perform ! + // ReadableByteStreamControllerCallPullIfNeeded(controller). + CallPullIfNeeded(GetScriptState(), controller_); + } + + void Trace(Visitor* visitor) const override { + visitor->Trace(controller_); + PromiseHandler::Trace(visitor); + } + + private: + const Member<ReadableByteStreamController> controller_; + }; + + class RejectFunction final : public PromiseHandler { + public: + RejectFunction(ScriptState* script_state, + ReadableByteStreamController* controller) + : PromiseHandler(script_state), controller_(controller) {} + + void CallWithLocal(v8::Local<v8::Value> r) override { + // 17. Upon rejection of startPromise with reason r, + // a. Perform ! ReadableByteStreamControllerError(controller, r). + Error(GetScriptState(), controller_, r); + } + + void Trace(Visitor* visitor) const override { + visitor->Trace(controller_); + PromiseHandler::Trace(visitor); + } + + private: + const Member<ReadableByteStreamController> controller_; + }; + + StreamThenPromise( + script_state->GetContext(), start_promise, + MakeGarbageCollected<ResolveFunction>(script_state, controller), + MakeGarbageCollected<RejectFunction>(script_state, controller)); +} + +void ReadableByteStreamController::SetUpFromUnderlyingSource( + ScriptState* script_state, + ReadableStream* stream, + v8::Local<v8::Object> underlying_source, + UnderlyingSource* underlying_source_dict, + double high_water_mark, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#set-up-readable-byte-stream-controller-from-underlying-source + // 1. Let controller be a new ReadableByteStreamController. + ReadableByteStreamController* controller = + MakeGarbageCollected<ReadableByteStreamController>(); + // 2. Let startAlgorithm be an algorithm that returns undefined. + StreamStartAlgorithm* start_algorithm = CreateTrivialStartAlgorithm(); + // 3. Let pullAlgorithm be an algorithm that returns a promise resolved with + // undefined. + StreamAlgorithm* pull_algorithm = CreateTrivialStreamAlgorithm(); + // 4. Let cancelAlgorithm be an algorithm that returns a promise resolved with + // undefined. + StreamAlgorithm* cancel_algorithm = CreateTrivialStreamAlgorithm(); + + const auto controller_value = ToV8(controller, script_state); + // 5. If underlyingSourceDict["start"] exists, then set startAlgorithm to an + // algorithm which returns the result of invoking + // underlyingSourceDict["start"] with argument list « controller » and + // callback this value underlyingSource. + if (underlying_source_dict->hasStart()) { + start_algorithm = CreateByteStreamStartAlgorithm( + script_state, underlying_source, + ToV8(underlying_source_dict->start(), script_state), controller_value); + } + // 6. If underlyingSourceDict["pull"] exists, then set pullAlgorithm to an + // algorithm which returns the result of invoking underlyingSourceDict["pull"] + // with argument list « controller » and callback this value underlyingSource. + if (underlying_source_dict->hasPull()) { + pull_algorithm = CreateAlgorithmFromResolvedMethod( + script_state, underlying_source, + ToV8(underlying_source_dict->pull(), script_state), controller_value); + } + // 7. If underlyingSourceDict["cancel"] exists, then set cancelAlgorithm to an + // algorithm which takes an argument reason and returns the result of invoking + // underlyingSourceDict["cancel"] with argument list « reason » and callback + // this value underlyingSource. + if (underlying_source_dict->hasCancel()) { + cancel_algorithm = CreateAlgorithmFromResolvedMethod( + script_state, underlying_source, + ToV8(underlying_source_dict->cancel(), script_state), controller_value); + } + // 8. Let autoAllocateChunkSize be + // underlyingSourceDict["autoAllocateChunkSize"], if it exists, or undefined + // otherwise. + size_t auto_allocate_chunk_size = + underlying_source_dict->hasAutoAllocateChunkSize() + ? static_cast<size_t>(underlying_source_dict->autoAllocateChunkSize()) + : 0u; + // 9. If autoAllocateChunkSize is 0, then throw a TypeError exception. + if (underlying_source_dict->hasAutoAllocateChunkSize() && + auto_allocate_chunk_size == 0) { + exception_state.ThrowTypeError("autoAllocateChunkSize cannot be 0"); + return; + } + // 10. Perform ? SetUpReadableByteStreamController(stream, controller, + // startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, + // autoAllocateChunkSize). + SetUp(script_state, stream, controller, start_algorithm, pull_algorithm, + cancel_algorithm, high_water_mark, auto_allocate_chunk_size, + exception_state); +} + +void ReadableByteStreamController::FillHeadPullIntoDescriptor( + ReadableByteStreamController* controller, + size_t size, + PullIntoDescriptor* pull_into_descriptor) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-fill-head-pull-into-descriptor + // 1. Assert: either controller.[[pendingPullIntos]] is empty, or + // controller.[[pendingPullIntos]][0] is pullIntoDescriptor. + DCHECK(controller->pending_pull_intos_.IsEmpty() || + controller->pending_pull_intos_[0] == pull_into_descriptor); + // 2. Perform ! ReadableByteStreamControllerInvalidateBYOBRequest(controller). + InvalidateBYOBRequest(controller); + // 3. Set pullIntoDescriptor’s bytes filled to bytes filled + size. + pull_into_descriptor->bytes_filled = + base::CheckAdd(pull_into_descriptor->bytes_filled, size).ValueOrDie(); +} + +bool ReadableByteStreamController::FillPullIntoDescriptorFromQueue( + ReadableByteStreamController* controller, + PullIntoDescriptor* pull_into_descriptor) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-fill-pull-into-descriptor-from-queue + // 1. Let elementSize be pullIntoDescriptor.[[elementSize]]. + const size_t element_size = pull_into_descriptor->element_size; + // 2. Let currentAlignedBytes be pullIntoDescriptor's bytes filled − + // (pullIntoDescriptor's bytes filled mod elementSize). + const size_t current_aligned_bytes = + pull_into_descriptor->bytes_filled - + (pull_into_descriptor->bytes_filled % element_size); + // 3. Let maxBytesToCopy be min(controller.[[queueTotalSize]], + // pullIntoDescriptor’s byte length − pullIntoDescriptor’s bytes filled). + // The subtraction will not underflow because bytes length will always be more + // than or equal to bytes filled. + const size_t max_bytes_to_copy = std::min( + static_cast<size_t>(controller->queue_total_size_), + pull_into_descriptor->byte_length - pull_into_descriptor->bytes_filled); + // 4. Let maxBytesFilled be pullIntoDescriptor’s bytes filled + + // maxBytesToCopy. + // This addition will not overflow because maxBytesToCopy can be at most + // queue_total_size_. Both bytes_filled and queue_total_size_ refer to + // actually allocated memory, so together they cannot exceed size_t. + const size_t max_bytes_filled = + pull_into_descriptor->bytes_filled + max_bytes_to_copy; + // 5. Let maxAlignedBytes be maxBytesFilled − (maxBytesFilled mod + // elementSize). + // This subtraction will not underflow because the modulus operator is + // guaranteed to return a value less than or equal to the first argument. + const size_t max_aligned_bytes = + max_bytes_filled - (max_bytes_filled % element_size); + // 6. Let totalBytesToCopyRemaining be maxBytesToCopy. + size_t total_bytes_to_copy_remaining = max_bytes_to_copy; + // 7. Let ready be false; + bool ready = false; + // 8. If maxAlignedBytes > currentAlignedBytes, + if (max_aligned_bytes > current_aligned_bytes) { + // a. Set totalBytesToCopyRemaining to maxAlignedBytes − + // pullIntoDescriptor’s bytes filled. + total_bytes_to_copy_remaining = + base::CheckSub(max_aligned_bytes, pull_into_descriptor->bytes_filled) + .ValueOrDie(); + // b. Set ready to true. + ready = true; + } + // 9. Let queue be controller.[[queue]]. + HeapDeque<Member<QueueEntry>>& queue = controller->queue_; + // 10. While totalBytesToCopyRemaining > 0, + while (total_bytes_to_copy_remaining > 0) { + // a. Let headOfQueue be queue[0]. + QueueEntry* head_of_queue = queue[0]; + // b. Let bytesToCopy be min(totalBytesToCopyRemaining, + // headOfQueue’s byte length). + size_t bytes_to_copy = + std::min(total_bytes_to_copy_remaining, head_of_queue->byte_length); + // c. Let destStart be pullIntoDescriptor’s byte offset + + // pullIntoDescriptor’s bytes filled. + // This addition will not overflow because byte offset and bytes filled + // refer to actually allocated memory, so together they cannot exceed + // size_t. + size_t dest_start = + pull_into_descriptor->byte_offset + pull_into_descriptor->bytes_filled; + // d. Perform ! CopyDataBlockBytes(pullIntoDescriptor’s + // buffer.[[ArrayBufferData]], destStart, headOfQueue’s + // buffer.[[ArrayBufferData]], headOfQueue’s byte offset, bytesToCopy). + memcpy( + static_cast<char*>(pull_into_descriptor->buffer->Data()) + dest_start, + static_cast<char*>(head_of_queue->buffer->Data()) + + head_of_queue->byte_offset, + bytes_to_copy); + // e. If headOfQueue’s byte length is bytesToCopy, + if (head_of_queue->byte_length == bytes_to_copy) { + // i. Remove queue[0]. + queue.pop_front(); + } else { + // f. Otherwise, + // i. Set headOfQueue’s byte offset to headOfQueue’s byte offset + + // bytesToCopy. + head_of_queue->byte_offset = + base::CheckAdd(head_of_queue->byte_offset, bytes_to_copy) + .ValueOrDie(); + // ii. Set headOfQueue’s byte length to headOfQueue’s byte + // length − bytesToCopy. + head_of_queue->byte_length = + base::CheckSub(head_of_queue->byte_length, bytes_to_copy) + .ValueOrDie(); + } + // g. Set controller.[[queueTotalSize]] to controller.[[queueTotalSize]] − + // bytesToCopy. + controller->queue_total_size_ = + base::CheckSub(controller->queue_total_size_, bytes_to_copy) + .ValueOrDie(); + // h. Perform ! + // ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, + // bytesToCopy, pullIntoDescriptor). + FillHeadPullIntoDescriptor(controller, bytes_to_copy, pull_into_descriptor); + // i. Set totalBytesToCopyRemaining to totalBytesToCopyRemaining − + // bytesToCopy. + // This subtraction will not underflow because bytes_to_copy will always be + // greater than or equal to total_bytes_to_copy_remaining. + total_bytes_to_copy_remaining -= bytes_to_copy; + } + // 11. If ready is false, + if (!ready) { + // a. Assert: controller.[[queueTotalSize]] is 0. + DCHECK_EQ(controller->queue_total_size_, 0u); + // b. Assert: pullIntoDescriptor’s bytes filled > 0. + DCHECK_GT(pull_into_descriptor->bytes_filled, 0.0); + // c. Assert: pullIntoDescriptor’s bytes filled < pullIntoDescriptor’s + // element size. + DCHECK_LT(pull_into_descriptor->bytes_filled, + pull_into_descriptor->element_size); + } + // 12. Return ready. + return ready; +} + +void ReadableByteStreamController::PullInto( + ScriptState* script_state, + ReadableByteStreamController* controller, + NotShared<DOMArrayBufferView> view, + ReadableStreamBYOBReader::ReadIntoRequest* read_into_request, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-pull-into + // 1. Let stream be controller.[[stream]]. + ReadableStream* const stream = controller->controlled_readable_stream_; + // 2. Let elementSize be 1. + size_t element_size = 1; + // 3. Let ctor be %DataView%. + auto* ctor = &CreateAsArrayBufferView<DOMDataView>; + // 4. If view has a [[TypedArrayName]] internal slot (i.e., it is not a + // DataView), + if (view->GetType() != DOMArrayBufferView::kTypeDataView) { + // a. Set elementSize to be the element size specified in the typed array + // constructors table for view.[[TypedArrayName]]. + element_size = view->TypeSize(); + // b. Set ctor to the constructor specified in the typed array + // constructors table for view.[[TypedArrayName]]. + switch (view->GetType()) { + case DOMArrayBufferView::kTypeInt8: + ctor = &CreateAsArrayBufferView<DOMInt8Array>; + break; + case DOMArrayBufferView::kTypeUint8: + ctor = &CreateAsArrayBufferView<DOMUint8Array>; + break; + case DOMArrayBufferView::kTypeUint8Clamped: + ctor = &CreateAsArrayBufferView<DOMUint8ClampedArray>; + break; + case DOMArrayBufferView::kTypeInt16: + ctor = &CreateAsArrayBufferView<DOMInt16Array>; + break; + case DOMArrayBufferView::kTypeUint16: + ctor = &CreateAsArrayBufferView<DOMUint16Array>; + break; + case DOMArrayBufferView::kTypeInt32: + ctor = &CreateAsArrayBufferView<DOMInt32Array>; + break; + case DOMArrayBufferView::kTypeUint32: + ctor = &CreateAsArrayBufferView<DOMUint32Array>; + break; + case DOMArrayBufferView::kTypeFloat32: + ctor = &CreateAsArrayBufferView<DOMFloat32Array>; + break; + case DOMArrayBufferView::kTypeFloat64: + ctor = &CreateAsArrayBufferView<DOMFloat64Array>; + break; + case DOMArrayBufferView::kTypeBigInt64: + ctor = &CreateAsArrayBufferView<DOMBigInt64Array>; + break; + case DOMArrayBufferView::kTypeBigUint64: + ctor = &CreateAsArrayBufferView<DOMBigUint64Array>; + break; + case DOMArrayBufferView::kTypeDataView: + NOTREACHED(); + } + } + // 5. Let byteOffset be view.[[ByteOffset]]. + const size_t byte_offset = view->byteOffset(); + // 6. Let byteLength be view.[[ByteLength]]. + const size_t byte_length = view->byteLength(); + // 7. Let buffer be ! TransferArrayBuffer(view.[[ViewedArrayBuffer]]). + DOMArrayBuffer* buffer = + TransferArrayBuffer(script_state, view->buffer(), exception_state); + // 8. Let pullIntoDescriptor be a new pull-into descriptor with buffer buffer, + // byte offset byteOffset, byte length byteLength, bytes filled 0, element + // size elementSize, view construcot ctor, and reader type "byob". + PullIntoDescriptor* pull_into_descriptor = + MakeGarbageCollected<PullIntoDescriptor>(buffer, byte_offset, byte_length, + 0, element_size, ctor, + ReaderType::kBYOB); + // 9. If controller.[[pendingPullIntos]] is not empty, + if (!controller->pending_pull_intos_.IsEmpty()) { + // a. Append pullIntoDescriptor to controller.[[pendingPullIntos]]. + controller->pending_pull_intos_.push_back(pull_into_descriptor); + // b. Perform ! ReadableStreamAddReadIntoRequest(stream, readIntoRequest). + ReadableStream::AddReadIntoRequest(script_state, stream, read_into_request); + // c. Return. + return; + } + // 10. If stream.[[state]] is "closed", + if (stream->state_ == ReadableStream::kClosed) { + // a. Let emptyView be ! Construct(ctor, « pullIntoDescriptor’s buffer, + // pullIntoDescriptor’s byte offset, 0 »). + DOMArrayBufferView* emptyView = ctor(pull_into_descriptor->buffer, + pull_into_descriptor->byte_offset, 0); + // b. Perform readIntoRequest’s close steps, given emptyView. + read_into_request->CloseSteps(script_state, emptyView); + // c. Return. + return; + } + // 11. If controller.[[queueTotalSize]] > 0, + if (controller->queue_total_size_ > 0) { + // a. If ! + // ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, + // pullIntoDescriptor) is true, + if (FillPullIntoDescriptorFromQueue(controller, pull_into_descriptor)) { + // i. Let filledView be ! + // ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor). + DOMArrayBufferView* filled_view = + ConvertPullIntoDescriptor(pull_into_descriptor); + // ii. Perform ! + // ReadableByteStreamControllerHandleQueueDrain(controller). + HandleQueueDrain(script_state, controller); + // iii. Perform readIntoRequest’s chunk steps, given filledView. + read_into_request->ChunkSteps(script_state, filled_view); + // iv. Return. + return; + } + // b. If controller.[[closeRequested]] is true, + if (controller->close_requested_) { + // i. Let e be a TypeError exception. + v8::Local<v8::Value> e = V8ThrowException::CreateTypeError( + script_state->GetIsolate(), "close requested"); + // ii. Perform ! ReadableByteStreamControllerError(controller, e). + controller->Error(script_state, controller, e); + // iii. Perform readIntoRequest’s error steps, given e. + read_into_request->ErrorSteps(script_state, e); + // iv. Return. + return; + } + } + // 12. Append pullIntoDescriptor to controller.[[pendingPullIntos]]. + controller->pending_pull_intos_.push_back(pull_into_descriptor); + // 13. Perform ! ReadableStreamAddReadIntoRequest(stream, readIntoRequest). + ReadableStream::AddReadIntoRequest(script_state, stream, read_into_request); + // 14. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller). + CallPullIfNeeded(script_state, controller); +} + +void ReadableByteStreamController::HandleQueueDrain( + ScriptState* script_state, + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-handle-queue-drain + // 1. Assert: controller.[[stream]].[[state]] is "readable". + DCHECK_EQ(controller->controlled_readable_stream_->state_, + ReadableStream::kReadable); + // 2. If controller.[[queueTotalSize]] is 0 and controller.[[closeRequested]] + // is true, + if (!controller->queue_total_size_ && controller->close_requested_) { + // a. Perform ! ReadableByteStreamControllerClearAlgorithms(controller). + ClearAlgorithms(controller); + // b. Perform ! ReadableStreamClose(controller.[[stream]]). + ReadableStream::Close(script_state, + controller->controlled_readable_stream_); + } else { + // 3. Otherwise, + // a. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller). + CallPullIfNeeded(script_state, controller); + } +} + +void ReadableByteStreamController::ResetQueue( + ReadableByteStreamController* controller) { + // https://streams.spec.whatwg.org/#reset-queue + // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots. + // 2. Set container.[[queue]] to a new empty list. + controller->queue_.clear(); + // 3. Set container.[[queueTotalSize]] to 0. + controller->queue_total_size_ = 0; +} + +void ReadableByteStreamController::Respond( + ScriptState* script_state, + ReadableByteStreamController* controller, + size_t bytes_written, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond + // 1. Assert: controller.[[pendingPullIntos]] is not empty. + DCHECK(!controller->pending_pull_intos_.IsEmpty()); + // 2. Perform ? ReadableByteStreamControllerRespondInternal(controller, + // bytesWritten). + RespondInternal(script_state, controller, bytes_written, exception_state); +} + +void ReadableByteStreamController::RespondInClosedState( + ScriptState* script_state, + ReadableByteStreamController* controller, + PullIntoDescriptor* first_descriptor, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-in-closed-state + // 1. Set firstDescriptor’s buffer to ! TransferArrayBuffer(firstDescriptor’s + // buffer). + first_descriptor->buffer = TransferArrayBuffer( + script_state, first_descriptor->buffer, exception_state); + // 2. Assert: firstDescriptor’s bytes filled is 0. + DCHECK_EQ(first_descriptor->bytes_filled, 0u); + // 3. Let stream be controller.[[stream]]. + ReadableStream* const stream = controller->controlled_readable_stream_; + // 4. If ! ReadableStreamHasBYOBReader(stream) is true, + if (ReadableStream::HasBYOBReader(stream)) { + // a. While ! ReadableStreamGetNumReadIntoRequests(stream) > 0, + while (ReadableStream::GetNumReadIntoRequests(stream) > 0) { + // i. Let pullIntoDescriptor be ! + // ReadableByteStreamControllerShiftPendingPullInto(controller). + PullIntoDescriptor* pull_into_descriptor = + ShiftPendingPullInto(controller); + // ii. Perform ! + // ReadableByteStreamControllerCommitPullIntoDescriptor(stream, + // pullIntoDescriptor). + CommitPullIntoDescriptor(script_state, stream, pull_into_descriptor); + } + } +} + +void ReadableByteStreamController::RespondInReadableState( + ScriptState* script_state, + ReadableByteStreamController* controller, + size_t bytes_written, + PullIntoDescriptor* pull_into_descriptor, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-in-readable-state + // 1. If pullIntoDescriptor’s bytes filled + bytesWritten > + // pullIntoDescriptor’s byte length, throw a RangeError exception. + if (base::ClampAdd(pull_into_descriptor->bytes_filled, bytes_written) > + pull_into_descriptor->byte_length) { + exception_state.ThrowRangeError( + "Cannot respond because buffer will overflow if written to"); + return; + } + // 2. Perform ! + // ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, + // bytesWritten, pullIntoDescriptor). + FillHeadPullIntoDescriptor(controller, bytes_written, pull_into_descriptor); + // 3. If pullIntoDescriptor’s bytes filled < pullIntoDescriptor’s element + // size, return. + if (pull_into_descriptor->bytes_filled < pull_into_descriptor->element_size) { + return; + } + // 4. Perform ! ReadableByteStreamControllerShiftPendingPullInto(controller). + ShiftPendingPullInto(controller); + // 5. Let remainderSize be pullIntoDescriptor’s bytes filled mod + // pullIntoDescriptor’s element size. + const size_t remainder_size = + pull_into_descriptor->bytes_filled % pull_into_descriptor->element_size; + // 6. If remainderSize > 0, + if (remainder_size > 0) { + // a. Let end be pullIntoDescriptor’s byte offset + pullIntoDescriptor’s + // bytes filled. + // This addition will not overflow because byte offset and bytes filled + // refer to actually allocated memory, so together they cannot exceed + // size_t. + size_t end = + pull_into_descriptor->byte_offset + pull_into_descriptor->bytes_filled; + // b. Let remainder be ? CloneArrayBuffer(pullIntoDescriptor’s + // buffer, end − remainderSize, remainderSize, %ArrayBuffer%). + DOMArrayBuffer* const remainder = DOMArrayBuffer::Create( + static_cast<char*>(pull_into_descriptor->buffer->Data()) + end - + remainder_size, + remainder_size); + // c. Perform ! + // ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, + // 0, remainder.[[ByteLength]]). + EnqueueChunkToQueue(controller, remainder, 0, remainder->ByteLength()); + } + // 7. Set pullIntoDescriptor’s buffer to ! + // TransferArrayBuffer(pullIntoDescriptor’s buffer). + pull_into_descriptor->buffer = TransferArrayBuffer( + script_state, pull_into_descriptor->buffer, exception_state); + // 8. Set pullIntoDescriptor’s bytes filled to pullIntoDescriptor’s bytes + // filled − remainderSize. + pull_into_descriptor->bytes_filled = + pull_into_descriptor->bytes_filled - remainder_size; + // 9. Perform ! + // ReadableByteStreamControllerCommitPullIntoDescriptor(controller.[[stream]], + // pullIntoDescriptor). + CommitPullIntoDescriptor(script_state, + controller->controlled_readable_stream_, + pull_into_descriptor); + // 10. Perform ! + // ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller). + ProcessPullIntoDescriptorsUsingQueue(script_state, controller); +} + +void ReadableByteStreamController::RespondInternal( + ScriptState* script_state, + ReadableByteStreamController* controller, + size_t bytes_written, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-internal + // 1. Let firstDescriptor be controller.[[pendingPullIntos]][0]. + PullIntoDescriptor* const first_descriptor = + controller->pending_pull_intos_[0]; + // 2. Let state be controller.[[stream]].[[state]]. + const ReadableStream::State state = + controller->controlled_readable_stream_->state_; + // 3. If state is "closed", + if (state == ReadableStream::kClosed) { + // a. If bytesWritten is not 0, throw a TypeError exception. + if (bytes_written != 0) { + exception_state.ThrowTypeError("bytes written is not 0"); + return; + } + // b. Perform ! + // ReadableByteStreamControllerRespondInClosedState(controller, + // firstDescriptor). + RespondInClosedState(script_state, controller, first_descriptor, + exception_state); + } else { + // 4. Otherwise, + // a. Assert: state is "readable". + DCHECK_EQ(state, ReadableStream::kReadable); + // b. Perform ? + // ReadableByteStreamControllerRespondInReadableState(controller, + // bytesWritten, firstDescriptor). + RespondInReadableState(script_state, controller, bytes_written, + first_descriptor, exception_state); + } + // 5. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller). + CallPullIfNeeded(script_state, controller); +} + +void ReadableByteStreamController::RespondWithNewView( + ScriptState* script_state, + ReadableByteStreamController* controller, + NotShared<DOMArrayBufferView> view, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-with-new-view + // 1. Assert: controller.[[pendingPullIntos]] is not empty. + DCHECK(!controller->pending_pull_intos_.IsEmpty()); + // 2. Let firstDescriptor be controller.[[pendingPullIntos]][0]. + PullIntoDescriptor* first_descriptor = controller->pending_pull_intos_[0]; + // 3. If firstDescriptor’s byte offset + firstDescriptor’ bytes filled is not + // view.[[ByteOffset]], throw a RangeError exception. + // We don't expect this addition to overflow as the bytes are expected to be + // equal. + if (first_descriptor->byte_offset + first_descriptor->bytes_filled != + view->byteOffset()) { + exception_state.ThrowRangeError( + "First descriptor's byte offset and bytes filled is not the same as " + "the view's byte offset"); + return; + } + // 4. If firstDescriptor’s byte length is not view.[[ByteLength]], throw a + // RangeError exception. + if (first_descriptor->byte_length != view->byteLength()) { + exception_state.ThrowRangeError("byte lengths are not equal"); + return; + } + // 5. Set firstDescriptor’s buffer to view.[[ViewedArrayBuffer]]. + first_descriptor->buffer = view->buffer(); + // 6. Perform ? ReadableByteStreamControllerRespondInternal(controller, + // view.[[ByteLength]]). + RespondInternal(script_state, controller, view->byteLength(), + exception_state); +} + +DOMArrayBuffer* ReadableByteStreamController::TransferArrayBuffer( + ScriptState* script_state, + DOMArrayBuffer* buffer, + ExceptionState& exception_state) { + ArrayBufferContents contents; + if (buffer->IsDetachable(script_state->GetIsolate()) && + buffer->Transfer(script_state->GetIsolate(), contents)) { + return DOMArrayBuffer::Create(std::move(contents)); + } + exception_state.ThrowTypeError("not able to transfer array buffer"); + return nullptr; +} + +void ReadableByteStreamController::Trace(Visitor* visitor) const { + visitor->Trace(byob_request_); + visitor->Trace(cancel_algorithm_); + visitor->Trace(controlled_readable_stream_); + visitor->Trace(pending_pull_intos_); + visitor->Trace(pull_algorithm_); + visitor->Trace(queue_); + ScriptWrappable::Trace(visitor); } // @@ -58,25 +1313,95 @@ v8::Local<v8::Promise> ReadableByteStreamController::CancelSteps( ScriptState* script_state, v8::Local<v8::Value> reason) { - ExceptionState exception_state(script_state->GetIsolate(), - ExceptionState::kExecutionContext, nullptr, - nullptr); - ThrowUnimplemented(exception_state); - return v8::Local<v8::Promise>(); + // https://streams.spec.whatwg.org/#rbs-controller-private-cancel + // 1. If this.[[pendingPullIntos]] is not empty, + if (!pending_pull_intos_.IsEmpty()) { + // a. Let firstDescriptor be this.[[pendingPullIntos]][0]. + PullIntoDescriptor* first_descriptor = pending_pull_intos_[0]; + // b. Set firstDescriptor’s bytes filled to 0. + first_descriptor->bytes_filled = 0; + } + // 2. Perform ! ResetQueue(this). + ResetQueue(this); + // 3. Let result be the result of performing this.[[cancelAlgorithm]], passing + // in reason. + auto result = cancel_algorithm_->Run(script_state, 1, &reason); + // 4. Perform ! ReadableByteStreamControllerClearAlgorithms(this). + ClearAlgorithms(this); + // 5. Return result. + return result; } StreamPromiseResolver* ReadableByteStreamController::PullSteps( ScriptState* script_state) { - ExceptionState exception_state(script_state->GetIsolate(), - ExceptionState::kExecutionContext, nullptr, - nullptr); - ThrowUnimplemented(exception_state); - return nullptr; -} + // https://whatpr.org/streams/1029.html#rbs-controller-private-pull + // TODO: This function follows an old version of the spec referenced above, so + // it needs to be updated to the new version on + // https://streams.spec.whatwg.org when the ReadableStreamDefaultReader + // implementation is updated. + // 1. Let stream be this.[[controlledReadableByteStream]]. + ReadableStream* const stream = controlled_readable_stream_; + // 2. Assert: ! ReadableStreamHasDefaultReader(stream) is true. + DCHECK(ReadableStream::HasDefaultReader(stream)); + // 3. If this.[[queueTotalSize]] > 0, + if (queue_total_size_ > 0) { + // a. Assert: ! ReadableStreamGetNumReadRequests(stream) is 0. + DCHECK_EQ(ReadableStream::GetNumReadRequests(stream), 0); + // b. Let entry be the first element of this.[[queue]]. + QueueEntry* entry = queue_[0]; + // c. Remove entry from this.[[queue]], shifting all other elements + // downward (so that the second becomes the first, and so on). + queue_.pop_front(); + // d. Set this.[[queueTotalSize]] to this.[[queueTotalSize]] − + // entry.[[byteLength]]. + queue_total_size_ -= entry->byte_length; + // e. Perform ! ReadableByteStreamControllerHandleQueueDrain(this). + HandleQueueDrain(script_state, this); + // f. Let view be ! Construct(%Uint8Array%, « entry.[[buffer]], + // entry.[[byteOffset]], entry.[[byteLength]] »). + DOMUint8Array* view = DOMUint8Array::Create( + entry->buffer, entry->byte_offset, entry->byte_length); + // g. Return a promise resolved with ! + // ReadableStreamCreateReadResult(view, false, + // stream.[[reader]].[[forAuthorCode]]). + ReadableStreamGenericReader* reader = stream->reader_; + return StreamPromiseResolver::CreateResolved( + script_state, + ReadableStream::CreateReadResult( + script_state, ToV8(view, script_state), false, + To<ReadableStreamDefaultReader>(reader)->for_author_code_)); + } + // 4. Let autoAllocateChunkSize be this.[[autoAllocateChunkSize]]. + const size_t auto_allocate_chunk_size = auto_allocate_chunk_size_; + // 5. If autoAllocateChunkSize is not undefined, + if (auto_allocate_chunk_size) { + // a. Let buffer be Construct(%ArrayBuffer%, « autoAllocateChunkSize »). + auto* buffer = DOMArrayBuffer::Create(auto_allocate_chunk_size, 1); + // b. If buffer is an abrupt completion, return a promise rejected with + // buffer.[[Value]]. + // This is not needed as DOMArrayBuffer::Create() is designed to + // crash if it cannot allocate the memory. -void ReadableByteStreamController::ThrowUnimplemented( - ExceptionState& exception_state) { - exception_state.ThrowTypeError("unimplemented"); + // c. Let pullIntoDescriptor be Record {[[buffer]]: buffer.[[Value]], + // [[byteOffset]]: 0, [[byteLength]]: autoAllocateChunkSize, + // [[bytesFilled]]: 0, [[elementSize]]: 1, [[ctor]]: %Uint8Array%, + // [[readerType]]: "default"}. + auto* ctor = &CreateAsArrayBufferView<DOMUint8Array>; + PullIntoDescriptor* pull_into_descriptor = + MakeGarbageCollected<PullIntoDescriptor>(buffer, 0, + auto_allocate_chunk_size, 0, 1, + ctor, ReaderType::kDefault); + // d. Append pullIntoDescriptor as the last element of + // this.[[pendingPullIntos]]. + pending_pull_intos_.push_back(pull_into_descriptor); + } + // 6. Let promise be ! ReadableStreamAddReadRequest(stream). + StreamPromiseResolver* promise = + ReadableStream::AddReadRequest(script_state, stream); + // 7. Perform ! ReadableByteStreamControllerCallPullIfNeeded(this). + CallPullIfNeeded(script_state, this); + // 8. Return promise. + return promise; } } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h index 84d1e38..faf5fa3d 100644 --- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h +++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h
@@ -7,28 +7,40 @@ #include "base/optional.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/core/streams/readable_stream_byob_reader.h" #include "third_party/blink/renderer/core/streams/readable_stream_controller.h" #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" #include "v8/include/v8.h" namespace blink { +class DOMArrayBuffer; class DOMArrayBufferView; class ExceptionState; +class ReadableStream; class ReadableStreamBYOBRequest; class ScriptState; +class StreamAlgorithm; +class StreamStartAlgorithm; class StreamPromiseResolver; +class UnderlyingSource; class ReadableByteStreamController : public ReadableStreamController { DEFINE_WRAPPERTYPEINFO(); public: + ReadableByteStreamController(); + // https://streams.spec.whatwg.org/#rbs-controller-byob-request - ReadableStreamBYOBRequest* byobRequest(ExceptionState&) const; + ReadableStreamBYOBRequest* byobRequest(); // https://streams.spec.whatwg.org/#rbs-controller-desired-size - base::Optional<double> desiredSize(ExceptionState&) const; + base::Optional<double> desiredSize(); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-get-desired-size + static base::Optional<double> GetDesiredSize(ReadableByteStreamController*); // https://streams.spec.whatwg.org/#rbs-controller-close void close(ScriptState*, ExceptionState&); @@ -39,8 +51,192 @@ ExceptionState&); // https://streams.spec.whatwg.org/#rbs-controller-error - void error(ScriptState*, ExceptionState&); - void error(ScriptState*, ScriptValue e, ExceptionState&); + void error(ScriptState*); + void error(ScriptState*, const ScriptValue& e); + + bool IsByteStreamController() const override { return true; } + bool IsDefaultController() const override { return false; } + + void Trace(Visitor*) const override; + + private: + friend class ReadableStream; + friend class ReadableStreamBYOBReader; + friend class ReadableStreamBYOBRequest; + + // https://streams.spec.whatwg.org/#readable-byte-stream-queue-entry + struct QueueEntry final : public GarbageCollected<QueueEntry> { + explicit QueueEntry(DOMArrayBuffer* buffer, + size_t byte_offset, + size_t byte_length); + + const Member<DOMArrayBuffer> buffer; + size_t byte_offset; + size_t byte_length; + + void Trace(Visitor*) const; + }; + + enum class ReaderType { kDefault, kBYOB }; + + // https://streams.spec.whatwg.org/#pull-into-descriptor + struct PullIntoDescriptor final + : public GarbageCollected<PullIntoDescriptor> { + // A function pointer is used to represent the view constructor + // to accommodate for different array types as specified by the + // ArrayBufferViewConstructorAdaptor. + using ViewConstructorType = DOMArrayBufferView* (*)(DOMArrayBuffer*, + size_t, + size_t); + + explicit PullIntoDescriptor(DOMArrayBuffer* buffer, + size_t byte_offset, + size_t byte_length, + size_t bytes_filled, + size_t element_size, + ViewConstructorType view_constructor, + ReaderType reader_type); + + Member<DOMArrayBuffer> buffer; + size_t byte_offset; + const size_t byte_length; + size_t bytes_filled; + const size_t element_size; + const ViewConstructorType view_constructor; + const ReaderType reader_type; + + void Trace(Visitor*) const; + }; + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-close + void Close(ScriptState*, ReadableByteStreamController*, ExceptionState&); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-error + static void Error(ScriptState*, + ReadableByteStreamController*, + v8::Local<v8::Value> e); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-enqueue + void Enqueue(ScriptState*, + ReadableByteStreamController*, + NotShared<DOMArrayBufferView> chunk, + ExceptionState&); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-enqueue-chunk-to-queue + static void EnqueueChunkToQueue(ReadableByteStreamController*, + DOMArrayBuffer*, + size_t byte_offset, + size_t byte_length); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-process-pull-into-descriptors-using-queue + static void ProcessPullIntoDescriptorsUsingQueue( + ScriptState*, + ReadableByteStreamController*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-call-pull-if-needed + static void CallPullIfNeeded(ScriptState*, ReadableByteStreamController*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-shift-pending-pull-into + static PullIntoDescriptor* ShiftPendingPullInto( + ReadableByteStreamController*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-should-call-pull + static bool ShouldCallPull(ReadableByteStreamController*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-commit-pull-into-descriptor + static void CommitPullIntoDescriptor(ScriptState*, + ReadableStream*, + PullIntoDescriptor*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-convert-pull-into-descriptor + static DOMArrayBufferView* ConvertPullIntoDescriptor(PullIntoDescriptor*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-clear-pending-pull-intos + static void ClearPendingPullIntos(ReadableByteStreamController*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-clear-algorithms + static void ClearAlgorithms(ReadableByteStreamController*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-invalidate-byob-request + static void InvalidateBYOBRequest(ReadableByteStreamController*); + + // https://streams.spec.whatwg.org/#set-up-readable-byte-stream-controller + static void SetUp(ScriptState*, + ReadableStream*, + ReadableByteStreamController*, + StreamStartAlgorithm* start_algorithm, + StreamAlgorithm* pull_algorithm, + StreamAlgorithm* cancel_algorithm, + double high_water_mark, + size_t auto_allocate_chunk_size, + ExceptionState&); + + // https://streams.spec.whatwg.org/#set-up-readable-byte-stream-controller-from-underlying-source + static void SetUpFromUnderlyingSource( + ScriptState*, + ReadableStream*, + v8::Local<v8::Object> underlying_source, + UnderlyingSource* underlying_source_dict, + double high_water_mark, + ExceptionState&); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-fill-head-pull-into-descriptor + static void FillHeadPullIntoDescriptor(ReadableByteStreamController*, + size_t size, + PullIntoDescriptor*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-fill-pull-into-descriptor-from-queue + static bool FillPullIntoDescriptorFromQueue(ReadableByteStreamController*, + PullIntoDescriptor*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-pull-into + static void PullInto(ScriptState*, + ReadableByteStreamController*, + NotShared<DOMArrayBufferView> view, + ReadableStreamBYOBReader::ReadIntoRequest*, + ExceptionState&); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-handle-queue-drain + static void HandleQueueDrain(ScriptState*, ReadableByteStreamController*); + + // https://streams.spec.whatwg.org/#reset-queue + static void ResetQueue(ReadableByteStreamController*); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond + static void Respond(ScriptState*, + ReadableByteStreamController*, + size_t bytes_written, + ExceptionState&); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-in-closed-state + static void RespondInClosedState(ScriptState*, + ReadableByteStreamController*, + PullIntoDescriptor* first_descriptor, + ExceptionState&); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-in-readable-state + static void RespondInReadableState(ScriptState*, + ReadableByteStreamController*, + size_t bytes_written, + PullIntoDescriptor*, + ExceptionState&); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-internal + static void RespondInternal(ScriptState*, + ReadableByteStreamController*, + size_t bytes_written, + ExceptionState&); + + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-with-new-view + static void RespondWithNewView(ScriptState*, + ReadableByteStreamController*, + NotShared<DOMArrayBufferView> view, + ExceptionState&); + + // https://streams.spec.whatwg.org/#transfer-array-buffer + static DOMArrayBuffer* TransferArrayBuffer(ScriptState*, + DOMArrayBuffer* buffer, + ExceptionState&); // https://streams.spec.whatwg.org/#rbs-controller-private-cancel v8::Local<v8::Promise> CancelSteps(ScriptState*, @@ -49,8 +245,27 @@ // https://streams.spec.whatwg.org/#rbs-controller-private-pull StreamPromiseResolver* PullSteps(ScriptState*) override; - private: - static void ThrowUnimplemented(ExceptionState&); + // autoAllocateChunkSize is encoded as 0 when it is undefined + size_t auto_allocate_chunk_size_ = 0u; + Member<ReadableStreamBYOBRequest> byob_request_; + Member<StreamAlgorithm> cancel_algorithm_; + bool close_requested_ = false; + bool pull_again_ = false; + Member<StreamAlgorithm> pull_algorithm_; + bool pulling_ = false; + HeapDeque<Member<PullIntoDescriptor>> pending_pull_intos_; + HeapDeque<Member<QueueEntry>> queue_; + double queue_total_size_; + bool started_ = false; + double strategy_high_water_mark_ = 0.0; + Member<ReadableStream> controlled_readable_stream_; +}; + +template <> +struct DowncastTraits<ReadableByteStreamController> { + static bool AllowFrom(const ReadableStreamController& controller) { + return controller.IsByteStreamController(); + } }; } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.idl b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.idl index db8ac02b..1e2db3ea 100644 --- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.idl +++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.idl
@@ -7,10 +7,10 @@ Exposed=(Window,Worker,Worklet), RuntimeEnabled=ReadableByteStream ] interface ReadableByteStreamController { - [RaisesException] readonly attribute ReadableStreamBYOBRequest? byobRequest; - [RaisesException] readonly attribute double? desiredSize; + readonly attribute ReadableStreamBYOBRequest? byobRequest; + readonly attribute double? desiredSize; [CallWith=ScriptState, RaisesException] void close(); [CallWith=ScriptState, RaisesException] void enqueue(ArrayBufferView chunk); - [CallWith=ScriptState, RaisesException] void error(optional any e); + [CallWith=ScriptState] void error(optional any e); };
diff --git a/third_party/blink/renderer/core/streams/readable_stream.cc b/third_party/blink/renderer/core/streams/readable_stream.cc index 5af2489..8e54f5d3 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.cc +++ b/third_party/blink/renderer/core/streams/readable_stream.cc
@@ -14,12 +14,15 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_readable_writable_pair.h" #include "third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_underlying_source.h" #include "third_party/blink/renderer/bindings/core/v8/v8_writable_stream.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/streams/miscellaneous_operations.h" #include "third_party/blink/renderer/core/streams/promise_handler.h" +#include "third_party/blink/renderer/core/streams/readable_byte_stream_controller.h" +#include "third_party/blink/renderer/core/streams/readable_stream_controller.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_controller.h" #include "third_party/blink/renderer/core/streams/readable_stream_generic_reader.h" #include "third_party/blink/renderer/core/streams/readable_stream_transferring_optimizer.h" @@ -39,6 +42,7 @@ #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/deque.h" @@ -1012,7 +1016,11 @@ } for (int branch = 0; branch < 2; ++branch) { - controller_[branch] = branch_[branch]->readable_stream_controller_; + ReadableStreamController* controller = + branch_[branch]->readable_stream_controller_; + // We just created the branches above. It is obvious that the controllers + // are default controllers. + controller_[branch] = To<ReadableStreamDefaultController>(controller); } class RejectFunction final : public PromiseHandler { @@ -1236,17 +1244,13 @@ ReadableStreamDefaultReaderOrReadableStreamBYOBReader& return_value, ExceptionState& exception_state) { // https://streams.spec.whatwg.org/#rs-get-reader - // Since byob readers are not completely implemented yet, this function should - // just call the default getReader(). - // TODO(nidhijaju): Add assertion options["mode"] is "byob" and return - // ? AcquireReadableStreamBYOBReader(this) according to spec, once byob - // readers have been implemented. if (options->hasMode()) { DCHECK_EQ(options->mode(), "byob"); - exception_state.ThrowTypeError("byob not implemented"); - return; + return_value.SetReadableStreamBYOBReader( + AcquireBYOBReader(script_state, this, exception_state)); + } else { + getReader(script_state, return_value, exception_state); } - getReader(script_state, return_value, exception_state); } ReadableStreamDefaultReader* ReadableStream::GetDefaultReaderForTesting( @@ -1407,14 +1411,35 @@ // 6. If typeString is "bytes", if (type_string == V8AtomicString(isolate, "bytes")) { - // TODO(ricea): Implement bytes type. - exception_state.ThrowRangeError("bytes type is not yet implemented"); + if (!RuntimeEnabledFeatures::ReadableByteStreamEnabled()) { + exception_state.ThrowRangeError("bytes type is not yet implemented"); + return; + } + UnderlyingSource* underlying_source_dict = UnderlyingSource::Create(); + V8UnderlyingSource::ToImpl(script_state->GetIsolate(), + raw_underlying_source.V8Value(), + underlying_source_dict, exception_state); + if (!strategy_unpacker.IsSizeUndefined()) { + exception_state.ThrowRangeError( + "Cannot create byte stream with size() defined on the strategy"); + return; + } + double high_water_mark = + strategy_unpacker.GetHighWaterMark(script_state, 0, exception_state); + if (exception_state.HadException()) { + return; + } + ReadableByteStreamController::SetUpFromUnderlyingSource( + script_state, this, underlying_source, underlying_source_dict, + high_water_mark, exception_state); return; } // 8. Otherwise, throw a RangeError exception. - exception_state.ThrowRangeError("Invalid type is specified"); - return; + else { + exception_state.ThrowRangeError("Invalid type is specified"); + return; + } } // 7. Otherwise, if type is undefined, @@ -1467,6 +1492,23 @@ return reader; } +ReadableStreamBYOBReader* ReadableStream::AcquireBYOBReader( + ScriptState* script_state, + ReadableStream* stream, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#acquire-readable-stream-byob-reader + // 1. Let reader be a new ReadableStreamBYOBReader. + // 2. Perform ? SetUpBYOBReader(reader, stream). + auto* reader = MakeGarbageCollected<ReadableStreamBYOBReader>( + script_state, stream, exception_state); + if (exception_state.HadException()) { + return nullptr; + } + + // 3. Return reader. + return reader; +} + void ReadableStream::Initialize(ReadableStream* stream) { // Fields are initialised by the constructor, so we only check that they were // initialised correctly. @@ -1611,13 +1653,28 @@ // Abstract Operations Used By Controllers // +void ReadableStream::AddReadIntoRequest( + ScriptState* script_state, + ReadableStream* stream, + ReadableStreamBYOBReader::ReadIntoRequest* readRequest) { + // https://streams.spec.whatwg.org/#readable-stream-add-read-into-request + // 1. Assert: stream.[[reader]] implements ReadableStreamBYOBReader. + DCHECK(stream->reader_->IsBYOBReader()); + // 2. Assert: stream.[[state]] is "readable" or "closed". + DCHECK(stream->state_ == kReadable || stream->state_ == kClosed); + // 3. Append readRequest to stream.[[reader]].[[readIntoRequests]]. + ReadableStreamGenericReader* reader = stream->reader_; + ReadableStreamBYOBReader* byob_reader = To<ReadableStreamBYOBReader>(reader); + byob_reader->read_into_requests_.push_back(readRequest); +} + StreamPromiseResolver* ReadableStream::AddReadRequest(ScriptState* script_state, ReadableStream* stream) { // https://streams.spec.whatwg.org/#readable-stream-add-read-request // 1. Assert: ! IsReadableStreamDefaultReader(stream.[[reader]]) is true. ReadableStreamGenericReader* reader = stream->reader_; ReadableStreamDefaultReader* default_reader = - static_cast<ReadableStreamDefaultReader*>(reader); + To<ReadableStreamDefaultReader>(reader); DCHECK(default_reader); // 2. Assert: stream.[[state]] is "readable". @@ -1699,30 +1756,28 @@ return; } - // TODO(ricea): Support BYOB readers. // 5. If ! IsReadableStreamDefaultReader(reader) is true, - // TODO(nidhijaju): Add a check that the reader is a default reader once BYOB - // readers have been implemented, so the static_cast can be changed later on. - // a. Repeat for each readRequest that is an element of reader. - // [[readRequests]], - HeapDeque<Member<StreamPromiseResolver>> requests; - requests.Swap( - static_cast<ReadableStreamDefaultReader*>(reader)->read_requests_); - for (StreamPromiseResolver* promise : requests) { - // i. Resolve readRequest.[[promise]] with ! - // ReadableStreamCreateReadResult(undefined, true, reader. - // [[forAuthorCode]]). - promise->Resolve( - script_state, - CreateReadResult(script_state, - v8::Undefined(script_state->GetIsolate()), true, - static_cast<ReadableStreamDefaultReader*>(reader) - ->for_author_code_)); + if (reader->IsDefaultReader()) { + // a. Repeat for each readRequest that is an element of reader. + // [[readRequests]], + HeapDeque<Member<StreamPromiseResolver>> requests; + requests.Swap(To<ReadableStreamDefaultReader>(reader)->read_requests_); + bool for_author_code = + To<ReadableStreamDefaultReader>(reader)->for_author_code_; + for (StreamPromiseResolver* promise : requests) { + // i. Resolve readRequest.[[promise]] with ! + // ReadableStreamCreateReadResult(undefined, true, reader. + // [[forAuthorCode]]). + promise->Resolve( + script_state, + CreateReadResult(script_state, + v8::Undefined(script_state->GetIsolate()), true, + for_author_code)); + } + + // b. Set reader.[[readRequests]] to an empty List. + // This is not required since we've already called Swap(). } - - // b. Set reader.[[readRequests]] to an empty List. - // This is not required since we've already called Swap(). - // 6. Resolve reader.[[closedPromise]] with undefined. reader->closed_promise_->ResolveWithUndefined(script_state); } @@ -1777,45 +1832,86 @@ ReadableStream* stream, v8::Local<v8::Value> e) { // https://streams.spec.whatwg.org/#readable-stream-error - // 2. Assert: stream.[[state]] is "readable". + // 1. Assert: stream.[[state]] is "readable". CHECK_EQ(stream->state_, kReadable); auto* isolate = script_state->GetIsolate(); - // 3. Set stream.[[state]] to "errored". + // 2. Set stream.[[state]] to "errored". stream->state_ = kErrored; - // 4. Set stream.[[storedError]] to e. + // 3. Set stream.[[storedError]] to e. stream->stored_error_.Set(isolate, e); - // 5. Let reader be stream.[[reader]]. + // 4. Let reader be stream.[[reader]]. ReadableStreamGenericReader* reader = stream->reader_; - // 6. If reader is undefined, return. + // 5. If reader is undefined, return. if (!reader) { return; } - // 7. If ! IsReadableStreamDefaultReader(reader) is true, - // TODO(ricea): Support BYOB readers. + // 6. If ! IsReadableStreamDefaultReader(reader) is true, // a. Repeat for each readRequest that is an element of reader. // [[readRequests]], - ReadableStreamDefaultReader* default_reader = - static_cast<ReadableStreamDefaultReader*>(reader); - for (StreamPromiseResolver* promise : default_reader->read_requests_) { - // i. Reject readRequest.[[promise]] with e. - promise->Reject(script_state, e); + if (reader->IsDefaultReader()) { + ReadableStreamDefaultReader* default_reader = + To<ReadableStreamDefaultReader>(reader); + for (StreamPromiseResolver* promise : default_reader->read_requests_) { + // i. Reject readRequest.[[promise]] with e. + promise->Reject(script_state, e); + } + + // b. Set reader.[[readRequests]] to a new empty List. + default_reader->read_requests_.clear(); } - // b. Set reader.[[readRequests]] to a new empty List. - default_reader->read_requests_.clear(); + // 7. Otherwise, + else { + // a. Assert: reader implements ReadableStreamBYOBReader. + DCHECK(reader->IsBYOBReader()); + // b. For each readIntoRequest of reader.[[readIntoRequests]], + ReadableStreamBYOBReader* byob_reader = + To<ReadableStreamBYOBReader>(reader); + for (ReadableStreamBYOBReader::ReadIntoRequest* request : + byob_reader->read_into_requests_) { + // i. Perform readIntoRequests' error steps, given e. + request->ErrorSteps(script_state, e); + } + // c. Set reader.[[readIntoRequests]] to a new empty list. + byob_reader->read_into_requests_.clear(); + } - // 9. Reject reader.[[closedPromise]] with e. + // 8. Reject reader.[[closedPromise]] with e. reader->closed_promise_->Reject(script_state, e); - // 10. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true. + // 9. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true. reader->closed_promise_->MarkAsHandled(isolate); } +void ReadableStream::FulfillReadIntoRequest(ScriptState* script_state, + ReadableStream* stream, + DOMArrayBufferView* chunk, + bool done) { + // https://streams.spec.whatwg.org/#readable-stream-fulfill-read-into-request + // 1. Let reader be stream.[[reader]]. + ReadableStreamGenericReader* reader = stream->reader_; + ReadableStreamBYOBReader* byob_reader = To<ReadableStreamBYOBReader>(reader); + // 2. Assert: reader.[[readIntoRequests]] is not empty. + DCHECK(!byob_reader->read_into_requests_.IsEmpty()); + // 3. Let readIntoRequest be reader.[[readIntoRequests]][0]. + ReadableStreamBYOBReader::ReadIntoRequest* read_into_request = + byob_reader->read_into_requests_[0]; + // 4. Remove readIntoRequest from reader.[[readIntoRequests]]. + byob_reader->read_into_requests_.pop_front(); + // 5. If done is true, perform readIntoRequest’s close steps, given chunk. + if (done) { + read_into_request->CloseSteps(script_state, chunk); + } else { + // 6. Otherwise, perform readIntoRequest’s chunk steps, given chunk. + read_into_request->ChunkSteps(script_state, chunk); + } +} + void ReadableStream::FulfillReadRequest(ScriptState* script_state, ReadableStream* stream, v8::Local<v8::Value> chunk, @@ -1824,7 +1920,7 @@ // 1. Let reader be stream.[[reader]]. ReadableStreamGenericReader* reader = stream->reader_; ReadableStreamDefaultReader* default_reader = - static_cast<ReadableStreamDefaultReader*>(reader); + To<ReadableStreamDefaultReader>(reader); // 2. Let readRequest be the first element of reader.[[readRequests]]. StreamPromiseResolver* read_request = default_reader->read_requests_.front(); @@ -1841,12 +1937,48 @@ default_reader->for_author_code_)); } +int ReadableStream::GetNumReadIntoRequests(const ReadableStream* stream) { + // https://streams.spec.whatwg.org/#readable-stream-get-num-read-into-requests + // 1. Return stream.[[reader]].[[readIntoRequests]]'s size. + ReadableStreamGenericReader* reader = stream->reader_; + return To<ReadableStreamBYOBReader>(reader)->read_into_requests_.size(); +} + int ReadableStream::GetNumReadRequests(const ReadableStream* stream) { // https://streams.spec.whatwg.org/#readable-stream-get-num-read-requests // 1. Return the number of elements in stream.[[reader]].[[readRequests]]. ReadableStreamGenericReader* reader = stream->reader_; - return static_cast<ReadableStreamDefaultReader*>(reader) - ->read_requests_.size(); + return To<ReadableStreamDefaultReader>(reader)->read_requests_.size(); +} + +bool ReadableStream::HasBYOBReader(const ReadableStream* stream) { + // https://streams.spec.whatwg.org/#readable-stream-has-byob-reader + // 1. Let reader be stream.[[reader]]. + ReadableStreamGenericReader* reader = stream->reader_; + + // 2. If reader is undefined, return false. + if (!reader) { + return false; + } + + // 3. If reader implements ReadableStreamBYOBReader, return true. + // 4. Return false. + return reader->IsBYOBReader(); +} + +bool ReadableStream::HasDefaultReader(const ReadableStream* stream) { + // https://streams.spec.whatwg.org/#readable-stream-has-default-reader + // 1. Let reader be stream.[[reader]]. + ReadableStreamGenericReader* reader = stream->reader_; + + // 2. If reader is undefined, return false. + if (!reader) { + return false; + } + + // 3. If reader implements ReadableStreamDefaultReader, return true. + // 4. Return false. + return reader->IsDefaultReader(); } //
diff --git a/third_party/blink/renderer/core/streams/readable_stream.h b/third_party/blink/renderer/core/streams/readable_stream.h index f64038c..7bf0f04 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.h +++ b/third_party/blink/renderer/core/streams/readable_stream.h
@@ -10,6 +10,7 @@ #include "base/optional.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/core/streams/readable_stream_byob_reader.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_reader.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" @@ -21,6 +22,8 @@ class AbortSignal; class ExceptionState; class MessagePort; +class ReadableByteStreamController; +class ReadableStreamController; class ReadableStreamDefaultController; class ReadableStreamDefaultReaderOrReadableStreamBYOBReader; class ReadableStreamGetReaderOptions; @@ -211,6 +214,11 @@ bool for_author_code, ExceptionState&); + // https://streams.spec.whatwg.org/#acquire-readable-stream-byob-reader + static ReadableStreamBYOBReader* AcquireBYOBReader(ScriptState*, + ReadableStream*, + ExceptionState&); + // // Functions exported for use by TransformStream. Not part of the standard. // @@ -227,7 +235,7 @@ return stream->state_ == kErrored; } - ReadableStreamDefaultController* GetController() { + ReadableStreamController* GetController() { return readable_stream_controller_; } @@ -239,6 +247,8 @@ void Trace(Visitor*) const override; private: + friend class ReadableByteStreamController; + friend class ReadableStreamBYOBReader; friend class ReadableStreamDefaultController; friend class ReadableStreamDefaultReader; friend class ReadableStreamGenericReader; @@ -257,6 +267,10 @@ // https://streams.spec.whatwg.org/#initialize-readable-stream static void Initialize(ReadableStream*); + static void AddReadIntoRequest(ScriptState*, + ReadableStream*, + ReadableStreamBYOBReader::ReadIntoRequest*); + // https://streams.spec.whatwg.org/#readable-stream-add-read-request static StreamPromiseResolver* AddReadRequest(ScriptState*, ReadableStream*); @@ -277,15 +291,30 @@ // https://streams.spec.whatwg.org/#readable-stream-error static void Error(ScriptState*, ReadableStream*, v8::Local<v8::Value> e); + // https://streams.spec.whatwg.org/#readable-stream-fulfill-read-into-request + static void FulfillReadIntoRequest(ScriptState*, + ReadableStream*, + DOMArrayBufferView* chunk, + bool done); + // https://streams.spec.whatwg.org/#readable-stream-fulfill-read-request static void FulfillReadRequest(ScriptState*, ReadableStream*, v8::Local<v8::Value> chunk, bool done); + // https://streams.spec.whatwg.org/#readable-stream-get-num-read-into-requests + static int GetNumReadIntoRequests(const ReadableStream*); + // https://streams.spec.whatwg.org/#readable-stream-get-num-read-requests static int GetNumReadRequests(const ReadableStream*); + // https://streams.spec.whatwg.org/#readable-stream-has-byob-reader + static bool HasBYOBReader(const ReadableStream*); + + // https://streams.spec.whatwg.org/#readable-stream-has-default-reader + static bool HasDefaultReader(const ReadableStream*); + // // TODO(ricea): Functions for transferable streams. // @@ -299,7 +328,7 @@ bool is_disturbed_ = false; State state_ = kReadable; - Member<ReadableStreamDefaultController> readable_stream_controller_; + Member<ReadableStreamController> readable_stream_controller_; Member<ReadableStreamGenericReader> reader_; TraceWrapperV8Reference<v8::Value> stored_error_; std::unique_ptr<ReadableStreamTransferringOptimizer> transferring_optimizer_;
diff --git a/third_party/blink/renderer/core/streams/readable_stream.idl b/third_party/blink/renderer/core/streams/readable_stream.idl index acb9cdf..b0bb862 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.idl +++ b/third_party/blink/renderer/core/streams/readable_stream.idl
@@ -4,8 +4,10 @@ // https://streams.spec.whatwg.org/#rs-class typedef (ReadableStreamDefaultReader or ReadableStreamBYOBReader) ReadableStreamReader; +typedef (ReadableStreamDefaultController or ReadableByteStreamController) ReadableStreamController; enum ReadableStreamReaderMode { "byob" }; +enum ReadableStreamType { "bytes" }; [ Exposed=(Window,Worker,Worklet)
diff --git a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.cc b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.cc index f801a0d..1dba45d 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.cc
@@ -5,28 +5,64 @@ #include "third_party/blink/renderer/core/streams/readable_stream_byob_reader.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" +#include "third_party/blink/renderer/core/streams/readable_stream_controller.h" #include "third_party/blink/renderer/core/streams/stream_promise_resolver.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/bindings/to_v8.h" #include "third_party/blink/renderer/platform/bindings/v8_binding.h" namespace blink { +ReadableStreamBYOBReader::ReadIntoRequest::ReadIntoRequest( + StreamPromiseResolver* resolver) + : resolver_(resolver) {} + +void ReadableStreamBYOBReader::ReadIntoRequest::ChunkSteps( + ScriptState* script_state, + DOMArrayBufferView* chunk) const { + resolver_->Resolve(script_state, + ReadableStream::CreateReadResult( + script_state, ToV8(chunk, script_state), false, true)); +} + +void ReadableStreamBYOBReader::ReadIntoRequest::CloseSteps( + ScriptState* script_state, + DOMArrayBufferView* chunk) const { + resolver_->Resolve(script_state, + ReadableStream::CreateReadResult( + script_state, ToV8(chunk, script_state), true, true)); +} + +void ReadableStreamBYOBReader::ReadIntoRequest::ErrorSteps( + ScriptState* script_state, + v8::Local<v8::Value> e) const { + resolver_->Reject(script_state, e); +} + +void ReadableStreamBYOBReader::ReadIntoRequest::Trace(Visitor* visitor) const { + visitor->Trace(resolver_); +} + ReadableStreamBYOBReader* ReadableStreamBYOBReader::Create( ScriptState* script_state, ReadableStream* stream, ExceptionState& exception_state) { - ThrowUnimplemented(exception_state); - return nullptr; + auto* reader = MakeGarbageCollected<ReadableStreamBYOBReader>( + script_state, stream, exception_state); + if (exception_state.HadException()) { + return nullptr; + } + return reader; } ReadableStreamBYOBReader::ReadableStreamBYOBReader( ScriptState* script_state, ReadableStream* stream, ExceptionState& exception_state) { - ThrowUnimplemented(exception_state); - return; + SetUpBYOBReader(script_state, this, stream, exception_state); } ReadableStreamBYOBReader::~ReadableStreamBYOBReader() = default; @@ -34,26 +70,135 @@ ScriptPromise ReadableStreamBYOBReader::read(ScriptState* script_state, NotShared<DOMArrayBufferView> view, ExceptionState& exception_state) { - return RejectUnimplemented(script_state); + // https://streams.spec.whatwg.org/#byob-reader-read + // 1. If view.[[ByteLength]] is 0, return a promise rejected with a TypeError + // exception. + if (view->byteLength() == 0) { + exception_state.ThrowTypeError( + "This readable stream reader cannot be used to read as the view has " + "byte length equal to 0"); + return ScriptPromise(); + } + + // 2. If view.[[ViewedArrayBuffer]].[[ArrayBufferByteLength]] is 0, return a + // promise rejected with a TypeError exception. + if (view->buffer()->ByteLength() == 0) { + exception_state.ThrowTypeError( + "This readable stream reader cannot be used to read as the viewed " + "array buffer has 0 byte length"); + return ScriptPromise(); + } + + // 3. If this.[[stream]] is undefined, return a promise rejected with a + // TypeError exception. + if (!owner_readable_stream_) { + exception_state.ThrowTypeError( + "This readable stream reader has been released and cannot be used to " + "read from its previous owner stream"); + return ScriptPromise(); + } + + // 4. Let promise be a new promise. + auto* promise = MakeGarbageCollected<StreamPromiseResolver>(script_state); + + // 5. Let readIntoRequest be a new read-into request with the following items: + // chunk steps, given chunk + // 1. Resolve promise with «[ "value" → chunk, "done" → false ]». + // close steps, given chunk + // 1. Resolve promise with «[ "value" → chunk, "done" → true ]». + // error steps, given e + // 1. Reject promise with e. + auto* read_into_request = MakeGarbageCollected<ReadIntoRequest>(promise); + + // 6. Perform ! ReadableStreamBYOBReaderRead(this, view, readIntoRequest). + Read(script_state, this, view, read_into_request, exception_state); + // 7. Return promise. + return promise->GetScriptPromise(script_state); +} + +void ReadableStreamBYOBReader::Read(ScriptState* script_state, + ReadableStreamBYOBReader* reader, + NotShared<DOMArrayBufferView> view, + ReadIntoRequest* read_into_request, + ExceptionState& exception_state) { + // https://streams.spec.whatwg.org/#readable-stream-byob-reader-read + // 1. Let stream be reader.[[stream]]. + ReadableStream* stream = reader->owner_readable_stream_; + + // 2. Assert: stream is not undefined. + DCHECK(stream); + + // 3. Set stream.[[disturbed]] to true. + stream->is_disturbed_ = true; + + // 4. If stream.[[state]] is "errored", perform readIntoRequest's error steps + // given stream.[[storedError]]. + if (stream->state_ == ReadableStream::kErrored) { + read_into_request->ErrorSteps( + script_state, stream->GetStoredError(script_state->GetIsolate())); + } else { + // 5. Otherwise, perform ! + // ReadableByteStreamControllerPullInto(stream.[[controller]], view, + // readIntoRequest). + ReadableStreamController* controller = stream->readable_stream_controller_; + ReadableByteStreamController::PullInto( + script_state, To<ReadableByteStreamController>(controller), view, + read_into_request, exception_state); + } } void ReadableStreamBYOBReader::releaseLock(ScriptState* script_state, ExceptionState& exception_state) { - ThrowUnimplemented(exception_state); - return; + // https://streams.spec.whatwg.org/#byob-reader-release-lock + // 1. If this.[[stream]] is undefined, return. + if (!owner_readable_stream_) { + return; + } + + // 2. If this.[[readIntoRequests]] is not empty, throw a TypeError exception. + if (read_into_requests_.size() > 0) { + exception_state.ThrowTypeError( + "Cannot release a readable stream reader when it still has outstanding " + "read() calls that have not yet settled"); + return; + } + + // 3. Perform ! ReadableStreamReaderGenericRelease(this). + GenericRelease(script_state, this); } -void ReadableStreamBYOBReader::ThrowUnimplemented( +void ReadableStreamBYOBReader::SetUpBYOBReader( + ScriptState* script_state, + ReadableStreamBYOBReader* reader, + ReadableStream* stream, ExceptionState& exception_state) { - exception_state.ThrowTypeError("unimplemented"); + // https://streams.spec.whatwg.org/#set-up-readable-stream-byob-reader + // If ! IsReadableStreamLocked(stream) is true, throw a TypeError exception. + if (ReadableStream::IsLocked(stream)) { + exception_state.ThrowTypeError( + "ReadableStreamBYOBReader constructor can only accept readable streams " + "that are not yet locked to a reader"); + return; + } + + // If stream.[[controller]] does not implement ReadableByteStreamController, + // throw a TypeError exception. + if (!stream->readable_stream_controller_->IsByteStreamController()) { + exception_state.ThrowTypeError( + "Cannot use a BYOB reader with a non-byte stream"); + return; + } + + // Perform ! ReadableStreamReaderGenericInitialize(reader, stream). + ReadableStreamGenericReader::GenericInitialize(script_state, reader, stream); + + // Set reader.[[readIntoRequests]] to a new empty list. + DCHECK_EQ(reader->read_into_requests_.size(), 0u); } -ScriptPromise ReadableStreamBYOBReader::RejectUnimplemented( - ScriptState* script_state) { - return StreamPromiseResolver::CreateRejected( - script_state, v8::Exception::TypeError(V8String( - script_state->GetIsolate(), "unimplemented"))) - ->GetScriptPromise(script_state); +void ReadableStreamBYOBReader::Trace(Visitor* visitor) const { + visitor->Trace(read_into_requests_); + ReadableStreamGenericReader::Trace(visitor); } } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.h b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.h index 1d9d421..fb7ac5b 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.h +++ b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.h
@@ -9,13 +9,16 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/streams/readable_stream_generic_reader.h" #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { class ExceptionState; class ScriptPromise; class ScriptState; +class StreamPromiseResolver; class ReadableStream; class DOMArrayBufferView; @@ -34,6 +37,9 @@ ExceptionState&); ~ReadableStreamBYOBReader() override; + bool IsDefaultReader() const override { return false; } + bool IsBYOBReader() const override { return true; } + // https://streams.spec.whatwg.org/#byob-reader-read ScriptPromise read(ScriptState*, NotShared<DOMArrayBufferView> view, @@ -42,11 +48,51 @@ // https://streams.spec.whatwg.org/#byob-reader-release-lock void releaseLock(ScriptState*, ExceptionState&); + // https://streams.spec.whatwg.org/#set-up-readable-stream-byob-reader + static void SetUpBYOBReader(ScriptState*, + ReadableStreamBYOBReader* reader, + ReadableStream* stream, + ExceptionState&); + + void Trace(Visitor*) const override; + private: + friend class ReadableByteStreamController; friend class ReadableStream; - static void ThrowUnimplemented(ExceptionState&); - static ScriptPromise RejectUnimplemented(ScriptState*); + + class ReadIntoRequest : public GarbageCollected<ReadIntoRequest> { + public: + explicit ReadIntoRequest(StreamPromiseResolver* resolver); + + void ChunkSteps(ScriptState*, DOMArrayBufferView* chunk) const; + void CloseSteps(ScriptState*, DOMArrayBufferView* chunk) const; + void ErrorSteps(ScriptState*, v8::Local<v8::Value> e) const; + + void Trace(Visitor*) const; + + private: + friend class ReadableStream; + + Member<StreamPromiseResolver> resolver_; + }; + + // https://streams.spec.whatwg.org/#readable-stream-byob-reader-read + static void Read(ScriptState*, + ReadableStreamBYOBReader*, + NotShared<DOMArrayBufferView> view, + ReadIntoRequest*, + ExceptionState&); + + HeapDeque<Member<ReadIntoRequest>> read_into_requests_; }; + +template <> +struct DowncastTraits<ReadableStreamBYOBReader> { + static bool AllowFrom(const ReadableStreamGenericReader& reader) { + return reader.IsBYOBReader(); + } +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_BYOB_READER_H_
diff --git a/third_party/blink/renderer/core/streams/readable_stream_byob_request.cc b/third_party/blink/renderer/core/streams/readable_stream_byob_request.cc index 86bf059..3c446df6 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_byob_request.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_byob_request.cc
@@ -11,30 +11,77 @@ namespace blink { +ReadableStreamBYOBRequest::ReadableStreamBYOBRequest( + ReadableByteStreamController* controller, + NotShared<DOMUint8Array> view) + : controller_(controller), view_(view) {} + NotShared<DOMArrayBufferView> ReadableStreamBYOBRequest::view( ExceptionState& exception_state) const { - ThrowUnimplemented(exception_state); - return NotShared<DOMArrayBufferView>(); + // https://streams.spec.whatwg.org/#rs-byob-request-view + // 1. Return this.[[view]]. + return view_; } void ReadableStreamBYOBRequest::respond(ScriptState* script_state, - uint64_t bytesWritten, + uint64_t bytes_written, ExceptionState& exception_state) { - ThrowUnimplemented(exception_state); - return; + // https://streams.spec.whatwg.org/#rs-byob-request-respond + // 1. If this.[[controller]] is undefined, throw a TypeError exception. + if (!controller_) { + exception_state.ThrowTypeError( + "Cannot respond to an invalidated ReadableStreamBYOBRequest"); + return; + } + // 2. If IsDetachedBuffer(this.[[view]].[[ArrayBuffer]]) is true, throw a + // TypeError exception. + if (view_->buffer()->IsDetached()) { + exception_state.ThrowTypeError("ArrayBufferView is detached"); + return; + } + // 3. Assert: this.[[view]].[[ByteLength]] > 0. + DCHECK_GT(view_->byteLength(), 0u); + // 4. Assert: this.[[view]].[[ViewedArrayBuffer]].[[ByteLength]] > 0. + DCHECK_GT(view_->buffer()->ByteLength(), 0.0); + // 5. Perform ? ReadableByteStreamControllerRespond(this.[[controller]], + // bytesWritten). + ReadableByteStreamController::Respond(script_state, controller_, + static_cast<size_t>(bytes_written), + exception_state); } void ReadableStreamBYOBRequest::respondWithNewView( ScriptState* script_state, NotShared<DOMArrayBufferView> view, ExceptionState& exception_state) { - ThrowUnimplemented(exception_state); - return; + // https://streams.spec.whatwg.org/#rs-byob-request-respond-with-new-view + // 1. If view.[[ByteLength]] is 0, throw a TypeError exception. + if (view->byteLength() == 0) { + exception_state.ThrowTypeError("ArrayBufferView is empty"); + return; + } + // 2. If view.[[ViewedArrayBuffer]].[[ArrayBufferByteLength]] is 0, throw a + // TypeError exception. + if (view->buffer()->ByteLength() == 0) { + exception_state.ThrowTypeError("ArrayBuffer is empty"); + return; + } + // 3. If this.[[controller]] is undefined, throw a TypeError exception. + if (!controller_) { + exception_state.ThrowTypeError( + "Cannot respond to an invalidated ReadableStreamBYOBRequest"); + return; + } + // 4. Return ? + // ReadableByteStreamControllerRespondWithNewView(this.[[controller]], view). + ReadableByteStreamController::RespondWithNewView(script_state, controller_, + view, exception_state); } -void ReadableStreamBYOBRequest::ThrowUnimplemented( - ExceptionState& exception_state) { - exception_state.ThrowTypeError("unimplemented"); +void ReadableStreamBYOBRequest::Trace(Visitor* visitor) const { + visitor->Trace(controller_); + visitor->Trace(view_); + ScriptWrappable::Trace(visitor); } } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream_byob_request.h b/third_party/blink/renderer/core/streams/readable_stream_byob_request.h index 7f65ecaf..16304775 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_byob_request.h +++ b/third_party/blink/renderer/core/streams/readable_stream_byob_request.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_BYOB_REQUEST_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_BYOB_REQUEST_H_ +#include "third_party/blink/renderer/core/streams/readable_byte_stream_controller.h" #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -18,19 +19,27 @@ DEFINE_WRAPPERTYPEINFO(); public: + ReadableStreamBYOBRequest(ReadableByteStreamController*, + NotShared<DOMUint8Array> view); + // https://streams.spec.whatwg.org/#rs-byob-request-view NotShared<DOMArrayBufferView> view(ExceptionState&) const; // https://streams.spec.whatwg.org/#rs-byob-request-respond - void respond(ScriptState*, uint64_t bytesWritten, ExceptionState&); + void respond(ScriptState*, uint64_t bytes_written, ExceptionState&); // https://streams.spec.whatwg.org/#rs-byob-request-respond-with-new-view void respondWithNewView(ScriptState*, NotShared<DOMArrayBufferView> view, ExceptionState&); + void Trace(Visitor*) const override; + private: - static void ThrowUnimplemented(ExceptionState&); + friend class ReadableByteStreamController; + + Member<ReadableByteStreamController> controller_; + NotShared<DOMArrayBufferView> view_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream_controller.h b/third_party/blink/renderer/core/streams/readable_stream_controller.h index 080c33a..8ea66c0 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_controller.h +++ b/third_party/blink/renderer/core/streams/readable_stream_controller.h
@@ -15,6 +15,9 @@ class ReadableStreamController : public ScriptWrappable { public: + virtual bool IsDefaultController() const = 0; + virtual bool IsByteStreamController() const = 0; + // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamcontroller-cancelsteps virtual v8::Local<v8::Promise> CancelSteps(ScriptState*, v8::Local<v8::Value> reason) = 0;
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_controller.h b/third_party/blink/renderer/core/streams/readable_stream_default_controller.h index b96ce094..ca53eca0 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_default_controller.h +++ b/third_party/blink/renderer/core/streams/readable_stream_default_controller.h
@@ -7,6 +7,7 @@ #include "base/optional.h" #include "third_party/blink/renderer/core/streams/readable_stream_controller.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" #include "v8/include/v8.h" namespace blink { @@ -70,6 +71,9 @@ static const char* EnqueueExceptionMessage( const ReadableStreamDefaultController*); + bool IsDefaultController() const override { return true; } + bool IsByteStreamController() const override { return false; } + void Trace(Visitor*) const override; // https://streams.spec.whatwg.org/#rs-default-controller-private-cancel @@ -125,6 +129,13 @@ Member<StrategySizeAlgorithm> strategy_size_algorithm_; }; +template <> +struct DowncastTraits<ReadableStreamDefaultController> { + static bool AllowFrom(const ReadableStreamController& controller) { + return controller.IsDefaultController(); + } +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_DEFAULT_CONTROLLER_H_
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_reader.h b/third_party/blink/renderer/core/streams/readable_stream_default_reader.h index ea1f52e..5ab9f59 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_default_reader.h +++ b/third_party/blink/renderer/core/streams/readable_stream_default_reader.h
@@ -8,8 +8,10 @@ #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/execution_context/execution_context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/streams/readable_byte_stream_controller.h" #include "third_party/blink/renderer/core/streams/readable_stream_generic_reader.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -36,6 +38,9 @@ ExceptionState&); ~ReadableStreamDefaultReader() override; + bool IsDefaultReader() const override { return true; } + bool IsBYOBReader() const override { return false; } + // https://streams.spec.whatwg.org/#default-reader-read ScriptPromise read(ScriptState*, ExceptionState&); @@ -60,6 +65,7 @@ bool HasPendingActivity() const final; private: + friend class ReadableByteStreamController; friend class ReadableStreamDefaultController; friend class ReadableStream; @@ -67,6 +73,13 @@ bool for_author_code_ = true; }; +template <> +struct DowncastTraits<ReadableStreamDefaultReader> { + static bool AllowFrom(const ReadableStreamGenericReader& reader) { + return reader.IsDefaultReader(); + } +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_DEFAULT_READER_H_
diff --git a/third_party/blink/renderer/core/streams/readable_stream_generic_reader.h b/third_party/blink/renderer/core/streams/readable_stream_generic_reader.h index 7e23844..1fe26a2b 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_generic_reader.h +++ b/third_party/blink/renderer/core/streams/readable_stream_generic_reader.h
@@ -31,6 +31,9 @@ ReadableStreamGenericReader(); ~ReadableStreamGenericReader() override; + virtual bool IsDefaultReader() const = 0; + virtual bool IsBYOBReader() const = 0; + // https://streams.spec.whatwg.org/#generic-reader-closed ScriptPromise closed(ScriptState*) const;
diff --git a/third_party/blink/renderer/core/streams/readable_stream_test.cc b/third_party/blink/renderer/core/streams/readable_stream_test.cc index 0954a00..b592509 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_test.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_test.cc
@@ -6,15 +6,18 @@ #include "base/optional.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/readable_stream_default_reader_or_readable_stream_byob_reader.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.h" #include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h" #include "third_party/blink/renderer/core/messaging/message_channel.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_reader.h" +#include "third_party/blink/renderer/core/streams/readable_stream_get_reader_options.h" #include "third_party/blink/renderer/core/streams/readable_stream_transferring_optimizer.h" #include "third_party/blink/renderer/core/streams/test_underlying_source.h" #include "third_party/blink/renderer/core/streams/underlying_source_base.h" @@ -220,6 +223,42 @@ EXPECT_TRUE(stream->IsDisturbed()); } +// Testing getReader with mode BYOB. +TEST_F(ReadableStreamTest, GetBYOBReader) { + V8TestingScope scope; + ScriptState* script_state = scope.GetScriptState(); + v8::Isolate* isolate = scope.GetIsolate(); + + ScriptValue byte_stream = + EvalWithPrintingError(&scope, "new ReadableStream({type: 'bytes'})"); + ReadableStream* stream{ + V8ReadableStream::ToImplWithTypeCheck(isolate, byte_stream.V8Value())}; + ASSERT_TRUE(stream); + + EXPECT_FALSE(stream->locked()); + EXPECT_FALSE(stream->IsLocked()); + EXPECT_FALSE(stream->IsDisturbed()); + + auto* options = ReadableStreamGetReaderOptions::Create(); + options->setMode("byob"); + + ReadableStreamDefaultReaderOrReadableStreamBYOBReader return_value; + stream->getReader(script_state, options, return_value, ASSERT_NO_EXCEPTION); + ReadableStreamBYOBReader* reader = + return_value.GetAsReadableStreamBYOBReader(); + ASSERT_TRUE(reader); + + EXPECT_TRUE(stream->locked()); + EXPECT_TRUE(stream->IsLocked()); + EXPECT_FALSE(stream->IsDisturbed()); + + NotShared<DOMArrayBufferView> view = + NotShared<DOMUint8Array>(DOMUint8Array::Create(1)); + reader->read(script_state, view, ASSERT_NO_EXCEPTION); + + EXPECT_TRUE(stream->IsDisturbed()); +} + TEST_F(ReadableStreamTest, Cancel) { V8TestingScope scope; ScriptState* script_state = scope.GetScriptState();
diff --git a/third_party/blink/renderer/core/streams/transferable_streams.cc b/third_party/blink/renderer/core/streams/transferable_streams.cc index 5c364db..eb47b5b 100644 --- a/third_party/blink/renderer/core/streams/transferable_streams.cc +++ b/third_party/blink/renderer/core/streams/transferable_streams.cc
@@ -946,7 +946,10 @@ return nullptr; } - controller_ = stream->GetController(); + // The stream is created right above, and the type of the source is not given, + // hence it is guaranteed that the controller is a + // ReadableStreamDefaultController. + controller_ = To<ReadableStreamDefaultController>(stream->GetController()); return stream; }
diff --git a/third_party/blink/renderer/core/streams/transform_stream.cc b/third_party/blink/renderer/core/streams/transform_stream.cc index 7b7706db..bd1659b 100644 --- a/third_party/blink/renderer/core/streams/transform_stream.cc +++ b/third_party/blink/renderer/core/streams/transform_stream.cc
@@ -262,6 +262,13 @@ WritableStream* writable) : readable_(readable), writable_(writable) {} +ReadableStreamDefaultController* TransformStream::GetReadableController() { + // The type of source is not given when constructing the readable stream in + // TranformStream, so it is guaranteed that the controller is a + // ReadableStreamDefaultController. + return To<ReadableStreamDefaultController>(readable_->GetController()); +} + void TransformStream::Trace(Visitor* visitor) const { visitor->Trace(backpressure_change_promise_); visitor->Trace(readable_); @@ -437,7 +444,6 @@ DCHECK_EQ(argc, 0); // https://streams.spec.whatwg.org/#transform-stream-default-sink-close-algorithm // 1. Let readable be stream.[[readable]]. - ReadableStream* readable = stream_->readable_; // 2. Let controller be stream.[[transformStreamController]]. TransformStreamDefaultController* controller = @@ -453,24 +459,24 @@ class ResolveFunction final : public PromiseHandlerWithValue { public: - ResolveFunction(ScriptState* script_state, ReadableStream* readable) - : PromiseHandlerWithValue(script_state), readable_(readable) {} + ResolveFunction(ScriptState* script_state, TransformStream* stream) + : PromiseHandlerWithValue(script_state), stream_(stream) {} v8::Local<v8::Value> CallWithLocal(v8::Local<v8::Value>) override { // 5. Return the result of transforming flushPromise with: // a. A fulfillment handler that performs the following steps: // i. If readable.[[state]] is "errored", throw // readable.[[storedError]]. - if (ReadableStream::IsErrored(readable_)) { + if (ReadableStream::IsErrored(stream_->readable_)) { // Returning a rejection is equivalent to throwing here. - return PromiseReject( - GetScriptState(), - readable_->GetStoredError(GetScriptState()->GetIsolate())); + return PromiseReject(GetScriptState(), + stream_->readable_->GetStoredError( + GetScriptState()->GetIsolate())); } // ii. Let readableController be // readable.[[readableStreamController]]. - auto* readable_controller = readable_->GetController(); + auto* readable_controller = stream_->GetReadableController(); // iii. If ! ReadableStreamDefaultControllerCanCloseOrEnqueue( // readableController) is true, perform ! @@ -485,12 +491,12 @@ } void Trace(Visitor* visitor) const override { - visitor->Trace(readable_); + visitor->Trace(stream_); PromiseHandlerWithValue::Trace(visitor); } private: - Member<ReadableStream> readable_; + Member<TransformStream> stream_; }; class RejectFunction final : public PromiseHandlerWithValue { @@ -522,7 +528,7 @@ // 5. Return the result of transforming flushPromise ... return StreamThenPromise( script_state->GetContext(), flush_promise, - MakeGarbageCollected<ResolveFunction>(script_state, readable), + MakeGarbageCollected<ResolveFunction>(script_state, stream_), MakeGarbageCollected<RejectFunction>(script_state, stream_)); } @@ -828,9 +834,8 @@ // https://streams.spec.whatwg.org/#transform-stream-error // 1. Perform ! ReadableStreamDefaultControllerError(stream.[[readable]]. // [[readableStreamController]], e). - ReadableStream* readable = stream->readable_; ReadableStreamDefaultController::Error(script_state, - readable->GetController(), e); + stream->GetReadableController(), e); // 2. Perform ! TransformStreamErrorWritableAndUnblockWrite(stream, e). ErrorWritableAndUnblockWrite(script_state, stream, e);
diff --git a/third_party/blink/renderer/core/streams/transform_stream.h b/third_party/blink/renderer/core/streams/transform_stream.h index 1db4d3c65..56f14c3 100644 --- a/third_party/blink/renderer/core/streams/transform_stream.h +++ b/third_party/blink/renderer/core/streams/transform_stream.h
@@ -15,6 +15,7 @@ class ExceptionState; class ReadableStream; +class ReadableStreamDefaultController; class ScriptState; class StrategySizeAlgorithm; class StreamAlgorithm; @@ -124,6 +125,8 @@ TransformStream*, bool backpressure); + ReadableStreamDefaultController* GetReadableController(); + // The [[backpressure]] internal slot from the standard is here called // |had_backpressure_| to conform to Blink style. The initial value is // *undefined* in the standard, but it is set to *true* by
diff --git a/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc b/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc index fc1749b..a85ce1d 100644 --- a/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc +++ b/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc
@@ -18,19 +18,29 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { TransformStreamDefaultController::TransformStreamDefaultController() = default; TransformStreamDefaultController::~TransformStreamDefaultController() = default; +ReadableStreamDefaultController* +TransformStreamDefaultController::GetDefaultController( + TransformStream* stream) { + // The TransformStreamDefaultController will always use a + // ReadableStreamDefaultController. Hence, it is safe to down-cast here. + return To<ReadableStreamDefaultController>( + stream->readable_->GetController()); +} + base::Optional<double> TransformStreamDefaultController::desiredSize() const { // https://streams.spec.whatwg.org/#ts-default-controller-desired-size // 2. Let readableController be // this.[[controlledTransformStream]].[[readable]]. // [[readableStreamController]]. const auto* readable_controller = - controlled_transform_stream_->readable_->GetController(); + GetDefaultController(controlled_transform_stream_); // 3. Return ! // ReadableStreamDefaultControllerGetDesiredSize(readableController). @@ -249,7 +259,7 @@ // 2. Let readableController be // stream.[[readable]].[[readableStreamController]]. - auto* readable_controller = stream->readable_->GetController(); + auto* readable_controller = GetDefaultController(stream); // 3. If ! // ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController) is @@ -360,7 +370,7 @@ // 2. Let readableController be // stream.[[readable]].[[readableStreamController]]. ReadableStreamDefaultController* readable_controller = - stream->readable_->GetController(); + GetDefaultController(stream); // 3. If ! // ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController) is
diff --git a/third_party/blink/renderer/core/streams/transform_stream_default_controller.h b/third_party/blink/renderer/core/streams/transform_stream_default_controller.h index f4d188b1..70130dc 100644 --- a/third_party/blink/renderer/core/streams/transform_stream_default_controller.h +++ b/third_party/blink/renderer/core/streams/transform_stream_default_controller.h
@@ -13,6 +13,7 @@ namespace blink { class ExceptionState; +class ReadableStreamDefaultController; class ScriptState; class StreamAlgorithm; class TransformStream; @@ -82,6 +83,9 @@ // https://streams.spec.whatwg.org/#transform-stream-default-controller-terminate static void Terminate(ScriptState*, TransformStreamDefaultController*); + static ReadableStreamDefaultController* GetDefaultController( + TransformStream*); + Member<TransformStream> controlled_transform_stream_; Member<StreamAlgorithm> flush_algorithm_; Member<StreamAlgorithm> transform_algorithm_;
diff --git a/third_party/blink/renderer/core/streams/underlying_source.idl b/third_party/blink/renderer/core/streams/underlying_source.idl new file mode 100644 index 0000000..dfc0184 --- /dev/null +++ b/third_party/blink/renderer/core/streams/underlying_source.idl
@@ -0,0 +1,13 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://streams.spec.whatwg.org/#dictdef-underlyingsource + +dictionary UnderlyingSource { + UnderlyingSourceStartCallback start; + UnderlyingSourcePullCallback pull; + UnderlyingSourceCancelCallback cancel; + ReadableStreamType type; + [EnforceRange] unsigned long long autoAllocateChunkSize; +};
diff --git a/third_party/blink/renderer/core/streams/underlying_source_cancel_callback.idl b/third_party/blink/renderer/core/streams/underlying_source_cancel_callback.idl new file mode 100644 index 0000000..1b671b8 --- /dev/null +++ b/third_party/blink/renderer/core/streams/underlying_source_cancel_callback.idl
@@ -0,0 +1,7 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://streams.spec.whatwg.org/#callbackdef-underlyingsourcecancelcallback + +callback UnderlyingSourceCancelCallback = Promise<void> (optional any reason);
diff --git a/third_party/blink/renderer/core/streams/underlying_source_pull_callback.idl b/third_party/blink/renderer/core/streams/underlying_source_pull_callback.idl new file mode 100644 index 0000000..9f69e86c --- /dev/null +++ b/third_party/blink/renderer/core/streams/underlying_source_pull_callback.idl
@@ -0,0 +1,7 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://streams.spec.whatwg.org/#callbackdef-underlyingsourcepullcallback + +callback UnderlyingSourcePullCallback = Promise<void> (ReadableStreamController controller);
diff --git a/third_party/blink/renderer/core/streams/underlying_source_start_callback.idl b/third_party/blink/renderer/core/streams/underlying_source_start_callback.idl new file mode 100644 index 0000000..e20a211d --- /dev/null +++ b/third_party/blink/renderer/core/streams/underlying_source_start_callback.idl
@@ -0,0 +1,7 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://streams.spec.whatwg.org/#callbackdef-underlyingsourcestartcallback + +callback UnderlyingSourceStartCallback = any (ReadableStreamController controller);
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index f8e55971..b157694 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -2653,6 +2653,8 @@ return LogicalSize(LayoutUnit(ratio.Width()), LayoutUnit(ratio.Height())); } + bool IsContainerForContainerQueries() const { return ContainsLayout(); } + private: EClear Clear() const { return ClearInternal(); } EFloat Floating() const { return FloatingInternal(); }
diff --git a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 index d728135..3d7a04a 100644 --- a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 +++ b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -1037,5 +1037,12 @@ field_group: "*", default_value: "false", }, + { + name: "DependsOnContainerQueries", + field_template: "primitive", + type_name: "bool", + field_group: "*", + default_value: "false", + }, ], }
diff --git a/third_party/blink/renderer/modules/compression/deflate_transformer.cc b/third_party/blink/renderer/modules/compression/deflate_transformer.cc index 07d96724..91a3b416 100644 --- a/third_party/blink/renderer/modules/compression/deflate_transformer.cc +++ b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
@@ -111,6 +111,10 @@ // Zlib treats this pointer as const, so this cast is safe. stream_.next_in = const_cast<uint8_t*>(start); + // enqueue() may execute JavaScript which may invalidate the input buffer. So + // accumulate all the output before calling enqueue(). + HeapVector<Member<DOMUint8Array>, 1u> buffers; + do { stream_.avail_out = out_buffer_.size(); stream_.next_out = out_buffer_.data(); @@ -120,16 +124,21 @@ wtf_size_t bytes = out_buffer_.size() - stream_.avail_out; if (bytes) { - controller->enqueue( - script_state_, - ScriptValue::From(script_state_, - DOMUint8Array::Create(out_buffer_.data(), bytes)), - exception_state); - if (exception_state.HadException()) { - return; - } + buffers.push_back(DOMUint8Array::Create(out_buffer_.data(), bytes)); } } while (stream_.avail_out == 0); + + DCHECK_EQ(stream_.avail_in, 0u); + + // JavaScript may be executed inside this loop, however it is safe because + // |buffers| is a local variable that JavaScript cannot modify. + for (DOMUint8Array* buffer : buffers) { + controller->enqueue(script_state_, ScriptValue::From(script_state_, buffer), + exception_state); + if (exception_state.HadException()) { + return; + } + } } void DeflateTransformer::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.cc b/third_party/blink/renderer/modules/compression/inflate_transformer.cc index 11ee058..fddb53b1 100644 --- a/third_party/blink/renderer/modules/compression/inflate_transformer.cc +++ b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/to_v8.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" #include "v8/include/v8.h" namespace blink { @@ -93,11 +94,15 @@ TransformStreamDefaultController* controller, ExceptionState& exception_state) { DCHECK(!was_flush_called_); + was_flush_called_ = true; Inflate(nullptr, 0u, IsFinished(true), controller, exception_state); inflateEnd(&stream_); - was_flush_called_ = true; out_buffer_.clear(); + if (exception_state.HadException()) { + return ScriptPromise(); + } + if (!reached_end_) { exception_state.ThrowTypeError("Compressed input was truncated."); } @@ -121,12 +126,22 @@ // Zlib treats this pointer as const, so this cast is safe. stream_.next_in = const_cast<uint8_t*>(start); + // enqueue() may execute JavaScript which may invalidate the input buffer. So + // accumulate all the output before calling enqueue(). + HeapVector<Member<DOMUint8Array>, 1u> buffers; + do { stream_.avail_out = out_buffer_.size(); stream_.next_out = out_buffer_.data(); const int err = inflate(&stream_, finished ? Z_FINISH : Z_NO_FLUSH); if (err != Z_OK && err != Z_STREAM_END && err != Z_BUF_ERROR) { DCHECK_NE(err, Z_STREAM_ERROR); + + EnqueueBuffers(controller, std::move(buffers), exception_state); + if (exception_state.HadException()) { + return; + } + if (err == Z_DATA_ERROR) { exception_state.ThrowTypeError( String("The compressed data was not valid: ") + stream_.msg + "."); @@ -138,25 +153,44 @@ wtf_size_t bytes = out_buffer_.size() - stream_.avail_out; if (bytes) { - controller->enqueue( - script_state_, - ScriptValue::From(script_state_, - DOMUint8Array::Create(out_buffer_.data(), bytes)), - exception_state); - if (exception_state.HadException()) { - return; - } + buffers.push_back(DOMUint8Array::Create(out_buffer_.data(), bytes)); } if (err == Z_STREAM_END) { reached_end_ = true; - if (stream_.next_in < start + length) { + const bool junk_found = stream_.avail_in > 0; + + EnqueueBuffers(controller, std::move(buffers), exception_state); + if (exception_state.HadException()) { + return; + } + + if (junk_found) { exception_state.ThrowTypeError( "Junk found after end of compressed data."); } return; } } while (stream_.avail_out == 0); + + DCHECK_EQ(stream_.avail_in, 0u); + + EnqueueBuffers(controller, std::move(buffers), exception_state); +} + +void InflateTransformer::EnqueueBuffers( + TransformStreamDefaultController* controller, + HeapVector<Member<DOMUint8Array>, 1u> buffers, + ExceptionState& exception_state) { + // JavaScript may be executed inside this loop, however it is safe because + // |buffers| is a local variable that JavaScript cannot modify. + for (DOMUint8Array* buffer : buffers) { + controller->enqueue(script_state_, ScriptValue::From(script_state_, buffer), + exception_state); + if (exception_state.HadException()) { + return; + } + } } void InflateTransformer::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.h b/third_party/blink/renderer/modules/compression/inflate_transformer.h index 390fce1..ac01659f 100644 --- a/third_party/blink/renderer/modules/compression/inflate_transformer.h +++ b/third_party/blink/renderer/modules/compression/inflate_transformer.h
@@ -41,6 +41,10 @@ TransformStreamDefaultController*, ExceptionState&); + void EnqueueBuffers(TransformStreamDefaultController*, + HeapVector<Member<DOMUint8Array>, 1u> buffers, + ExceptionState&); + Member<ScriptState> script_state_; z_stream stream_;
diff --git a/third_party/blink/renderer/modules/file_system_access/global_native_file_system.cc b/third_party/blink/renderer/modules/file_system_access/global_native_file_system.cc index 0622d1d5..10f759d 100644 --- a/third_party/blink/renderer/modules/file_system_access/global_native_file_system.cc +++ b/third_party/blink/renderer/modules/file_system_access/global_native_file_system.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/platform/network/http_parsers.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/functional.h" +#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h" namespace blink { @@ -38,14 +39,42 @@ return chr == ' ' || chr == '\n' || chr == '\t' || chr == '\r'; } -bool AddExtension(const String& extension, - Vector<String>& extensions, - ExceptionState& exception_state) { +bool IsValidSuffixCodePoint(UChar chr) { + return IsASCIIAlphanumeric(chr) || chr == '+' || chr == '.'; +} + +bool VerifyIsValidExtension(const String& extension, + ExceptionState& exception_state) { if (!extension.StartsWith(".")) { exception_state.ThrowTypeError("Extension '" + extension + "' must start with '.'."); return false; } + if (!extension.IsAllSpecialCharacters<IsValidSuffixCodePoint>()) { + exception_state.ThrowTypeError("Extension '" + extension + + "' contains invalid characters."); + return false; + } + if (extension.EndsWith(".")) { + exception_state.ThrowTypeError("Extension '" + extension + + "' must not end with '.'."); + return false; + } + if (extension.length() > 16) { + exception_state.ThrowTypeError("Extension '" + extension + + "' cannot be longer than 16 characters."); + return false; + } + + return true; +} + +bool AddExtension(const String& extension, + Vector<String>& extensions, + ExceptionState& exception_state) { + if (!VerifyIsValidExtension(extension, exception_state)) + return false; + extensions.push_back(extension.Substring(1)); return true; }
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto index 2cb47ce..6089a320 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto
@@ -5,13 +5,13 @@ syntax = "proto2"; message SanitizerConfigProto { + required string html_string = 1; + message Elements { repeated string element = 1; } - repeated string allow_elements = 1; - repeated string block_elements = 2; - repeated string drop_elements = 3; + repeated string allow_elements = 2; + repeated string block_elements = 3; + repeated string drop_elements = 4; - map<string, Elements> allow_attributes = 4; - map<string, Elements> drop_attributes = 5; - - required string html_string = 6; + map<string, Elements> allow_attributes = 5; + map<string, Elements> drop_attributes = 6; }
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm index b9bd84e..930aba4 100644 --- a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm +++ b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
@@ -171,10 +171,8 @@ DCHECK_NE(desired_family_string, FontCache::LegacySystemFontFamily()); if (desired_family_string == font_family_names::kSystemUi) { - NSFont* font = nil; - if (@available(macOS 10.11, *)) { - font = [NSFont systemFontOfSize:size weight:toFontWeight(desired_weight)]; - } + NSFont* font = [NSFont systemFontOfSize:size + weight:toFontWeight(desired_weight)]; if (desired_traits & IMPORTANT_FONT_TRAITS) font = [[NSFontManager sharedFontManager] convertFont:font toHaveTrait:desired_traits];
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac_test.mm b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac_test.mm index 0636b18..c3c3e678 100644 --- a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac_test.mm +++ b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac_test.mm
@@ -6,7 +6,6 @@ #include <AppKit/AppKit.h> -#include "base/mac/mac_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/font_family_names.h" @@ -19,21 +18,6 @@ EXPECT_TRUE([font.description containsString:substring]); } -TEST(FontMatcherMacTest, YosemiteFontWeights) { - if (!base::mac::IsOS10_10()) - return; - - TestSystemFontContainsString(FontSelectionValue(100), @"-UltraLight"); - TestSystemFontContainsString(FontSelectionValue(200), @"-Thin"); - TestSystemFontContainsString(FontSelectionValue(300), @"-Light"); - TestSystemFontContainsString(FontSelectionValue(400), @"-Regular"); - TestSystemFontContainsString(FontSelectionValue(500), @"-Medium"); - TestSystemFontContainsString(FontSelectionValue(600), @"-Bold"); - TestSystemFontContainsString(FontSelectionValue(700), @"-Bold"); - TestSystemFontContainsString(FontSelectionValue(800), @"-Heavy"); - TestSystemFontContainsString(FontSelectionValue(900), @"-Heavy"); -} - TEST(FontMatcherMacTest, NoUniqueFontMatchOnUnavailableFont) { NSFont* font = MatchUniqueFont( "ThisFontNameDoesNotExist07F444B9-4DDF-4A41-8F30-C80D4ED4CCA2", 12);
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn index 503522b0..6079edf 100644 --- a/third_party/blink/renderer/platform/heap/BUILD.gn +++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -55,6 +55,7 @@ sources = [ "blink_gc_memory_dump_provider.h", "collection_support/heap_hash_table_backing.h", + "collection_support/heap_linked_hash_set.h", "collection_support/heap_linked_stack.h", "collection_support/heap_vector_backing.h", "disallow_new_wrapper.h",
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h index 27460c3..d1bb9401 100644 --- a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h +++ b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
@@ -15,16 +15,15 @@ template <typename Table> class HeapHashTableBacking final - : public WTF::ConditionalDestructor< + : public GarbageCollected<HeapHashTableBacking<Table>>, + public WTF::ConditionalDestructor< HeapHashTableBacking<Table>, std::is_trivially_destructible<typename Table::ValueType>::value> { - DISALLOW_NEW(); - IS_GARBAGE_COLLECTED_TYPE(); - public: template <typename Backing> - static void* AllocateObject(size_t size); + static void* AllocateObject(size_t); + // Conditionally invoked via destructor. void Finalize(); }; @@ -47,10 +46,9 @@ ThreadState* state = ThreadStateFor<ThreadingTrait<Backing>::kAffinity>::GetState(); DCHECK(state->IsAllocationAllowed()); - const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(Backing); return state->Heap().AllocateOnArenaIndex( state, size, BlinkGC::kHashTableArenaIndex, GCInfoTrait<Backing>::Index(), - type_name); + WTF_HEAP_PROFILER_TYPE_NAME(Backing)); } template <typename Table>
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h b/third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h new file mode 100644 index 0000000..7e9b074 --- /dev/null +++ b/third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h
@@ -0,0 +1,41 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_LINKED_HASH_SET_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_LINKED_HASH_SET_H_ + +#include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h" +#include "third_party/blink/renderer/platform/wtf/type_traits.h" + +namespace blink { + +template <typename ValueArg, typename TraitsArg = HashTraits<ValueArg>> +class HeapLinkedHashSet final + : public GarbageCollected<HeapLinkedHashSet<ValueArg, TraitsArg>>, + public LinkedHashSet<ValueArg, TraitsArg, HeapAllocator> { + static void CheckType() { + static_assert(WTF::IsMemberOrWeakMemberType<ValueArg>::value, + "HeapLinkedHashSet supports only Member and WeakMember."); + // If not trivially destructible, we have to add a destructor which will + // hinder performance. + static_assert(std::is_trivially_destructible<HeapLinkedHashSet>::value, + "HeapLinkedHashSet must be trivially destructible."); + static_assert(WTF::IsTraceable<ValueArg>::value, + "For sets without traceable elements, use LinkedHashSet<> " + "instead of HeapLinkedHashSet<>."); + } + + public: + HeapLinkedHashSet() = default; + + void Trace(Visitor* v) const { + CheckType(); + LinkedHashSet<ValueArg, TraitsArg, HeapAllocator>::Trace(v); + } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_LINKED_HASH_SET_H_
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h b/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h index 407d705..051dc07 100644 --- a/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h +++ b/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h
@@ -47,12 +47,7 @@ template <typename T> class HeapLinkedStack final : public GarbageCollected<HeapLinkedStack<T>> { public: - static void CheckType() { - static_assert(internal::IsMember<T>, - "HeapLinkedStack supports only Member."); - } - - HeapLinkedStack() { CheckType(); } + HeapLinkedStack() = default; inline size_t size() const; inline bool IsEmpty() const; @@ -61,7 +56,10 @@ inline const T& Peek() const; inline void Pop(); - void Trace(Visitor* visitor) const { visitor->Trace(head_); } + void Trace(Visitor* visitor) const { + CheckType(); + visitor->Trace(head_); + } private: class Node final : public GarbageCollected<Node> { @@ -77,6 +75,11 @@ Member<Node> next_; }; + static void CheckType() { + static_assert(internal::IsMember<T>, + "HeapLinkedStack supports only Member."); + } + Member<Node> head_; size_t size_ = 0; };
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h b/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h index 12b72b7..b75d0fc 100644 --- a/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h +++ b/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
@@ -20,27 +20,28 @@ template <typename T, typename Traits = WTF::VectorTraits<T>> class HeapVectorBacking final - : public WTF::ConditionalDestructor<HeapVectorBacking<T, Traits>, + : public GarbageCollected<HeapVectorBacking<T, Traits>>, + public WTF::ConditionalDestructor<HeapVectorBacking<T, Traits>, !Traits::kNeedsDestruction> { - DISALLOW_NEW(); - IS_GARBAGE_COLLECTED_TYPE(); - public: template <typename Backing> - static void* AllocateObject(size_t size) { - ThreadState* state = - ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); - DCHECK(state->IsAllocationAllowed()); - const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(Backing); - return state->Heap().AllocateOnArenaIndex( - state, size, BlinkGC::kVectorArenaIndex, GCInfoTrait<Backing>::Index(), - type_name); - } + static void* AllocateObject(size_t); // Conditionally invoked via destructor. void Finalize(); }; +// static +template <typename T, typename Traits> +template <typename Backing> +void* HeapVectorBacking<T, Traits>::AllocateObject(size_t size) { + ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); + DCHECK(state->IsAllocationAllowed()); + return state->Heap().AllocateOnArenaIndex( + state, size, BlinkGC::kVectorArenaIndex, GCInfoTrait<Backing>::Index(), + WTF_HEAP_PROFILER_TYPE_NAME(Backing)); +} + template <typename T, typename Traits> void HeapVectorBacking<T, Traits>::Finalize() { static_assert(Traits::kNeedsDestruction,
diff --git a/third_party/blink/renderer/platform/heap/impl/heap.h b/third_party/blink/renderer/platform/heap/impl/heap.h index f1740aaa..8da725d 100644 --- a/third_party/blink/renderer/platform/heap/impl/heap.h +++ b/third_party/blink/renderer/platform/heap/impl/heap.h
@@ -538,8 +538,6 @@ using GCInfoFoldedType = typename GCInfoFolded<Derived>::Type; GarbageCollected() = default; - - DISALLOW_COPY_AND_ASSIGN(GarbageCollected); }; // Used for passing custom sizes to MakeGarbageCollected.
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_allocator.h b/third_party/blink/renderer/platform/heap/impl/heap_allocator.h index 36013d9..6e72c47 100644 --- a/third_party/blink/renderer/platform/heap/impl/heap_allocator.h +++ b/third_party/blink/renderer/platform/heap/impl/heap_allocator.h
@@ -9,6 +9,7 @@ #include "build/build_config.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap_buildflags.h" @@ -42,22 +43,6 @@ } // namespace internal -#define DISALLOW_IN_CONTAINER() \ - public: \ - using IsDisallowedInContainerMarker = int; \ - \ - private: \ - friend class ::WTF::internal::__thisIsHereToForceASemicolonAfterThisMacro - -// IsAllowedInContainer returns true if some type T supports being nested -// arbitrarily in other containers. This is relevant for collections where some -// collections assume that they are placed on a non-moving arena. -template <typename T, typename = int> -struct IsAllowedInContainer : std::true_type {}; -template <typename T> -struct IsAllowedInContainer<T, typename T::IsDisallowedInContainerMarker> - : std::false_type {}; - // This is a static-only class used as a trait on collections to make them heap // allocated. However see also HeapListHashSetAllocator. class PLATFORM_EXPORT HeapAllocator { @@ -216,12 +201,6 @@ static_assert(std::is_trivially_destructible<HeapHashMap>::value, "HeapHashMap must be trivially destructible."); static_assert( - IsAllowedInContainer<KeyArg>::value, - "Not allowed to directly nest type. Use Member<> indirection instead."); - static_assert( - IsAllowedInContainer<MappedArg>::value, - "Not allowed to directly nest type. Use Member<> indirection instead."); - static_assert( WTF::IsTraceable<KeyArg>::value || WTF::IsTraceable<MappedArg>::value, "For hash maps without traceable elements, use HashMap<> " "instead of HeapHashMap<>."); @@ -266,9 +245,6 @@ "HeapHashSet supports only Member and WeakMember."); static_assert(std::is_trivially_destructible<HeapHashSet>::value, "HeapHashSet must be trivially destructible."); - static_assert( - IsAllowedInContainer<ValueArg>::value, - "Not allowed to directly nest type. Use Member<> indirection instead."); static_assert(WTF::IsTraceable<ValueArg>::value, "For hash sets without traceable elements, use HashSet<> " "instead of HeapHashSet<>."); @@ -288,36 +264,6 @@ struct GCInfoTrait<HeapHashSet<T, U, V>> : public GCInfoTrait<HashSet<T, U, V, HeapAllocator>> {}; -template <typename ValueArg, typename TraitsArg = HashTraits<ValueArg>> -class HeapLinkedHashSet - : public LinkedHashSet<ValueArg, TraitsArg, HeapAllocator> { - IS_GARBAGE_COLLECTED_CONTAINER_TYPE(); - DISALLOW_NEW(); - - static void CheckType() { - static_assert(WTF::IsMemberOrWeakMemberType<ValueArg>::value, - "HeapLinkedHashSet supports only Member and WeakMember."); - // If not trivially destructible, we have to add a destructor which will - // hinder performance. - static_assert(std::is_trivially_destructible<HeapLinkedHashSet>::value, - "HeapLinkedHashSet must be trivially destructible."); - static_assert( - IsAllowedInContainer<ValueArg>::value, - "Not allowed to directly nest type. Use Member<> indirection instead."); - static_assert(WTF::IsTraceable<ValueArg>::value, - "For sets without traceable elements, use LinkedHashSet<> " - "instead of HeapLinkedHashSet<>."); - } - - public: - template <typename> - static void* AllocateObject(size_t size) { - return ThreadHeap::Allocate<HeapLinkedHashSet<ValueArg, TraitsArg>>(size); - } - - HeapLinkedHashSet() { CheckType(); } -}; - } // namespace blink namespace WTF { @@ -389,10 +335,6 @@ }; }; -template <typename T, typename U> -struct GCInfoTrait<HeapLinkedHashSet<T, U>> - : public GCInfoTrait<LinkedHashSet<T, U, HeapAllocator>> {}; - template <typename ValueArg, wtf_size_t inlineCapacity = 0, // The inlineCapacity is just a dummy // to match ListHashSet (off-heap). @@ -409,9 +351,6 @@ "HeapListHashSet supports only Member and WeakMember."); static_assert(std::is_trivially_destructible<HeapListHashSet>::value, "HeapListHashSet must be trivially destructible."); - static_assert( - IsAllowedInContainer<ValueArg>::value, - "Not allowed to directly nest type. Use Member<> indirection instead."); static_assert(WTF::IsTraceable<ValueArg>::value, "For sets without traceable elements, use ListHashSet<> " "instead of HeapListHashSet<>."); @@ -445,9 +384,6 @@ "HeapHashCountedSet supports only Member and WeakMember."); static_assert(std::is_trivially_destructible<HeapHashCountedSet>::value, "HeapHashCountedSet must be trivially destructible."); - static_assert( - IsAllowedInContainer<Value>::value, - "Not allowed to directly nest type. Use Member<> indirection instead."); static_assert(WTF::IsTraceable<Value>::value, "For counted sets without traceable elements, use " "HashCountedSet<> instead of HeapHashCountedSet<>."); @@ -476,9 +412,6 @@ static_assert( std::is_trivially_destructible<HeapVector>::value || inlineCapacity, "HeapVector must be trivially destructible."); - static_assert( - IsAllowedInContainer<T>::value, - "Not allowed to directly nest type. Use Member<> indirection instead."); static_assert(WTF::IsTraceable<T>::value, "For vectors without traceable elements, use Vector<> " "instead of HeapVector<>."); @@ -527,12 +460,12 @@ return *this; } - HeapVector(HeapVector&& other) + HeapVector(HeapVector&& other) noexcept : Vector<T, inlineCapacity, HeapAllocator>(std::move(other)) { CheckType(); } - HeapVector& operator=(HeapVector&& other) { + HeapVector& operator=(HeapVector&& other) noexcept { Vector<T, inlineCapacity, HeapAllocator>::operator=(std::move(other)); return *this; } @@ -556,9 +489,6 @@ static_assert(internal::IsMember<T>, "HeapDeque supports only Member."); static_assert(std::is_trivially_destructible<HeapDeque>::value, "HeapDeque must be trivially destructible."); - static_assert( - IsAllowedInContainer<T>::value, - "Not allowed to directly nest type. Use Member<> indirection instead."); static_assert(WTF::IsTraceable<T>::value, "For vectors without traceable elements, use Deque<> instead " "of HeapDeque<>");
diff --git a/third_party/blink/renderer/platform/heap/test/concurrent_marking_test.cc b/third_party/blink/renderer/platform/heap/test/concurrent_marking_test.cc index 4f92244..aec8e7f 100644 --- a/third_party/blink/renderer/platform/heap/test/concurrent_marking_test.cc +++ b/third_party/blink/renderer/platform/heap/test/concurrent_marking_test.cc
@@ -36,6 +36,14 @@ // Tests that expose data races when modifying collections ===================== // ============================================================================= +template <typename T> +struct MethodAdapterBase { + static void Swap(T& a, T& b) { a.swap(b); } +}; + +template <typename T> +struct MethodAdapter : public MethodAdapterBase<T> {}; + template <typename C> void AddToCollection() { constexpr int kIterations = 10; @@ -135,7 +143,7 @@ new_collection->insert(MakeGarbageCollected<IntegerObject>(j)); } driver.SingleConcurrentStep(); - collection->swap(*new_collection); + MethodAdapter<C>::Swap(*collection, *new_collection); } driver.FinishSteps(); driver.FinishGC(); @@ -192,34 +200,31 @@ SwapCollections<HeapHashSet<Member<IntegerObject>>>(); } -// HeapLinkedHashSet template <typename T> -class HeapLinkedHashSetAdapter : public HeapLinkedHashSet<T> { - public: - ALWAYS_INLINE void swap(HeapLinkedHashSetAdapter<T>& other) { - HeapLinkedHashSet<T>::Swap(other); +struct MethodAdapter<HeapLinkedHashSet<T>> + : public MethodAdapterBase<HeapLinkedHashSet<T>> { + static void Swap(HeapLinkedHashSet<T>& a, HeapLinkedHashSet<T>& b) { + a.Swap(b); } }; TEST_F(ConcurrentMarkingTest, AddToLinkedHashSet) { - AddToCollection<HeapLinkedHashSetAdapter<Member<IntegerObject>>>(); + AddToCollection<HeapLinkedHashSet<Member<IntegerObject>>>(); } TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfLinkedHashSet) { - RemoveFromBeginningOfCollection< - HeapLinkedHashSetAdapter<Member<IntegerObject>>>(); + RemoveFromBeginningOfCollection<HeapLinkedHashSet<Member<IntegerObject>>>(); } TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfLinkedHashSet) { - RemoveFromMiddleOfCollection< - HeapLinkedHashSetAdapter<Member<IntegerObject>>>(); + RemoveFromMiddleOfCollection<HeapLinkedHashSet<Member<IntegerObject>>>(); } TEST_F(ConcurrentMarkingTest, RemoveFromEndOfLinkedHashSet) { - RemoveFromEndOfCollection<HeapLinkedHashSetAdapter<Member<IntegerObject>>>(); + RemoveFromEndOfCollection<HeapLinkedHashSet<Member<IntegerObject>>>(); } TEST_F(ConcurrentMarkingTest, ClearLinkedHashSet) { - ClearCollection<HeapLinkedHashSetAdapter<Member<IntegerObject>>>(); + ClearCollection<HeapLinkedHashSet<Member<IntegerObject>>>(); } TEST_F(ConcurrentMarkingTest, SwapLinkedHashSet) { - SwapCollections<HeapLinkedHashSetAdapter<Member<IntegerObject>>>(); + SwapCollections<HeapLinkedHashSet<Member<IntegerObject>>>(); } // HeapListHashSet
diff --git a/third_party/blink/renderer/platform/network/http_parsers.cc b/third_party/blink/renderer/platform/network/http_parsers.cc index 443f141f..ffde8bea 100644 --- a/third_party/blink/renderer/platform/network/http_parsers.cc +++ b/third_party/blink/renderer/platform/network/http_parsers.cc
@@ -144,6 +144,7 @@ blink::ContentSecurityPolicyPtr ConvertToBlink( ContentSecurityPolicyPtr policy_in) { return blink::ContentSecurityPolicy::New( + ConvertToBlink(std::move(policy_in->self_origin)), ConvertToBlink(std::move(policy_in->raw_directives)), ConvertToBlink(std::move(policy_in->directives)), policy_in->upgrade_insecure_requests, policy_in->treat_as_public_address,
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 33d1f48..95208ec 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -600,6 +600,10 @@ depends_on: ["PictureInPictureAPI"], }, { + name: "CSSPseudoDir", + status: "experimental", + }, + { name: "CSSPseudoIs", status: "stable", }, @@ -1648,6 +1652,7 @@ }, { name: "ReadableByteStream", + status: "experimental", }, { name: "RemotePlayback",
diff --git a/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc b/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc index 97cb4c2..e795d786 100644 --- a/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc +++ b/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc
@@ -200,19 +200,7 @@ scoped_refptr<media::VideoFrame> source_frame, scoped_refptr<blink::WebRtcVideoFrameAdapter::BufferPoolOwner> scaled_frame_pool) { - gfx::GpuMemoryBuffer* gmb = source_frame->GetGpuMemoryBuffer(); - if (!gmb || !gmb->Map()) { - return nullptr; - } - // Crop to the visible rectangle specified in |source_frame|. - const uint8_t* src_y = (reinterpret_cast<const uint8_t*>(gmb->memory(0)) + - source_frame->visible_rect().x() + - (source_frame->visible_rect().y() * gmb->stride(0))); - const uint8_t* src_uv = - (reinterpret_cast<const uint8_t*>(gmb->memory(1)) + - ((source_frame->visible_rect().x() / 2) * 2) + - ((source_frame->visible_rect().y() / 2) * gmb->stride(1))); - + auto mapped_frame = media::ConvertToMemoryMappedFrame(source_frame); // Convert to I420 and scale to the natural size specified in // |source_frame|. auto dst_frame = scaled_frame_pool->CreateFrame( @@ -220,25 +208,26 @@ gfx::Rect(source_frame->natural_size()), source_frame->natural_size(), source_frame->timestamp()); if (!dst_frame) { - gmb->Unmap(); LOG(ERROR) << "Failed to create I420 frame from pool."; return nullptr; } dst_frame->metadata()->MergeMetadataFrom(source_frame->metadata()); const auto& i420_planes = dst_frame->layout().planes(); webrtc::NV12ToI420Scaler scaler; - scaler.NV12ToI420Scale(src_y, gmb->stride(0), src_uv, gmb->stride(1), - source_frame->visible_rect().width(), - source_frame->visible_rect().height(), - dst_frame->data(media::VideoFrame::kYPlane), - i420_planes[media::VideoFrame::kYPlane].stride, - dst_frame->data(media::VideoFrame::kUPlane), - i420_planes[media::VideoFrame::kUPlane].stride, - dst_frame->data(media::VideoFrame::kVPlane), - i420_planes[media::VideoFrame::kVPlane].stride, - dst_frame->coded_size().width(), - dst_frame->coded_size().height()); - gmb->Unmap(); + scaler.NV12ToI420Scale( + mapped_frame->visible_data(media::VideoFrame::kYPlane), + mapped_frame->stride(media::VideoFrame::kYPlane), + mapped_frame->visible_data(media::VideoFrame::kUVPlane), + mapped_frame->stride(media::VideoFrame::kUVPlane), + source_frame->visible_rect().width(), + source_frame->visible_rect().height(), + dst_frame->data(media::VideoFrame::kYPlane), + i420_planes[media::VideoFrame::kYPlane].stride, + dst_frame->data(media::VideoFrame::kUPlane), + i420_planes[media::VideoFrame::kUPlane].stride, + dst_frame->data(media::VideoFrame::kVPlane), + i420_planes[media::VideoFrame::kVPlane].stride, + dst_frame->coded_size().width(), dst_frame->coded_size().height()); return dst_frame; } @@ -246,26 +235,17 @@ scoped_refptr<media::VideoFrame> source_frame, scoped_refptr<blink::WebRtcVideoFrameAdapter::BufferPoolOwner> scaled_frame_pool) { - gfx::GpuMemoryBuffer* gmb = source_frame->GetGpuMemoryBuffer(); - if (!gmb || !gmb->Map()) { - return nullptr; - } - // Crop to the visible rectangle specified in |source_frame|. - const uint8_t* src_y = (reinterpret_cast<const uint8_t*>(gmb->memory(0)) + - source_frame->visible_rect().x() + - (source_frame->visible_rect().y() * gmb->stride(0))); - const uint8_t* src_uv = - (reinterpret_cast<const uint8_t*>(gmb->memory(1)) + - ((source_frame->visible_rect().x() / 2) * 2) + - ((source_frame->visible_rect().y() / 2) * gmb->stride(1))); - + auto mapped_frame = media::ConvertToMemoryMappedFrame(source_frame); auto dst_frame = scaled_frame_pool->CreateFrame( media::PIXEL_FORMAT_NV12, source_frame->natural_size(), gfx::Rect(source_frame->natural_size()), source_frame->natural_size(), source_frame->timestamp()); dst_frame->metadata()->MergeMetadataFrom(source_frame->metadata()); const auto& nv12_planes = dst_frame->layout().planes(); - libyuv::NV12Scale(src_y, gmb->stride(0), src_uv, gmb->stride(1), + libyuv::NV12Scale(mapped_frame->visible_data(media::VideoFrame::kYPlane), + mapped_frame->stride(media::VideoFrame::kYPlane), + mapped_frame->visible_data(media::VideoFrame::kUVPlane), + mapped_frame->stride(media::VideoFrame::kUVPlane), source_frame->visible_rect().width(), source_frame->visible_rect().height(), dst_frame->data(media::VideoFrame::kYPlane), @@ -274,7 +254,6 @@ nv12_planes[media::VideoFrame::kUVPlane].stride, dst_frame->coded_size().width(), dst_frame->coded_size().height(), libyuv::kFilterBox); - gmb->Unmap(); return dst_frame; }
diff --git a/third_party/blink/tools/blinkpy/common/memoized.py b/third_party/blink/tools/blinkpy/common/memoized.py index 409b3a4..cd2dbaf 100644 --- a/third_party/blink/tools/blinkpy/common/memoized.py +++ b/third_party/blink/tools/blinkpy/common/memoized.py
@@ -52,5 +52,13 @@ # Use python "descriptor" protocol __get__ to appear # invisible during property access. def __get__(self, instance, owner): - # Return a function partial with object already bound as self. - return functools.partial(self.__call__, instance) + # Imagine we have a class, Foo, that has a @memoized method, bar(). So + # that foo.bar() works we need to bind the underlying instance via + # functools.partial, but we also want cache_clear() to work so we + # monkey-patch it on top. + wrapper = functools.partial(self.__call__, instance) + wrapper.cache_clear = self.cache_clear + return wrapper + + def cache_clear(self): + self._results_cache = {}
diff --git a/third_party/blink/tools/blinkpy/common/memoized_unittest.py b/third_party/blink/tools/blinkpy/common/memoized_unittest.py index 58273fd0..0f50270 100644 --- a/third_party/blink/tools/blinkpy/common/memoized_unittest.py +++ b/third_party/blink/tools/blinkpy/common/memoized_unittest.py
@@ -40,6 +40,11 @@ self.call_count += 1 return argument + 1 + @memoized + def memoized_subtract_one(self, argument): + self.call_count += 1 + return argument - 1 + class MemoizedTest(unittest.TestCase): def test_multiple_identical_calls(self): @@ -64,6 +69,22 @@ self.assertEqual(add_one(4), 5) self.assertEqual(test.call_count, 1) + def test_cache_clear(self): + test = _TestObject() + self.assertEqual(test.memoized_add_one(1), 2) + self.assertEqual(test.memoized_subtract_one(2), 1) + self.assertEqual(test.call_count, 2) + + # Now clear the cache of memoized_add_one. This should only clear the + # cache for that function. + test.memoized_add_one.cache_clear() + + self.assertEqual(test.memoized_subtract_one(2), 1) + self.assertEqual(test.call_count, 2) + + self.assertEqual(test.memoized_add_one(1), 2) + self.assertEqual(test.call_count, 3) + def test_non_hashable_args(self): test = _TestObject() try:
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer.py b/third_party/blink/tools/blinkpy/w3c/test_importer.py index 25bf0dfb..047fb81a 100644 --- a/third_party/blink/tools/blinkpy/w3c/test_importer.py +++ b/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -48,7 +48,6 @@ def __init__(self, host, wpt_github=None, wpt_manifests=None): self.host = host self.wpt_github = wpt_github - self.port = host.port_factory.get() self.executive = host.executive self.fs = host.filesystem @@ -157,8 +156,9 @@ # TODO(robertma): Implement `add --all` in Git (it is different from `commit --all`). self.chromium_git.run(['add', '--all', self.dest_path]) - # Remove expectations for tests that were deleted and rename tests - # in expectations for renamed tests. + # Remove expectations for tests that were deleted and rename tests in + # expectations for renamed tests. This requires the old WPT manifest, so + # must happen before we regenerate it. self._expectations_updater.cleanup_test_expectations_files() self._generate_manifest() @@ -166,7 +166,6 @@ # TODO(crbug.com/800570 robertma): Re-enable it once we fix the bug. # self._delete_orphaned_baselines() - if not self.chromium_git.has_working_directory_changes(): _log.info('Done: no changes to import.') return 0
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py index 81d13cfa5..b1f3344 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
@@ -155,6 +155,13 @@ mapping tests that couldn't be rebaselined to lists of expectation lines written to TestExpectations. """ + # The wpt_manifest function in Port is cached by default, but may be out + # of date if this code is called during test import. An out of date + # manifest will cause us to mistreat newly added tests, as they will not + # exist in the cached manifest. To avoid this, we invalidate the cache + # here. See https://crbug.com/1154650 . + self.port.wpt_manifest.cache_clear() + issue_number = self.get_issue_number() if issue_number == 'None': raise ScriptError('No issue on current branch.') @@ -170,7 +177,9 @@ if (job_status.result == 'SUCCESS' and not self.options.include_unexpected_pass): continue + # Temporary logging for https://crbug.com/1154650 result_dicts = self.get_failing_results_dicts(build) + _log.info('Merging failing results dicts for %s', build) for result_dict in result_dicts: test_expectations = self.merge_dicts( test_expectations, result_dict) @@ -363,9 +372,14 @@ elif target[key] == source[key]: pass else: + # Temporary logging for https://crbug.com/1154650. + _log.info( + 'Error: mismatching key values in merge_dicts.\n' + 'target[key]: %s\nsource[key]: %s', target[key], + source[key]) raise ValueError( - 'The key: %s already exist in the target dictionary.' % - '.'.join(path)) + 'The key: %s already exists in the target dictionary.' + % '.'.join(path)) else: target[key] = source[key] return target
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations index 651812226..28cd6c2 100644 --- a/third_party/blink/web_tests/LeakExpectations +++ b/third_party/blink/web_tests/LeakExpectations
@@ -37,6 +37,9 @@ crbug.com/1098106 virtual/off-main-thread-css-paint/http/tests/csspaint/invalidation-background-image.html [ Crash ] crbug.com/1098106 virtual/off-main-thread-css-paint/http/tests/csspaint/invalidation-content-image.html [ Crash ] +# Random timeout +crbug.com/1151861 [ Linux ] external/wpt/workers/semantics/multiple-workers/003.html [ Timeout Crash ] + # ----------------------------------------------------------------- # Flakily leaks # -----------------------------------------------------------------
diff --git a/third_party/blink/web_tests/SmokeTests b/third_party/blink/web_tests/SmokeTests index c14f6f1..b485096 100644 --- a/third_party/blink/web_tests/SmokeTests +++ b/third_party/blink/web_tests/SmokeTests
@@ -798,7 +798,6 @@ http/tests/security/local-JavaScript-from-remote.html http/tests/security/no-javascript-refresh.php http/tests/shapes/crash-image-changed-during-layout.html -http/tests/streams/chromium/get-reader-byob.html http/tests/uri/escaped-entity.html http/tests/uri/resolve-encoding-relative.html http/tests/uri/utf8-path.html
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index b3b35de..705d9eb 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2692,7 +2692,6 @@ crbug.com/626703 [ Mac ] external/wpt/css/css-fonts/standard-font-family.html [ Failure ] crbug.com/626703 [ Mac10.13 ] external/wpt/screen-capture/getdisplaymedia.https.html [ Failure Timeout ] crbug.com/626703 [ Mac10.14 ] external/wpt/screen-capture/getdisplaymedia.https.html [ Failure Timeout ] -crbug.com/626703 external/wpt/streams/readable-byte-streams/construct-byob-request.any.sharedworker.html [ Timeout ] crbug.com/626703 [ Mac ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html [ Timeout ] crbug.com/626703 [ Win ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html [ Timeout ] crbug.com/1144104 [ Linux ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.html [ Failure ] @@ -2722,7 +2721,6 @@ crbug.com/626703 [ Win10 ] external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html [ Failure Timeout ] crbug.com/626703 [ Win ] external/wpt/web-animations/timing-model/animation-effects/phases-and-states.html [ Crash ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/snap-to-line.html [ Failure ] -crbug.com/626703 external/wpt/shadow-dom/directionality-002.tentative.html [ Failure ] crbug.com/626703 [ Mac10.13 ] external/wpt/webaudio/the-audio-api/the-mediastreamaudiosourcenode-interface/mediastreamaudiosourcenode-routing.html [ Timeout ] crbug.com/626703 [ Mac10.14 ] external/wpt/webaudio/the-audio-api/the-mediastreamaudiosourcenode-interface/mediastreamaudiosourcenode-routing.html [ Timeout ] crbug.com/626703 [ Win7 ] external/wpt/IndexedDB/structured-clone.any.html [ Timeout ] @@ -2995,8 +2993,6 @@ crbug.com/626703 external/wpt/web-animations/timing-model/timelines/update-and-send-events.html [ Failure ] crbug.com/626703 external/wpt/svg/painting/reftests/paint-context-001.svg [ Failure ] crbug.com/626703 external/wpt/svg/painting/reftests/paint-context-002.svg [ Failure ] -crbug.com/626703 external/wpt/css/css-scoping/shadow-directionality-002.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-scoping/shadow-directionality-001.tentative.html [ Failure ] crbug.com/626703 external/wpt/screen-orientation/orientation-reading.html [ Timeout ] crbug.com/626703 external/wpt/html/browsers/browsing-the-web/unloading-documents/prompt-and-unload-script-closeable.html [ Failure ] crbug.com/626703 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html?encoding=x-cp1251 [ Timeout ] @@ -4087,17 +4083,6 @@ # [css-animations] crbug.com/993365 external/wpt/css/css-transitions/Element-getAnimations.tentative.html [ Failure Pass ] -# [selectors-4] -crbug.com/576815 external/wpt/css/selectors/selectors-dir-selector-ltr-001.html [ Failure ] -crbug.com/576815 external/wpt/css/selectors/selectors-dir-selector-rtl-001.html [ Failure ] -crbug.com/576815 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-01a.html [ Failure ] -crbug.com/576815 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-01b.html [ Failure ] -crbug.com/576815 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-02a.html [ Failure ] -crbug.com/576815 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-02b.html [ Failure ] -crbug.com/576815 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-03a.html [ Failure ] -crbug.com/576815 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-03b.html [ Failure ] -crbug.com/576815 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-04.html [ Failure ] - crbug.com/664450 http/tests/devtools/console/console-on-animation-worklet.js [ Skip ] crbug.com/826419 external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-track-inband.html [ Skip ] @@ -5932,7 +5917,6 @@ crbug.com/1150475 fast/dom/open-and-close-by-DOM.html [ Pass Failure ] #Sheriff 2020-11-23 -crbug.com/1151861 external/wpt/workers/semantics/multiple-workers/003.html [ Timeout Crash ] crbug.com/1152088 [ Mac10.13 Debug ] fast/dom/cssTarget-crash.html [ Pass Timeout ] crbug.com/1149734 http/tests/devtools/sources/source-frame-toolbar-items.js [ Pass Failure ] crbug.com/1149734 http/tests/devtools/sources/debugger-frameworks/frameworks-sourcemap.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/compression/compression-with-detach.tentative.any.js b/third_party/blink/web_tests/external/wpt/compression/compression-with-detach.tentative.any.js new file mode 100644 index 0000000..786bba2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/compression/compression-with-detach.tentative.any.js
@@ -0,0 +1,55 @@ +// META: global=window,worker +// META: script=resources/concatenate-stream.js + +'use strict'; + +const kInputLength = 500000; + +function createLargeRandomInput() { + const buffer = new ArrayBuffer(kInputLength); + // The getRandomValues API will only let us get 65536 bytes at a time, so call + // it multiple times. + const kChunkSize = 65536; + for (let offset = 0; offset < kInputLength; offset += kChunkSize) { + const length = + offset + kChunkSize > kInputLength ? kInputLength - offset : kChunkSize; + const view = new Uint8Array(buffer, offset, length); + crypto.getRandomValues(view); + } + return new Uint8Array(buffer); +} + +function decompress(view) { + const ds = new DecompressionStream('deflate'); + const writer = ds.writable.getWriter(); + writer.write(view); + writer.close(); + return concatenateStream(ds.readable); +} + +promise_test(async () => { + const input = createLargeRandomInput(); + const inputCopy = input.slice(0, input.byteLength); + const cs = new CompressionStream('deflate'); + const writer = cs.writable.getWriter(); + writer.write(input); + writer.close(); + // Object.prototype.then will be looked up synchronously when the promise + // returned by read() is resolved. + Object.defineProperty(Object.prototype, 'then', { + get() { + // Cause input to become detached and unreferenced. + try { + postMessage(undefined, 'nowhere', [input.buffer]); + } catch (e) { + // It's already detached. + } + } + }); + const output = await concatenateStream(cs.readable); + // Perform the comparison as strings since this is reasonably fast even when + // JITted JavaScript is running under an emulator. + assert_equals( + inputCopy.toString(), (await decompress(output)).toString(), + 'decompressing the output should return the input'); +}, 'data should be correctly compressed even if input is detached partway');
diff --git a/third_party/blink/web_tests/external/wpt/compression/decompression-with-detach.tentative.any.js b/third_party/blink/web_tests/external/wpt/compression/decompression-with-detach.tentative.any.js new file mode 100644 index 0000000..a2f8bda0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/compression/decompression-with-detach.tentative.any.js
@@ -0,0 +1,41 @@ +// META: global=window,worker +// META: script=resources/concatenate-stream.js + +'use strict'; + +const kInputLength = 1000000; + +async function createLargeCompressedInput() { + const cs = new CompressionStream('deflate'); + // The input has to be large enough that it won't fit in a single chunk when + // decompressed. + const writer = cs.writable.getWriter(); + writer.write(new Uint8Array(kInputLength)); + writer.close(); + return concatenateStream(cs.readable); +} + +promise_test(async () => { + const input = await createLargeCompressedInput(); + const ds = new DecompressionStream('deflate'); + const writer = ds.writable.getWriter(); + writer.write(input); + writer.close(); + // Object.prototype.then will be looked up synchronously when the promise + // returned by read() is resolved. + Object.defineProperty(Object.prototype, 'then', { + get() { + // Cause input to become detached and unreferenced. + try { + postMessage(undefined, 'nowhere', [input.buffer]); + } catch (e) { + // It's already detached. + } + } + }); + const output = await concatenateStream(ds.readable); + // If output successfully decompressed and gave the right length, we can be + // reasonably confident that no data corruption happened. + assert_equals( + output.byteLength, kInputLength, 'output should be the right length'); +}, 'data should be correctly decompressed even if input is detached partway');
diff --git a/third_party/blink/web_tests/external/wpt/compression/resources/concatenate-stream.js b/third_party/blink/web_tests/external/wpt/compression/resources/concatenate-stream.js new file mode 100644 index 0000000..a35bb14 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/compression/resources/concatenate-stream.js
@@ -0,0 +1,25 @@ +'use strict'; + +// Read all the chunks from a stream that returns BufferSource objects and +// concatenate them into a single Uint8Array. +async function concatenateStream(readableStream) { + const reader = readableStream.getReader(); + let totalSize = 0; + const buffers = []; + while (true) { + const { value, done } = await reader.read(); + if (done) { + break; + } + buffers.push(value); + totalSize += value.byteLength; + } + reader.releaseLock(); + const concatenated = new Uint8Array(totalSize); + let offset = 0; + for (const buffer of buffers) { + concatenated.set(buffer, offset); + offset += buffer.byteLength; + } + return concatenated; +}
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/frame-src/frame-src-sandboxed-allowed-expected.txt b/third_party/blink/web_tests/external/wpt/content-security-policy/frame-src/frame-src-sandboxed-allowed-expected.txt deleted file mode 100644 index 1102ea6..0000000 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/frame-src/frame-src-sandboxed-allowed-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL SubframeLoaded assert_unreached: unexpected securitypolicyviolation Reached unreachable code -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scroll-anchoring/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-scroll-anchoring/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scroll-anchoring/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scroll-anchoring/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-scroll-anchoring/OWNERS index 6db7af8..c6ee3b6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-scroll-anchoring/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/css-scroll-anchoring/OWNERS
@@ -1,4 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true skobes@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shapes/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-shapes/DIR_METADATA new file mode 100644 index 0000000..815ca00 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-shapes/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout>Shape" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shapes/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-shapes/OWNERS index 45d17fb8..e8b3fc1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shapes/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/css-shapes/OWNERS
@@ -1,4 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout>Shape -# WPT-NOTIFY: true bjonesbe@adobe.com
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-sizing/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-sizing/OWNERS index 95f61b7..51c6a57d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-sizing/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/OWNERS
@@ -1,4 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true cbiesinger@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/css-syntax/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-syntax/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-syntax/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-syntax/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-syntax/OWNERS deleted file mode 100644 index e282c4f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-syntax/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-tables/DIR_METADATA new file mode 100644 index 0000000..bd468f81a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout>Table" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-tables/OWNERS index 1cc9d5b..aef437e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-tables/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/OWNERS
@@ -1,4 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout>Table -# WPT-NOTIFY: true dgrogan@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-text-decor/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-text-decor/OWNERS index 801a0f4..f196c82 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text-decor/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/OWNERS
@@ -1,4 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true drott@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-text/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-text/OWNERS deleted file mode 100644 index 9b2e5be..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-text/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/css/css-timing/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-timing/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-timing/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-timing/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-timing/OWNERS deleted file mode 100644 index e282c4f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-timing/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-transforms/DIR_METADATA new file mode 100644 index 0000000..46ba8320 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Transforms" +} +team_email: "paint-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-transforms/OWNERS deleted file mode 100644 index e090a5a..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: paint-dev@chromium.org -# COMPONENT: Blink>Transforms -# WPT-NOTIFY: true \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-typed-om/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-typed-om/OWNERS deleted file mode 100644 index e282c4f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-ui/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-ui/OWNERS index 5f43f91..5e03d9bc 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-ui/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/OWNERS
@@ -1,4 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true rego@igalia.com
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-values/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-values/OWNERS deleted file mode 100644 index e282c4f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-values/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS
diff --git a/third_party/blink/web_tests/external/wpt/css/css-variables/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-variables/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-variables/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-variables/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-variables/OWNERS deleted file mode 100644 index e282c4f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-variables/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/DIR_METADATA new file mode 100644 index 0000000..fecdb38 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout>WritingMode" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/OWNERS b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/OWNERS index d7655b1..53463b3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/OWNERS
@@ -1,4 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout>WritingMode -# WPT-NOTIFY: true kojii@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/cssom-view/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/OWNERS b/third_party/blink/web_tests/external/wpt/css/cssom-view/OWNERS deleted file mode 100644 index e282c4f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/cssom-view/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/cssom/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/cssom/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/OWNERS b/third_party/blink/web_tests/external/wpt/css/cssom/OWNERS deleted file mode 100644 index e282c4f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/cssom/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/filter-effects/DIR_METADATA new file mode 100644 index 0000000..765407c4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Paint" +} +team_email: "paint-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/OWNERS b/third_party/blink/web_tests/external/wpt/css/filter-effects/OWNERS deleted file mode 100644 index 5f3e240..0000000 --- a/third_party/blink/web_tests/external/wpt/css/filter-effects/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: paint-dev@chromium.org -# COMPONENT: Blink>Paint -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/css/geometry/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/geometry/DIR_METADATA new file mode 100644 index 0000000..f7d3bf5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/geometry/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Geometry" +} +team_email: "paint-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/geometry/OWNERS b/third_party/blink/web_tests/external/wpt/css/geometry/OWNERS index b788e32..806af33 100644 --- a/third_party/blink/web_tests/external/wpt/css/geometry/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/geometry/OWNERS
@@ -1,6 +1,3 @@ -# TEAM: paint-dev@chromium.org -# COMPONENT: Blink>Geometry -# WPT-NOTIFY: true xlai@chromium.org jinho.bang@samsung.com hs1217.lee@samsung.com
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/mediaqueries/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/OWNERS b/third_party/blink/web_tests/external/wpt/css/mediaqueries/OWNERS deleted file mode 100644 index e282c4f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/motion/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/OWNERS b/third_party/blink/web_tests/external/wpt/css/motion/OWNERS index d10225e..812e93d 100644 --- a/third_party/blink/web_tests/external/wpt/css/motion/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/motion/OWNERS
@@ -1,3 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS ericwilligers@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/selectors/DIR_METADATA new file mode 100644 index 0000000..a1cb39c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>CSS" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/OWNERS b/third_party/blink/web_tests/external/wpt/css/selectors/OWNERS index 9b25911..5e03d9bc 100644 --- a/third_party/blink/web_tests/external/wpt/css/selectors/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/selectors/OWNERS
@@ -1,3 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>CSS rego@igalia.com
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-auto.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-auto.html new file mode 100644 index 0000000..d53e989 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-auto.html
@@ -0,0 +1,93 @@ +<!doctype html> +<html> +<head> + <link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <style> + #div4_1 { + direction: rtl; + } + </style> +</head> + +<!-- ת is the Hebrew letter tav, i.e. RTL --> +<body> + <div id=testDivs> + <div id=div1 dir=auto> + <div id=div1_1>a</div> + </div> + <div id=div2 dir=auto> + <div id=div2_1>ת</div> + </div> + <div id=div3 dir=auto> + <div id=div3_1 dir=rtl>ת</div> + <div id=div3_2>a</div> + </div> + <div id=div4 dir=auto> + <div id=div4_1> + <div id=div4_1_1>a</div> + </div> + </div> + </div> +</body> + +<script> +function test_directionality(message, element, expected) { + test(() => { + var isLTR = document.querySelector("#" + element.id + ":dir(ltr)") == element; + var isRTL = document.querySelector("#" + element.id + ":dir(rtl)") == element; + if (expected == "ltr") { + assert_true(isLTR); + assert_false(isRTL); + } else { + assert_false(isLTR); + assert_true(isRTL); + } + }, message + " directionality of element " + element.id + " is " + expected); +} + +test_directionality("Initial ", div1, "ltr"); +test_directionality("Initial ", div1_1, "ltr"); +test_directionality("Initial ", div2, "rtl"); +test_directionality("Initial ", div2_1, "rtl"); +test_directionality("Initial ", div3, "ltr"); +test_directionality("Initial ", div3_1, "rtl"); +test_directionality("Initial ", div3_2, "ltr"); +test_directionality("Initial ", div4, "ltr"); +test_directionality("Initial ", div4_1, "ltr"); +test_directionality("Initial ", div4_1_1, "ltr"); + +div1_1.innerText = "\u05EA"; +div1_1.offsetTop; +test_directionality("Updated ", div1, "rtl"); +test_directionality("Updated ", div1_1, "rtl"); + +div1_1.dir = "ltr"; +div1_1.offsetTop; +test_directionality("Updated ", div1, "ltr"); +test_directionality("Updated ", div1_1, "ltr"); + +div1_1.innerText = "a"; +div1_1.offsetTop; +test_directionality("Reupdated ", div1, "ltr"); +test_directionality("Reupdated ", div1_1, "ltr"); + +div2_1.remove(); +div2.offsetTop; +test_directionality("Updated ", div2, "ltr"); + +div3_1.dir = ""; +div3_1.offsetTop; +test_directionality("Updated ", div3, "rtl"); +div3.appendChild(div3_1); +div3.offsetTop; +test_directionality("Updated ", div3, "ltr"); + +div4_1_1.innerText = "\u05EA"; +div4_1_1.offsetTop; +test_directionality("Updated ", div4, "rtl"); +test_directionality("Updated ", div4_1, "rtl"); +test_directionality("Updated ", div4_1_1, "rtl"); +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-001-ref.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-001-ref.html new file mode 100644 index 0000000..8c79c83 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-001-ref.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> + <style type="text/css"> + span { background-color: lime } + </style> +</head> +<body> + <div> + <div> + <div></div> + <span>The background color should be lime</span> + </div> + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-001.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-001.html new file mode 100644 index 0000000..f9523896 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-001.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Selectors Level 4 Test: Check for correctly updating :dir matching on dir attribute change from default(ltr) to rtl</title> + <link rel="author" title="Miyoung Shin" href="mailto:myid.shin@igalia.com"> + <link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo"> + <link rel="match" href="selectors-dir-selector-change-001-ref.html"> + <style type="text/css"> + #x:dir(rtl) + span { background-color: lime } + #outer { direction:ltr } + </style> +</head> +<body> + <div id="outer" style="-webkit-locale: 'en'"> + <div> + <div id="x"></div> + <span>The background color should be lime</span> + </div> + </div> + <script> + outer.offsetTop; + outer.setAttribute("dir", "rtl"); + </script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-002.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-002.html new file mode 100644 index 0000000..bc032b5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-002.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Selectors Level 4 Test: Check for correctly updating :dir matching on dir attribute change from default(ltr) to rtl</title> + <link rel="author" title="Miyoung Shin" href="mailto:myid.shin@igalia.com"> + <link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo"> + <link rel="match" href="../reference/ref-filled-green-100px-square.xht"> + <style type="text/css"> + div { + width: 100px; + height: 100px; + background-color: red; + } + + div:dir(rtl) { + background-color: green; + } + </style> +</head> +<body> + <p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + <div id="inner"></div> + <script> + inner.offsetTop; + inner.setAttribute("dir", "rtl"); + </script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-003-ref.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-003-ref.html new file mode 100644 index 0000000..8c79c83 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-003-ref.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> + <style type="text/css"> + span { background-color: lime } + </style> +</head> +<body> + <div> + <div> + <div></div> + <span>The background color should be lime</span> + </div> + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-003.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-003.html new file mode 100644 index 0000000..f400015 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-003.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Selectors Level 4 Test: Check for correctly updating :dir matching on dir attribute change from rtl to auto</title> + <link rel="author" title="Miyoung Shin" href="mailto:myid.shin@igalia.com"> + <link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo"> + <link rel="match" href="selectors-dir-selector-change-003-ref.html"> + <style type="text/css"> + #x:dir(ltr) + span { background-color: lime } + </style> +</head> +<body> + <div id="outer" dir="rtl"> + <div> + <div id="x"></div> + <span>The background color should be lime</span> + </div> + </div> + <script> + outer.offsetTop; + outer.setAttribute("dir", "auto"); + </script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-004-ref.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-004-ref.html new file mode 100644 index 0000000..9a130cb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-004-ref.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <style type="text/css"> + span { background-color: lime } + </style> +</head> +<body> + <div> + <div dir="rtl"> + <div></div> + <span>מקור השם עברית</span> + </div> + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-004.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-004.html new file mode 100644 index 0000000..4c76b29 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-change-004.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Selectors Level 4 Test: Check for correctly updating :dir matching on directionality change from ltr to rtl</title> + <link rel="author" title="Miyoung Shin" href="mailto:myid.shin@igalia.com"> + <link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo"> + <link rel="match" href="selectors-dir-selector-change-004-ref.html"> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <style type="text/css"> + #x:dir(rtl) + span { background-color: lime } + </style> +</head> +<body> + <div dir="auto"> + <div> + <div id="x"></div> + <span id="inner">The background color should be lime</span> + </div> + </div> + <script> + inner.offsetTop; + inner.innerHTML = "מקור השם עברית"; + </script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-ltr-002.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-ltr-002.html new file mode 100644 index 0000000..bbb3f26 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-ltr-002.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Selectors Level 4 Test: exception handling for an invalid identifier of dir()</title> + <link rel="author" title="Miyoung Shin" href="mailto:myid.shin@igalia.com"> + <link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo"> + <link rel="match" href="../reference/ref-filled-green-100px-square.xht"> + <meta name="flags" content=""> + <meta name="assert" content="The invalid identifier of :dir(ltrr) pseudo-class doesn't match an element that has a directionality of (ltr). Even if the div element has dir=ltr, the selector should not match."> + <style type="text/css"> + div { + width: 100px; + height: 100px; + background-color: green; + } + + div:dir(ltrr) { + background-color: red; + } + </style> +</head> +<body> + <p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + <div dir="ltr"></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-ltr-003.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-ltr-003.html new file mode 100644 index 0000000..821a336 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-ltr-003.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Selectors Level 4 Test: exception handling for multiple identifiers of dir() </title> + <link rel="author" title="Miyoung Shin" href="mailto:myid.shin@igalia.com"> + <link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo"> + <link rel="match" href="../reference/ref-filled-green-100px-square.xht"> + <meta name="flags" content=""> + <meta name="assert" content="The multiple identifiers of :dir(ltr, rtl) pseudo-class don't match an element that has a directionality of (ltr). Even if the div element has dir=ltr, the selector should not match."> + <style type="text/css"> + div { + width: 100px; + height: 100px; + background-color: green; + } + + div:dir(ltr, rtl) { + background-color: red; + } + </style> +</head> +<body> + <p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + <div dir="ltr"></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-querySelector.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-querySelector.html new file mode 100644 index 0000000..a05e3fe --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-querySelector.html
@@ -0,0 +1,71 @@ +<!doctype html> +<html> +<head> + <link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + <div id=outer> + <div id=div1></div> + <div id=div2 dir=ltr> + <div id=div2_1></div> + <div id=div2_2 dir=ltr></div> + <div id=div2_3 dir=rtl></div> + </div> + <div id=div3 dir=rtl> + <div id=div3_1> + <div id=div3_1_1></div> + </div> + <div id=div3_2 dir=ltr></div> + <div id=div3_3 dir=rtl></div> + </div> + <div id=div4 dir=lol></div> + <div id=div5 dir=auto></div> + </div> +</body> + +<script> +test(() => { + assert_equals(document.querySelector(":dir(lol)"), null); + assert_equals(document.querySelector(":dir(lol )"), null); + assert_equals(document.querySelector(":dir( auto)"), null); + assert_equals(document.querySelector(":dir(\nauto\t)"), null); +}, ":dir() allows any ident value but strings other than ltr/rtl don't match"); + +test(() => { + assert_throws_dom("SYNTAX_ERR", () => { document.querySelector(":dir()"); }); + assert_throws_dom("SYNTAX_ERR", () => { document.querySelector(":dir(ltr, rtl)"); }); + assert_throws_dom("SYNTAX_ERR", () => { document.querySelector(":dir('ltr')"); }); +}, ":dir() requires exactly an ident argument"); + +test(() => { + assert_equals(document.querySelector(":dir(rtl)"), div2_3); + assert_equals(document.querySelector("*:dir(rtl)"), div2_3); + assert_equals(document.querySelector("div:dir(ltr)"), outer); + assert_equals(document.querySelector("div:dir(ltr):dir(ltr)"), outer); + assert_equals(document.querySelector(":dir(rtl)#div3_3"), div3_3); + assert_equals(document.querySelector(":nth-child(2):dir(rtl)"), null); + assert_equals(document.querySelector(":nth-child(3):dir(rtl)"), div2_3); + assert_equals(document.querySelector(":nth-child(4):dir(ltr)"), div4); + assert_equals(document.querySelector(":nth-last-child(3):dir(rtl)"), div3); +}, ":dir() works in compound selectors"); + +test(() => { + assert_equals(document.querySelector("#div2 :dir(ltr)"), div2_1); + assert_equals(document.querySelector(":dir(rtl) div"), div3_1); + assert_equals(document.querySelector("div + :dir(ltr)"), div2); + assert_equals(document.querySelector(":dir(ltr) + :dir(rtl)"), div2_3); + assert_equals(document.querySelector(":dir(rtl) :dir(rtl)"), div3_1); + assert_equals(document.querySelector(":dir(rtl) + :dir(ltr)"), div3_2); + assert_equals(document.querySelector(":dir(rtl) ~ :dir(rtl)"), div3_3); + assert_equals(document.querySelector(":dir(rtl) :dir(ltr)"), div3_2); + assert_equals(document.querySelector("* :dir(rtl) *"), div3_1); + assert_equals(document.querySelector("div :dir(rtl) div"), div3_1); + assert_equals(document.querySelector(":dir(ltr) :dir(rtl) + :dir(ltr)"), div3_2); + assert_equals(document.querySelector(":dir(ltr) + :dir(rtl) + * + *"), div5); + assert_equals(document.querySelector(":dir(rtl) > * > :dir(rtl)"), div3_1_1); +}, ":dir() works in complex selectors"); +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-white-space-001-ref.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-white-space-001-ref.html new file mode 100644 index 0000000..955a2dd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-white-space-001-ref.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <style type="text/css"> + div { + width: 100px; + height: 100px; + background-color: green; + } + </style> +</head> +<body> + <p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + <div></div> + <div></div> + <div></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-white-space-001.html b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-white-space-001.html new file mode 100644 index 0000000..d3128a0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/selectors-dir-selector-white-space-001.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Selectors Level 4 Test: Verify for an identifier with leading and tailing whitespace of dir() </title> + <link rel="author" title="Miyoung Shin" href="mailto:myid.shin@igalia.com"> + <link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo"> + <link rel="match" href="selectors-dir-selector-white-space-001-ref.html"> + <meta name="assert" content="The :dir(ltr) pseudo-class matches an element that has a directionality of (ltr). Since the div element has dir=ltr, the selector matches."> + <style type="text/css"> + div { + width: 100px; + height: 100px; + background-color: red; + } + + #a:dir( ltr) { background-color: green; } + #b:dir(ltr ) { background-color: green; } + #c:dir( ltr ) { background-color: green; } + </style> +</head> +<body> + <p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + <div id="a" dir="ltr"></div> + <div id="b" dir="ltr"></div> + <div id="c" dir="ltr"></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/OWNERS b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/OWNERS index 5f43f91..5e03d9bc 100644 --- a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/OWNERS
@@ -1,4 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true rego@igalia.com
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/DIR_METADATA new file mode 100644 index 0000000..38ef497 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout>Flexbox" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/OWNERS b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/OWNERS index 3aa8367..51c6a57d 100644 --- a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/OWNERS +++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/OWNERS
@@ -1,4 +1 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout>Flexbox -# WPT-NOTIFY: true cbiesinger@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/DIR_METADATA new file mode 100644 index 0000000..815ca00 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout>Shape" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/OWNERS b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/OWNERS deleted file mode 100644 index 5704d224..0000000 --- a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout>Shape -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/DIR_METADATA b/third_party/blink/web_tests/external/wpt/custom-elements/DIR_METADATA new file mode 100644 index 0000000..1c2a667 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/custom-elements/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>HTML>CustomElements" +} +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/OWNERS b/third_party/blink/web_tests/external/wpt/custom-elements/OWNERS deleted file mode 100644 index e1d5315..0000000 --- a/third_party/blink/web_tests/external/wpt/custom-elements/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: dom-dev@chromium.org -# COMPONENT: Blink>HTML>CustomElements
diff --git a/third_party/blink/web_tests/external/wpt/html-media-capture/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html-media-capture/DIR_METADATA new file mode 100644 index 0000000..f76b084a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html-media-capture/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>ImageCapture" +} +team_email: "webrtc-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS b/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS index bae3815..3c4f9b8 100644 --- a/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS +++ b/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS
@@ -1,4 +1,2 @@ -# TEAM: webrtc-dev@chromium.org -# COMPONENT: Blink>ImageCapture rijubrata.bhaumik@intel.com
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/OWNERS b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/OWNERS deleted file mode 100644 index 9b2e5be..0000000 --- a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/OWNERS b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/OWNERS deleted file mode 100644 index 9b2e5be..0000000 --- a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/OWNERS b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/OWNERS deleted file mode 100644 index 9b2e5be..0000000 --- a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/OWNERS b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/OWNERS deleted file mode 100644 index 9b2e5be..0000000 --- a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content-rendering-rules/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content-rendering-rules/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content-rendering-rules/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content-rendering-rules/OWNERS b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content-rendering-rules/OWNERS deleted file mode 100644 index 9b2e5be..0000000 --- a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content-rendering-rules/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/images/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/images/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/images/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/images/OWNERS b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/images/OWNERS deleted file mode 100644 index 9b2e5be..0000000 --- a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/images/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/semantics/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/OWNERS b/third_party/blink/web_tests/external/wpt/html/semantics/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/semantics/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir-expected.txt index 8d4f297..dc96464 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir-expected.txt
@@ -1,6 +1,32 @@ This is a testharness.js-based test. -FAIL ':dir(rtl)' matches all elements whose directionality is 'rtl'. Failed to execute 'querySelectorAll' on 'Document': ':dir(rtl)' is not a valid selector. -FAIL ':dir(ltr)' matches all elements whose directionality is 'ltr'. Failed to execute 'querySelectorAll' on 'Document': ':dir(ltr)' is not a valid selector. -FAIL ':dir(ltr)' doesn't match elements not in the document. Failed to execute 'querySelectorAll' on 'Document': ':dir(ltr)' is not a valid selector. +FAIL ':dir(rtl)' matches all elements whose directionality is 'rtl'. assert_array_equals: lengths differ, expected array [Element node <bdo dir="rtl" id="bdo1">WERBEH</bdo>, Element node <bdi dir="rtl" id="bdi2">WERBEH</bdi>, Element node <bdi id="bdi4">إيان</bdi>, Element node <span dir="rtl" id="span2">WERBEH</span>, Element node <span dir="rtl" id="span5">WERBEH</span>, Element node <span dir="rtl" id="span7"> + <input type="tel" id="in..., Element node <input type="tel" id="input-tel3" dir="rtl"></input>, Element node <bdo dir="auto" id="bdo4">إيان</bdo>] length 8, got [Element node <bdo dir="rtl" id="bdo1">WERBEH</bdo>, Element node <bdi dir="rtl" id="bdi2">WERBEH</bdi>, Element node <bdi id="bdi4">إيان</bdi>, Element node <span dir="rtl" id="span2">WERBEH</span>, Element node <span dir="rtl" id="span5">WERBEH</span>, Element node <span dir="rtl" id="span7"> + <input type="tel" id="in..., Element node <input type="tel" id="input-tel1"></input>, Element node <input type="tel" id="input-tel2" dir="invalid"></input>, Element node <input type="tel" id="input-tel3" dir="rtl"></input>, Element node <bdo dir="auto" id="bdo4">إيان</bdo>] length 10 +FAIL ':dir(ltr)' matches all elements whose directionality is 'ltr'. assert_array_equals: lengths differ, expected array […, Element node <link rel="author" title="Denis Ah-Kang" href="mailto:den..., Element node <link rel="help" href="https://html.spec.whatwg.org/multi..., Element node <script src="/resources/testharness.js" id="script1"></sc..., Element node <script src="/resources/testharnessreport.js" id="script2..., Element node <script src="utils.js" id="script3"></script>, Element node <style id="style"> + #span1 {direction: rtl;} + #..., Element node <body id="body"> + <div id="log"></div> + <bdo dir="r..., Element node <div id="log"></div>, Element node <bdo dir="ltr" id="bdo2">HEBREW</bdo>, Element node <bdi id="bdi1">HEBREW</bdi>, Element node <bdi dir="ltr" id="bdi3">HEBREW</bdi>, Element node <span id="span1">WERBEH</span>, Element node <span dir="ltr" id="span3">HEBREW</span>, Element node <span id="span4">WERBEH</span>, Element node <span dir="ltr" id="span6">HEBREW</span>, Element node <input type="tel" id="input-tel1"></input>, Element node <input type="tel" id="input-tel2" dir="invalid"></input>, Element node <bdo dir="auto" id="bdo3">HEBREW</bdo>, Element node <bdo dir="ltr" id="bdo5">עברית</bdo>, Element node <script id="script4"> + const rtlElements = [ + ...] length 24, got […, Element node <meta charset="utf-8" id="meta"></meta>, Element node <title id="title">Selector: pseudo-classes (:dir(ltr), :d..., Element node <link rel="author" title="Denis Ah-Kang" href="mailto:den..., Element node <link rel="help" href="https://html.spec.whatwg.org/multi..., Element node <script src="/resources/testharness.js" id="script1"></sc..., Element node <script src="/resources/testharnessreport.js" id="script2..., Element node <script src="utils.js" id="script3"></script>, Element node <style id="style"> + #span1 {direction: rtl;} + #..., Element node <body id="body"> + <div id="log"></div> + <bdo dir="r..., Element node <div id="log"></div>, Element node <bdo dir="ltr" id="bdo2">HEBREW</bdo>, Element node <bdi id="bdi1">HEBREW</bdi>, Element node <bdi dir="ltr" id="bdi3">HEBREW</bdi>, Element node <span id="span1">WERBEH</span>, Element node <span dir="ltr" id="span3">HEBREW</span>, Element node <span id="span4">WERBEH</span>, Element node <span dir="ltr" id="span6">HEBREW</span>, Element node <bdo dir="auto" id="bdo3">HEBREW</bdo>, Element node <bdo dir="ltr" id="bdo5">עברית</bdo>, Element node <script id="script4"> + const rtlElements = [ + ...] length 22 +FAIL ':dir(ltr)' doesn't match elements not in the document. assert_array_equals: lengths differ, expected array […, Element node <link rel="author" title="Denis Ah-Kang" href="mailto:den..., Element node <link rel="help" href="https://html.spec.whatwg.org/multi..., Element node <script src="/resources/testharness.js" id="script1"></sc..., Element node <script src="/resources/testharnessreport.js" id="script2..., Element node <script src="utils.js" id="script3"></script>, Element node <style id="style"> + #span1 {direction: rtl;} + #..., Element node <body id="body"> + <div id="log"></div> + <bdo dir="r..., Element node <div id="log"></div>, Element node <bdo dir="ltr" id="bdo2">HEBREW</bdo>, Element node <bdi id="bdi1">HEBREW</bdi>, Element node <bdi dir="ltr" id="bdi3">HEBREW</bdi>, Element node <span id="span1">WERBEH</span>, Element node <span dir="ltr" id="span3">HEBREW</span>, Element node <span id="span4">WERBEH</span>, Element node <span dir="ltr" id="span6">HEBREW</span>, Element node <input type="tel" id="input-tel1"></input>, Element node <input type="tel" id="input-tel2" dir="invalid"></input>, Element node <bdo dir="auto" id="bdo3">HEBREW</bdo>, Element node <bdo dir="ltr" id="bdo5">עברית</bdo>, Element node <script id="script4"> + const rtlElements = [ + ...] length 24, got […, Element node <meta charset="utf-8" id="meta"></meta>, Element node <title id="title">Selector: pseudo-classes (:dir(ltr), :d..., Element node <link rel="author" title="Denis Ah-Kang" href="mailto:den..., Element node <link rel="help" href="https://html.spec.whatwg.org/multi..., Element node <script src="/resources/testharness.js" id="script1"></sc..., Element node <script src="/resources/testharnessreport.js" id="script2..., Element node <script src="utils.js" id="script3"></script>, Element node <style id="style"> + #span1 {direction: rtl;} + #..., Element node <body id="body"> + <div id="log"></div> + <bdo dir="r..., Element node <div id="log"></div>, Element node <bdo dir="ltr" id="bdo2">HEBREW</bdo>, Element node <bdi id="bdi1">HEBREW</bdi>, Element node <bdi dir="ltr" id="bdi3">HEBREW</bdi>, Element node <span id="span1">WERBEH</span>, Element node <span dir="ltr" id="span3">HEBREW</span>, Element node <span id="span4">WERBEH</span>, Element node <span dir="ltr" id="span6">HEBREW</span>, Element node <bdo dir="auto" id="bdo3">HEBREW</bdo>, Element node <bdo dir="ltr" id="bdo5">עברית</bdo>, Element node <script id="script4"> + const rtlElements = [ + ...] length 22 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir-html-input-dynamic-text-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir-html-input-dynamic-text-expected.txt deleted file mode 100644 index d26b681..0000000 --- a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir-html-input-dynamic-text-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL :dir on <input> isn't altered by text children Failed to execute 'matches' on 'Element': ':dir(ltr)' is not a valid selector. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir01-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir01-expected.txt deleted file mode 100644 index dc08da0..0000000 --- a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/dir01-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL direction doesn't affect :dir() Failed to execute 'querySelectorAll' on 'Document': ':dir(ltr)' is not a valid selector. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/OWNERS b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/serializing-html-fragments/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/syntax/serializing-html-fragments/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/syntax/serializing-html-fragments/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/serializing-html-fragments/OWNERS b/third_party/blink/web_tests/external/wpt/html/syntax/serializing-html-fragments/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/syntax/serializing-html-fragments/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/serializing-xml-fragments/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/syntax/serializing-xml-fragments/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/syntax/serializing-xml-fragments/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/serializing-xml-fragments/OWNERS b/third_party/blink/web_tests/external/wpt/html/syntax/serializing-xml-fragments/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/syntax/serializing-xml-fragments/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/user-activation/DIR_METADATA new file mode 100644 index 0000000..4a2c8aa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/OWNERS b/third_party/blink/web_tests/external/wpt/html/user-activation/OWNERS index f17b123..35449ec5 100644 --- a/third_party/blink/web_tests/external/wpt/html/user-activation/OWNERS +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/OWNERS
@@ -1,4 +1 @@ -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input -# WPT-NOTIFY: true mustaq@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/OWNERS b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/closing-the-input-stream/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-write/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-write/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-write/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-write/OWNERS b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-write/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-write/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-writeln/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-writeln/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-writeln/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-writeln/OWNERS b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-writeln/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/document-writeln/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/OWNERS b/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/event-loops/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/event-loops/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/event-loops/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/event-loops/OWNERS b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/event-loops/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/event-loops/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/OWNERS b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/processing-model-2/DIR_METADATA b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/processing-model-2/DIR_METADATA new file mode 100644 index 0000000..1510459 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/processing-model-2/DIR_METADATA
@@ -0,0 +1 @@ +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/processing-model-2/OWNERS b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/processing-model-2/OWNERS deleted file mode 100644 index 422c227..0000000 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/processing-model-2/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# TEAM: dom-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/DIR_METADATA b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/DIR_METADATA new file mode 100644 index 0000000..866f703 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Canvas" +} +team_email: "paint-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/OWNERS b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/OWNERS deleted file mode 100644 index 3b83b67..0000000 --- a/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: paint-dev@chromium.org -# COMPONENT: Blink>Canvas -# WPT-NOTIFY: true \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/images/DIR_METADATA b/third_party/blink/web_tests/external/wpt/images/DIR_METADATA new file mode 100644 index 0000000..13df631 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/images/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Image" +} +team_email: "paint-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/images/OWNERS b/third_party/blink/web_tests/external/wpt/images/OWNERS deleted file mode 100644 index 6640d0e..0000000 --- a/third_party/blink/web_tests/external/wpt/images/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: paint-dev@chromium.org -# COMPONENT: Blink>Image -# WPT-NOTIFY: true \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/DIR_METADATA b/third_party/blink/web_tests/external/wpt/infrastructure/DIR_METADATA index 8e9f60a..da335b9 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/DIR_METADATA +++ b/third_party/blink/web_tests/external/wpt/infrastructure/DIR_METADATA
@@ -1,9 +1,7 @@ monorail { - project: "chromium" component: "Blink>Infra>Ecosystem" } team_email: "ecosystem-infra@chromium.org" -os: LINUX wpt { notify: YES }
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/OWNERS b/third_party/blink/web_tests/external/wpt/infrastructure/OWNERS index 49891ac8..0df202b 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/OWNERS +++ b/third_party/blink/web_tests/external/wpt/infrastructure/OWNERS
@@ -1,6 +1,3 @@ -# TEAM: ecosystem-infra@chromium.org -# COMPONENT: Blink>Infra>Ecosystem -# WPT-NOTIFY: true foolip@chromium.org robertma@chromium.org smcgruer@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/DIR_METADATA b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/DIR_METADATA new file mode 100644 index 0000000..4a2c8aa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/OWNERS b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/OWNERS index 6aa7ab7..dee5bb0f 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/OWNERS +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/OWNERS
@@ -1,4 +1 @@ -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input -# WPT-NOTIFY: true lanwei@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/input-events/DIR_METADATA b/third_party/blink/web_tests/external/wpt/input-events/DIR_METADATA new file mode 100644 index 0000000..4a2c8aa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/input-events/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/input-events/OWNERS b/third_party/blink/web_tests/external/wpt/input-events/OWNERS index 3b44901..004dcc9 100644 --- a/third_party/blink/web_tests/external/wpt/input-events/OWNERS +++ b/third_party/blink/web_tests/external/wpt/input-events/OWNERS
@@ -1,5 +1,2 @@ -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input -# WPT-NOTIFY: true nzolghadr@chromium.org yosin@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/DIR_METADATA b/third_party/blink/web_tests/external/wpt/intersection-observer/DIR_METADATA new file mode 100644 index 0000000..85377a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/intersection-observer/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Layout" +} +team_email: "layout-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/OWNERS b/third_party/blink/web_tests/external/wpt/intersection-observer/OWNERS index 1d4fb997..ac2b5a2 100644 --- a/third_party/blink/web_tests/external/wpt/intersection-observer/OWNERS +++ b/third_party/blink/web_tests/external/wpt/intersection-observer/OWNERS
@@ -1,5 +1,2 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout -# WPT-NOTIFY: true eae@chromium.org szager@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/native-file-system/showPicker-errors.https.window.js b/third_party/blink/web_tests/external/wpt/native-file-system/showPicker-errors.https.window.js index e8f0d3f..d1dabf3 100644 --- a/third_party/blink/web_tests/external/wpt/native-file-system/showPicker-errors.https.window.js +++ b/third_party/blink/web_tests/external/wpt/native-file-system/showPicker-errors.https.window.js
@@ -80,9 +80,39 @@ showPickerMethod + ': MIME type can\'t have invalid characters in subtype.'); - promise_test(async t => { - await promise_rejects_js(t, TypeError, self[showPickerMethod]({ - types: [{accept: {'text/plain': ['.txt', 'txt']}}] - })); - }, showPickerMethod + ': extension has to start with ".".'); + const invalid_extensions = { + '.extensiontoolong': 'extension length more than 16.', + '.txt.': 'extenstion ends with "."', + 'txt': 'extenstion does not start with "."', + '.$txt' : 'illegal character "$"', + '.t<xt': 'illegal character "<"', + '.t/xt': 'illegal character "\"', + '.\txt': 'illegal character "/"', + '.txt\\': 'illegal characters "\\"', + '.txt?': 'illegal character "?"', + '.txt*': 'illegal character "*"', + '.{txt': 'illegal character "{"', + '.}txt': 'illegal character "}"', + ' .txt': 'illegal whitespace at front of extension', + '. txt': 'illegal whitespace in extension', + '.txt ': 'illegal whitespace at end of extension', + '.\u202etxt\u202e' : 'illegal RTL character', + '.t\u00E6xt': 'non-ASCII character "æ"', + '.קום': 'non-ASCII character "קום"', + '.txt🙂': 'non-ASCII character "🙂"', + '.{txt}': 'illegal characters "{" and "}"', + } + + for (const [extension, description] of Object.entries(invalid_extensions)) { + define_file_picker_extension_error_test(showPickerMethod, extension, description) + } } + +function define_file_picker_extension_error_test(showPickerMethod, extension, description) { + promise_test(async t => { + await promise_rejects_js( + t, TypeError, + self[showPickerMethod]( + { types: [{ accept: { 'text/plain': ['.txt', extension] } }] })); + }, showPickerMethod + ': invalid extension "' + extension + '". ' + description + "."); +} \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/selection/DIR_METADATA b/third_party/blink/web_tests/external/wpt/selection/DIR_METADATA new file mode 100644 index 0000000..484b90d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/selection/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>Editing>Selection" +} +team_email: "layout-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/selection/OWNERS b/third_party/blink/web_tests/external/wpt/selection/OWNERS deleted file mode 100644 index 259ded51..0000000 --- a/third_party/blink/web_tests/external/wpt/selection/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Editing>Selection
diff --git a/third_party/blink/web_tests/external/wpt/server-timing/DIR_METADATA b/third_party/blink/web_tests/external/wpt/server-timing/DIR_METADATA new file mode 100644 index 0000000..34d52c7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/server-timing/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>PerformanceAPIs>ServerTiming" +} +team_email: "loading-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/server-timing/OWNERS b/third_party/blink/web_tests/external/wpt/server-timing/OWNERS index 46e79e05..2746bb9 100644 --- a/third_party/blink/web_tests/external/wpt/server-timing/OWNERS +++ b/third_party/blink/web_tests/external/wpt/server-timing/OWNERS
@@ -1,4 +1,2 @@ -# TEAM: loading-dev@chromium.org -# COMPONENT: Blink>PerformanceAPIs>ServerTiming cvazac@akamai.com igrigorik@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/DIR_METADATA b/third_party/blink/web_tests/external/wpt/service-workers/DIR_METADATA new file mode 100644 index 0000000..23931a5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>ServiceWorker" +} +team_email: "worker-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/OWNERS b/third_party/blink/web_tests/external/wpt/service-workers/OWNERS index c7c9d2c..245436a 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/OWNERS +++ b/third_party/blink/web_tests/external/wpt/service-workers/OWNERS
@@ -1,4 +1 @@ -# TEAM: worker-dev@chromium.org -# COMPONENT: Blink>ServiceWorker -# WPT-NOTIFY: true file://content/browser/service_worker/OWNERS
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/DIR_METADATA b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/DIR_METADATA new file mode 100644 index 0000000..f48eedf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Storage>CacheStorage" +} +team_email: "storage-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/OWNERS b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/OWNERS index afb2620..82c8165 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/OWNERS +++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/OWNERS
@@ -1,4 +1 @@ -# TEAM: storage-dev@chromium.org -# COMPONENT: Blink>Storage>CacheStorage -# WPT-NOTIFY: true jsbell@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/DIR_METADATA b/third_party/blink/web_tests/external/wpt/shadow-dom/DIR_METADATA new file mode 100644 index 0000000..407e33f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>DOM>ShadowDOM" +} +team_email: "dom-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/OWNERS b/third_party/blink/web_tests/external/wpt/shadow-dom/OWNERS deleted file mode 100644 index 5fc1b89..0000000 --- a/third_party/blink/web_tests/external/wpt/shadow-dom/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: dom-dev@chromium.org -# COMPONENT: Blink>DOM>ShadowDOM
diff --git a/third_party/blink/web_tests/external/wpt/storage/DIR_METADATA b/third_party/blink/web_tests/external/wpt/storage/DIR_METADATA new file mode 100644 index 0000000..56c0693 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/storage/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Storage>Quota" +} +team_email: "storage-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/storage/OWNERS b/third_party/blink/web_tests/external/wpt/storage/OWNERS index ce2ae1f..82c8165 100644 --- a/third_party/blink/web_tests/external/wpt/storage/OWNERS +++ b/third_party/blink/web_tests/external/wpt/storage/OWNERS
@@ -1,4 +1 @@ -# TEAM: storage-dev@chromium.org -# COMPONENT: Blink>Storage>Quota -# WPT-NOTIFY: true jsbell@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/streams/DIR_METADATA b/third_party/blink/web_tests/external/wpt/streams/DIR_METADATA new file mode 100644 index 0000000..04b78c0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/streams/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Network>StreamsAPI" +} +team_email: "blink-network-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/streams/OWNERS b/third_party/blink/web_tests/external/wpt/streams/OWNERS index 041c2b6..0431035 100644 --- a/third_party/blink/web_tests/external/wpt/streams/OWNERS +++ b/third_party/blink/web_tests/external/wpt/streams/OWNERS
@@ -1,5 +1,2 @@ -# TEAM: blink-network-dev@chromium.org -# COMPONENT: Blink>Network>StreamsAPI -# WPT-NOTIFY: true domenic@chromium.org ricea@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/streams/idlharness.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/idlharness.any-expected.txt index bf60a89..ac189daf 100644 --- a/third_party/blink/web_tests/external/wpt/streams/idlharness.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/idlharness.any-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 224 tests; 139 PASS, 85 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 224 tests; 193 PASS, 31 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS ReadableStreamDefaultReader includes ReadableStreamGenericReader: member names are unique @@ -46,24 +46,24 @@ PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "closed" with the proper type PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "cancel(optional any)" with the proper type PASS ReadableStreamDefaultReader interface: calling cancel(optional any) on (new ReadableStream()).getReader() with too few arguments must throw TypeError -FAIL ReadableStreamBYOBReader interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface object length assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface object name assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation read(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation releaseLock() assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: attribute closed assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation cancel(optional any) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader must be primary interface of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL Stringification of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "read(ArrayBufferView)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: calling read(ArrayBufferView) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "releaseLock()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "closed" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "cancel(optional any)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" +PASS ReadableStreamBYOBReader interface: existence and properties of interface object +PASS ReadableStreamBYOBReader interface object length +PASS ReadableStreamBYOBReader interface object name +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableStreamBYOBReader interface: operation read(ArrayBufferView) +PASS ReadableStreamBYOBReader interface: operation releaseLock() +PASS ReadableStreamBYOBReader interface: attribute closed +PASS ReadableStreamBYOBReader interface: operation cancel(optional any) +PASS ReadableStreamBYOBReader must be primary interface of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) +PASS Stringification of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "read(ArrayBufferView)" with the proper type +PASS ReadableStreamBYOBReader interface: calling read(ArrayBufferView) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "releaseLock()" with the proper type +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "closed" with the proper type +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "cancel(optional any)" with the proper type +PASS ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError FAIL ReadableStreamDefaultController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing FAIL ReadableStreamDefaultController interface object length assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing FAIL ReadableStreamDefaultController interface object name assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing @@ -82,42 +82,42 @@ PASS ReadableStreamDefaultController interface: calling enqueue(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError PASS ReadableStreamDefaultController interface: self.readableStreamDefaultController must inherit property "error(optional any)" with the proper type PASS ReadableStreamDefaultController interface: calling error(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError -FAIL ReadableByteStreamController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface object length assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface object name assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: attribute byobRequest assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: attribute desiredSize assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation close() assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation enqueue(ArrayBufferView) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation error(optional any) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController must be primary interface of self.readableByteStreamController assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL Stringification of self.readableByteStreamController assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "byobRequest" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "desiredSize" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "close()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "enqueue(ArrayBufferView)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: calling enqueue(ArrayBufferView) on self.readableByteStreamController with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "error(optional any)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: calling error(optional any) on self.readableByteStreamController with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface object length assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface object name assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: attribute view assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: operation respond(unsigned long long) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: operation respondWithNewView(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest must be primary interface of self.readableStreamByobRequest assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL Stringification of self.readableStreamByobRequest assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "view" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respond(unsigned long long)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respondWithNewView(ArrayBufferView)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +PASS ReadableByteStreamController interface: existence and properties of interface object +PASS ReadableByteStreamController interface object length +PASS ReadableByteStreamController interface object name +PASS ReadableByteStreamController interface: existence and properties of interface prototype object +PASS ReadableByteStreamController interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableByteStreamController interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableByteStreamController interface: attribute byobRequest +PASS ReadableByteStreamController interface: attribute desiredSize +PASS ReadableByteStreamController interface: operation close() +PASS ReadableByteStreamController interface: operation enqueue(ArrayBufferView) +PASS ReadableByteStreamController interface: operation error(optional any) +PASS ReadableByteStreamController must be primary interface of self.readableByteStreamController +PASS Stringification of self.readableByteStreamController +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "byobRequest" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "desiredSize" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "close()" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "enqueue(ArrayBufferView)" with the proper type +PASS ReadableByteStreamController interface: calling enqueue(ArrayBufferView) on self.readableByteStreamController with too few arguments must throw TypeError +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "error(optional any)" with the proper type +PASS ReadableByteStreamController interface: calling error(optional any) on self.readableByteStreamController with too few arguments must throw TypeError +PASS ReadableStreamBYOBRequest interface: existence and properties of interface object +PASS ReadableStreamBYOBRequest interface object length +PASS ReadableStreamBYOBRequest interface object name +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableStreamBYOBRequest interface: attribute view +PASS ReadableStreamBYOBRequest interface: operation respond(unsigned long long) +PASS ReadableStreamBYOBRequest interface: operation respondWithNewView(ArrayBufferView) +PASS ReadableStreamBYOBRequest must be primary interface of self.readableStreamByobRequest +PASS Stringification of self.readableStreamByobRequest +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "view" with the proper type +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respond(unsigned long long)" with the proper type +PASS ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respondWithNewView(ArrayBufferView)" with the proper type +PASS ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError PASS WritableStream interface: existence and properties of interface object PASS WritableStream interface object length PASS WritableStream interface object name
diff --git a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.serviceworker-expected.txt index bf60a89..ac189daf 100644 --- a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.serviceworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.serviceworker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 224 tests; 139 PASS, 85 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 224 tests; 193 PASS, 31 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS ReadableStreamDefaultReader includes ReadableStreamGenericReader: member names are unique @@ -46,24 +46,24 @@ PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "closed" with the proper type PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "cancel(optional any)" with the proper type PASS ReadableStreamDefaultReader interface: calling cancel(optional any) on (new ReadableStream()).getReader() with too few arguments must throw TypeError -FAIL ReadableStreamBYOBReader interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface object length assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface object name assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation read(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation releaseLock() assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: attribute closed assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation cancel(optional any) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader must be primary interface of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL Stringification of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "read(ArrayBufferView)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: calling read(ArrayBufferView) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "releaseLock()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "closed" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "cancel(optional any)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" +PASS ReadableStreamBYOBReader interface: existence and properties of interface object +PASS ReadableStreamBYOBReader interface object length +PASS ReadableStreamBYOBReader interface object name +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableStreamBYOBReader interface: operation read(ArrayBufferView) +PASS ReadableStreamBYOBReader interface: operation releaseLock() +PASS ReadableStreamBYOBReader interface: attribute closed +PASS ReadableStreamBYOBReader interface: operation cancel(optional any) +PASS ReadableStreamBYOBReader must be primary interface of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) +PASS Stringification of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "read(ArrayBufferView)" with the proper type +PASS ReadableStreamBYOBReader interface: calling read(ArrayBufferView) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "releaseLock()" with the proper type +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "closed" with the proper type +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "cancel(optional any)" with the proper type +PASS ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError FAIL ReadableStreamDefaultController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing FAIL ReadableStreamDefaultController interface object length assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing FAIL ReadableStreamDefaultController interface object name assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing @@ -82,42 +82,42 @@ PASS ReadableStreamDefaultController interface: calling enqueue(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError PASS ReadableStreamDefaultController interface: self.readableStreamDefaultController must inherit property "error(optional any)" with the proper type PASS ReadableStreamDefaultController interface: calling error(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError -FAIL ReadableByteStreamController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface object length assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface object name assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: attribute byobRequest assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: attribute desiredSize assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation close() assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation enqueue(ArrayBufferView) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation error(optional any) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController must be primary interface of self.readableByteStreamController assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL Stringification of self.readableByteStreamController assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "byobRequest" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "desiredSize" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "close()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "enqueue(ArrayBufferView)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: calling enqueue(ArrayBufferView) on self.readableByteStreamController with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "error(optional any)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: calling error(optional any) on self.readableByteStreamController with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface object length assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface object name assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: attribute view assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: operation respond(unsigned long long) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: operation respondWithNewView(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest must be primary interface of self.readableStreamByobRequest assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL Stringification of self.readableStreamByobRequest assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "view" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respond(unsigned long long)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respondWithNewView(ArrayBufferView)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +PASS ReadableByteStreamController interface: existence and properties of interface object +PASS ReadableByteStreamController interface object length +PASS ReadableByteStreamController interface object name +PASS ReadableByteStreamController interface: existence and properties of interface prototype object +PASS ReadableByteStreamController interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableByteStreamController interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableByteStreamController interface: attribute byobRequest +PASS ReadableByteStreamController interface: attribute desiredSize +PASS ReadableByteStreamController interface: operation close() +PASS ReadableByteStreamController interface: operation enqueue(ArrayBufferView) +PASS ReadableByteStreamController interface: operation error(optional any) +PASS ReadableByteStreamController must be primary interface of self.readableByteStreamController +PASS Stringification of self.readableByteStreamController +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "byobRequest" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "desiredSize" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "close()" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "enqueue(ArrayBufferView)" with the proper type +PASS ReadableByteStreamController interface: calling enqueue(ArrayBufferView) on self.readableByteStreamController with too few arguments must throw TypeError +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "error(optional any)" with the proper type +PASS ReadableByteStreamController interface: calling error(optional any) on self.readableByteStreamController with too few arguments must throw TypeError +PASS ReadableStreamBYOBRequest interface: existence and properties of interface object +PASS ReadableStreamBYOBRequest interface object length +PASS ReadableStreamBYOBRequest interface object name +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableStreamBYOBRequest interface: attribute view +PASS ReadableStreamBYOBRequest interface: operation respond(unsigned long long) +PASS ReadableStreamBYOBRequest interface: operation respondWithNewView(ArrayBufferView) +PASS ReadableStreamBYOBRequest must be primary interface of self.readableStreamByobRequest +PASS Stringification of self.readableStreamByobRequest +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "view" with the proper type +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respond(unsigned long long)" with the proper type +PASS ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respondWithNewView(ArrayBufferView)" with the proper type +PASS ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError PASS WritableStream interface: existence and properties of interface object PASS WritableStream interface object length PASS WritableStream interface object name
diff --git a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.sharedworker-expected.txt index bf60a89..ac189daf 100644 --- a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.sharedworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.sharedworker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 224 tests; 139 PASS, 85 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 224 tests; 193 PASS, 31 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS ReadableStreamDefaultReader includes ReadableStreamGenericReader: member names are unique @@ -46,24 +46,24 @@ PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "closed" with the proper type PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "cancel(optional any)" with the proper type PASS ReadableStreamDefaultReader interface: calling cancel(optional any) on (new ReadableStream()).getReader() with too few arguments must throw TypeError -FAIL ReadableStreamBYOBReader interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface object length assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface object name assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation read(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation releaseLock() assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: attribute closed assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation cancel(optional any) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader must be primary interface of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL Stringification of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "read(ArrayBufferView)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: calling read(ArrayBufferView) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "releaseLock()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "closed" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "cancel(optional any)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" +PASS ReadableStreamBYOBReader interface: existence and properties of interface object +PASS ReadableStreamBYOBReader interface object length +PASS ReadableStreamBYOBReader interface object name +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableStreamBYOBReader interface: operation read(ArrayBufferView) +PASS ReadableStreamBYOBReader interface: operation releaseLock() +PASS ReadableStreamBYOBReader interface: attribute closed +PASS ReadableStreamBYOBReader interface: operation cancel(optional any) +PASS ReadableStreamBYOBReader must be primary interface of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) +PASS Stringification of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "read(ArrayBufferView)" with the proper type +PASS ReadableStreamBYOBReader interface: calling read(ArrayBufferView) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "releaseLock()" with the proper type +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "closed" with the proper type +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "cancel(optional any)" with the proper type +PASS ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError FAIL ReadableStreamDefaultController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing FAIL ReadableStreamDefaultController interface object length assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing FAIL ReadableStreamDefaultController interface object name assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing @@ -82,42 +82,42 @@ PASS ReadableStreamDefaultController interface: calling enqueue(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError PASS ReadableStreamDefaultController interface: self.readableStreamDefaultController must inherit property "error(optional any)" with the proper type PASS ReadableStreamDefaultController interface: calling error(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError -FAIL ReadableByteStreamController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface object length assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface object name assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: attribute byobRequest assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: attribute desiredSize assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation close() assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation enqueue(ArrayBufferView) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation error(optional any) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController must be primary interface of self.readableByteStreamController assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL Stringification of self.readableByteStreamController assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "byobRequest" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "desiredSize" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "close()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "enqueue(ArrayBufferView)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: calling enqueue(ArrayBufferView) on self.readableByteStreamController with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "error(optional any)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: calling error(optional any) on self.readableByteStreamController with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface object length assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface object name assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: attribute view assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: operation respond(unsigned long long) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: operation respondWithNewView(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest must be primary interface of self.readableStreamByobRequest assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL Stringification of self.readableStreamByobRequest assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "view" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respond(unsigned long long)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respondWithNewView(ArrayBufferView)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +PASS ReadableByteStreamController interface: existence and properties of interface object +PASS ReadableByteStreamController interface object length +PASS ReadableByteStreamController interface object name +PASS ReadableByteStreamController interface: existence and properties of interface prototype object +PASS ReadableByteStreamController interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableByteStreamController interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableByteStreamController interface: attribute byobRequest +PASS ReadableByteStreamController interface: attribute desiredSize +PASS ReadableByteStreamController interface: operation close() +PASS ReadableByteStreamController interface: operation enqueue(ArrayBufferView) +PASS ReadableByteStreamController interface: operation error(optional any) +PASS ReadableByteStreamController must be primary interface of self.readableByteStreamController +PASS Stringification of self.readableByteStreamController +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "byobRequest" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "desiredSize" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "close()" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "enqueue(ArrayBufferView)" with the proper type +PASS ReadableByteStreamController interface: calling enqueue(ArrayBufferView) on self.readableByteStreamController with too few arguments must throw TypeError +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "error(optional any)" with the proper type +PASS ReadableByteStreamController interface: calling error(optional any) on self.readableByteStreamController with too few arguments must throw TypeError +PASS ReadableStreamBYOBRequest interface: existence and properties of interface object +PASS ReadableStreamBYOBRequest interface object length +PASS ReadableStreamBYOBRequest interface object name +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableStreamBYOBRequest interface: attribute view +PASS ReadableStreamBYOBRequest interface: operation respond(unsigned long long) +PASS ReadableStreamBYOBRequest interface: operation respondWithNewView(ArrayBufferView) +PASS ReadableStreamBYOBRequest must be primary interface of self.readableStreamByobRequest +PASS Stringification of self.readableStreamByobRequest +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "view" with the proper type +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respond(unsigned long long)" with the proper type +PASS ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respondWithNewView(ArrayBufferView)" with the proper type +PASS ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError PASS WritableStream interface: existence and properties of interface object PASS WritableStream interface object length PASS WritableStream interface object name
diff --git a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.worker-expected.txt index bf60a89..ac189daf 100644 --- a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.worker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 224 tests; 139 PASS, 85 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 224 tests; 193 PASS, 31 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS ReadableStreamDefaultReader includes ReadableStreamGenericReader: member names are unique @@ -46,24 +46,24 @@ PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "closed" with the proper type PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "cancel(optional any)" with the proper type PASS ReadableStreamDefaultReader interface: calling cancel(optional any) on (new ReadableStream()).getReader() with too few arguments must throw TypeError -FAIL ReadableStreamBYOBReader interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface object length assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface object name assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation read(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation releaseLock() assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: attribute closed assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader interface: operation cancel(optional any) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing -FAIL ReadableStreamBYOBReader must be primary interface of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL Stringification of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "read(ArrayBufferView)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: calling read(ArrayBufferView) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "releaseLock()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "closed" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "cancel(optional any)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" -FAIL ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" +PASS ReadableStreamBYOBReader interface: existence and properties of interface object +PASS ReadableStreamBYOBReader interface object length +PASS ReadableStreamBYOBReader interface object name +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableStreamBYOBReader interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableStreamBYOBReader interface: operation read(ArrayBufferView) +PASS ReadableStreamBYOBReader interface: operation releaseLock() +PASS ReadableStreamBYOBReader interface: attribute closed +PASS ReadableStreamBYOBReader interface: operation cancel(optional any) +PASS ReadableStreamBYOBReader must be primary interface of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) +PASS Stringification of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "read(ArrayBufferView)" with the proper type +PASS ReadableStreamBYOBReader interface: calling read(ArrayBufferView) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "releaseLock()" with the proper type +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "closed" with the proper type +PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "cancel(optional any)" with the proper type +PASS ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError FAIL ReadableStreamDefaultController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing FAIL ReadableStreamDefaultController interface object length assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing FAIL ReadableStreamDefaultController interface object name assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing @@ -82,42 +82,42 @@ PASS ReadableStreamDefaultController interface: calling enqueue(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError PASS ReadableStreamDefaultController interface: self.readableStreamDefaultController must inherit property "error(optional any)" with the proper type PASS ReadableStreamDefaultController interface: calling error(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError -FAIL ReadableByteStreamController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface object length assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface object name assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: attribute byobRequest assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: attribute desiredSize assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation close() assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation enqueue(ArrayBufferView) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController interface: operation error(optional any) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing -FAIL ReadableByteStreamController must be primary interface of self.readableByteStreamController assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL Stringification of self.readableByteStreamController assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "byobRequest" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "desiredSize" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "close()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "enqueue(ArrayBufferView)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: calling enqueue(ArrayBufferView) on self.readableByteStreamController with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "error(optional any)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableByteStreamController interface: calling error(optional any) on self.readableByteStreamController with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface object length assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface object name assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: attribute view assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: operation respond(unsigned long long) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest interface: operation respondWithNewView(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing -FAIL ReadableStreamBYOBRequest must be primary interface of self.readableStreamByobRequest assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL Stringification of self.readableStreamByobRequest assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "view" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respond(unsigned long long)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respondWithNewView(ArrayBufferView)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" -FAIL ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +PASS ReadableByteStreamController interface: existence and properties of interface object +PASS ReadableByteStreamController interface object length +PASS ReadableByteStreamController interface object name +PASS ReadableByteStreamController interface: existence and properties of interface prototype object +PASS ReadableByteStreamController interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableByteStreamController interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableByteStreamController interface: attribute byobRequest +PASS ReadableByteStreamController interface: attribute desiredSize +PASS ReadableByteStreamController interface: operation close() +PASS ReadableByteStreamController interface: operation enqueue(ArrayBufferView) +PASS ReadableByteStreamController interface: operation error(optional any) +PASS ReadableByteStreamController must be primary interface of self.readableByteStreamController +PASS Stringification of self.readableByteStreamController +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "byobRequest" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "desiredSize" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "close()" with the proper type +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "enqueue(ArrayBufferView)" with the proper type +PASS ReadableByteStreamController interface: calling enqueue(ArrayBufferView) on self.readableByteStreamController with too few arguments must throw TypeError +PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "error(optional any)" with the proper type +PASS ReadableByteStreamController interface: calling error(optional any) on self.readableByteStreamController with too few arguments must throw TypeError +PASS ReadableStreamBYOBRequest interface: existence and properties of interface object +PASS ReadableStreamBYOBRequest interface object length +PASS ReadableStreamBYOBRequest interface object name +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's "constructor" property +PASS ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's @@unscopables property +PASS ReadableStreamBYOBRequest interface: attribute view +PASS ReadableStreamBYOBRequest interface: operation respond(unsigned long long) +PASS ReadableStreamBYOBRequest interface: operation respondWithNewView(ArrayBufferView) +PASS ReadableStreamBYOBRequest must be primary interface of self.readableStreamByobRequest +PASS Stringification of self.readableStreamByobRequest +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "view" with the proper type +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respond(unsigned long long)" with the proper type +PASS ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError +PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respondWithNewView(ArrayBufferView)" with the proper type +PASS ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError PASS WritableStream interface: existence and properties of interface object PASS WritableStream interface object length PASS WritableStream interface object name
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any-expected.txt deleted file mode 100644 index 9a39ea47..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -This is a testharness.js-based test. -FAIL ReadableStream with byte source: read()ing from a closed stream still transfers the buffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read()ing from a stream with queued chunks still transfers the buffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing an already-detached buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing a zero-length buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing a zero-length view on a non-zero-length buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into an already-detached buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into a zero-length buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into a zero-length view on a non-zero-length buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.js index 0777208..d4ad483 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.js
@@ -212,8 +212,7 @@ c.close(); - const zeroLengthView = new Uint8Array(view.buffer, 0, 0); - assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(zeroLengthView)); + assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view)); }), type: 'bytes' });
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker-expected.txt deleted file mode 100644 index 9a39ea47..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -This is a testharness.js-based test. -FAIL ReadableStream with byte source: read()ing from a closed stream still transfers the buffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read()ing from a stream with queued chunks still transfers the buffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing an already-detached buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing a zero-length buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing a zero-length view on a non-zero-length buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into an already-detached buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into a zero-length buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into a zero-length view on a non-zero-length buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.sharedworker-expected.txt deleted file mode 100644 index 9a39ea47..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.sharedworker-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -This is a testharness.js-based test. -FAIL ReadableStream with byte source: read()ing from a closed stream still transfers the buffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read()ing from a stream with queued chunks still transfers the buffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing an already-detached buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing a zero-length buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing a zero-length view on a non-zero-length buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into an already-detached buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into a zero-length buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into a zero-length view on a non-zero-length buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.worker-expected.txt deleted file mode 100644 index 9a39ea47..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.worker-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -This is a testharness.js-based test. -FAIL ReadableStream with byte source: read()ing from a closed stream still transfers the buffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read()ing from a stream with queued chunks still transfers the buffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing an already-detached buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing a zero-length buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueuing a zero-length view on a non-zero-length buffer throws Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into an already-detached buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into a zero-length buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: reading into a zero-length view on a non-zero-length buffer rejects Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the readable state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the closed state) Failed to construct 'ReadableStream': bytes type is not yet implemented -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt deleted file mode 100644 index 129e634..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: ReadableByteStreamController is not defined -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt deleted file mode 100644 index 8804b86f..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: Failed to register a ServiceWorker for scope ('https://web-platform.test:8444/streams/readable-byte-streams/does/not/exist') with script ('https://web-platform.test:8444/streams/readable-byte-streams/construct-byob-request.any.worker.js'): ServiceWorker script evaluation failed -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.sharedworker-expected.txt deleted file mode 100644 index 8ec519e..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.sharedworker-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL construct-byob-request Uncaught RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt deleted file mode 100644 index 129e634..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: ReadableByteStreamController is not defined -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any-expected.txt deleted file mode 100644 index 97c2cf1..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any-expected.txt +++ /dev/null
@@ -1,83 +0,0 @@ -This is a testharness.js-based test. -Found 76 tests; 2 PASS, 74 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS getReader({mode: "byob"}) throws on non-bytes streams -FAIL ReadableStream with byte source can be constructed with no errors Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL getReader({mode}) must perform ToString() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Construct and expect start and pull being called Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: No automatic pull call if start doesn't finish Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Construct with highWaterMark of 0 Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: desiredSize when closed Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: desiredSize when errored Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), then releaseLock() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader() with mode set to byob, then releaseLock() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that closing a stream does not release a reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that erroring a stream does not release a reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader with pending read() must throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() and read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: autoAllocateChunkSize Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Mix of auto allocate and BYOB Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() and read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Push source that doesn't understand pull signal Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: pull() function is not callable assert_throws_js: constructor should throw function "() => new ReadableStream({ - pull: 'foo', - type: 'bytes' - })" threw object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" ("RangeError") expected instance of function "function TypeError() { [native code] }" ("TypeError") -FAIL ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), read(view) partially, then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), enqueue(), close(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), close(), getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to pull() by enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to pull() by enqueue() asynchronously Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to multiple pull() by separate enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() with a transferred ArrayBuffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() with too big value Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), read(view), then cancel() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: cancel() with partially filled pending pull() request Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully covered by view Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throw if close()-ed more than once Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throw on enqueue() after close() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() and close() in pull() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read() twice, then enqueue() twice Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view), close() and respond() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view), big enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view) and multiple enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with passing undefined as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with passing an empty object as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read() on an errored stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(), then error() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) on an errored stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then error() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull function must error the stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respond() twice on the same byobRequest should throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respondWithNewView() twice on the same byobRequest should throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respond(0) twice on the same byobRequest should throw even when closed Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL pull() resolving should not make releaseLock() possible Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader can be constructed directly Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires a ReadableStream argument Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires an unlocked ReadableStream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes" Failed to construct 'ReadableStream': bytes type is not yet implemented -PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.serviceworker-expected.txt deleted file mode 100644 index 97c2cf1..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.serviceworker-expected.txt +++ /dev/null
@@ -1,83 +0,0 @@ -This is a testharness.js-based test. -Found 76 tests; 2 PASS, 74 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS getReader({mode: "byob"}) throws on non-bytes streams -FAIL ReadableStream with byte source can be constructed with no errors Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL getReader({mode}) must perform ToString() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Construct and expect start and pull being called Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: No automatic pull call if start doesn't finish Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Construct with highWaterMark of 0 Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: desiredSize when closed Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: desiredSize when errored Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), then releaseLock() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader() with mode set to byob, then releaseLock() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that closing a stream does not release a reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that erroring a stream does not release a reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader with pending read() must throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() and read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: autoAllocateChunkSize Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Mix of auto allocate and BYOB Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() and read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Push source that doesn't understand pull signal Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: pull() function is not callable assert_throws_js: constructor should throw function "() => new ReadableStream({ - pull: 'foo', - type: 'bytes' - })" threw object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" ("RangeError") expected instance of function "function TypeError() { [native code] }" ("TypeError") -FAIL ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), read(view) partially, then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), enqueue(), close(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), close(), getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to pull() by enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to pull() by enqueue() asynchronously Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to multiple pull() by separate enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() with a transferred ArrayBuffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() with too big value Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), read(view), then cancel() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: cancel() with partially filled pending pull() request Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully covered by view Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throw if close()-ed more than once Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throw on enqueue() after close() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() and close() in pull() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read() twice, then enqueue() twice Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view), close() and respond() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view), big enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view) and multiple enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with passing undefined as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with passing an empty object as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read() on an errored stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(), then error() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) on an errored stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then error() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull function must error the stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respond() twice on the same byobRequest should throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respondWithNewView() twice on the same byobRequest should throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respond(0) twice on the same byobRequest should throw even when closed Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL pull() resolving should not make releaseLock() possible Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader can be constructed directly Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires a ReadableStream argument Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires an unlocked ReadableStream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes" Failed to construct 'ReadableStream': bytes type is not yet implemented -PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.sharedworker-expected.txt deleted file mode 100644 index 97c2cf1..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.sharedworker-expected.txt +++ /dev/null
@@ -1,83 +0,0 @@ -This is a testharness.js-based test. -Found 76 tests; 2 PASS, 74 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS getReader({mode: "byob"}) throws on non-bytes streams -FAIL ReadableStream with byte source can be constructed with no errors Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL getReader({mode}) must perform ToString() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Construct and expect start and pull being called Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: No automatic pull call if start doesn't finish Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Construct with highWaterMark of 0 Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: desiredSize when closed Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: desiredSize when errored Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), then releaseLock() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader() with mode set to byob, then releaseLock() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that closing a stream does not release a reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that erroring a stream does not release a reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader with pending read() must throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() and read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: autoAllocateChunkSize Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Mix of auto allocate and BYOB Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() and read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Push source that doesn't understand pull signal Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: pull() function is not callable assert_throws_js: constructor should throw function "() => new ReadableStream({ - pull: 'foo', - type: 'bytes' - })" threw object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" ("RangeError") expected instance of function "function TypeError() { [native code] }" ("TypeError") -FAIL ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), read(view) partially, then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), enqueue(), close(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), close(), getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to pull() by enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to pull() by enqueue() asynchronously Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to multiple pull() by separate enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() with a transferred ArrayBuffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() with too big value Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), read(view), then cancel() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: cancel() with partially filled pending pull() request Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully covered by view Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throw if close()-ed more than once Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throw on enqueue() after close() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() and close() in pull() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read() twice, then enqueue() twice Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view), close() and respond() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view), big enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view) and multiple enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with passing undefined as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with passing an empty object as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read() on an errored stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(), then error() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) on an errored stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then error() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull function must error the stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respond() twice on the same byobRequest should throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respondWithNewView() twice on the same byobRequest should throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respond(0) twice on the same byobRequest should throw even when closed Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL pull() resolving should not make releaseLock() possible Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader can be constructed directly Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires a ReadableStream argument Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires an unlocked ReadableStream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes" Failed to construct 'ReadableStream': bytes type is not yet implemented -PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.worker-expected.txt deleted file mode 100644 index 97c2cf1..0000000 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.worker-expected.txt +++ /dev/null
@@ -1,83 +0,0 @@ -This is a testharness.js-based test. -Found 76 tests; 2 PASS, 74 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS getReader({mode: "byob"}) throws on non-bytes streams -FAIL ReadableStream with byte source can be constructed with no errors Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL getReader({mode}) must perform ToString() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Construct and expect start and pull being called Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: No automatic pull call if start doesn't finish Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Construct with highWaterMark of 0 Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: desiredSize when closed Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: desiredSize when errored Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), then releaseLock() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader() with mode set to byob, then releaseLock() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that closing a stream does not release a reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that erroring a stream does not release a reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader with pending read() must throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() and read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: autoAllocateChunkSize Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Mix of auto allocate and BYOB Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Automatic pull() after start() and read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Push source that doesn't understand pull signal Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: pull() function is not callable assert_throws_js: constructor should throw function "() => new ReadableStream({ - pull: 'foo', - type: 'bytes' - })" threw object "RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented" ("RangeError") expected instance of function "function TypeError() { [native code] }" ("TypeError") -FAIL ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), read(view) partially, then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), enqueue(), close(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), close(), getReader(), then read() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to pull() by enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to pull() by enqueue() asynchronously Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Respond to multiple pull() by separate enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() with a transferred ArrayBuffer Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() with too big value Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: getReader(), read(view), then cancel() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: cancel() with partially filled pending pull() request Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully covered by view Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view) Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with Uint16Array Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throw if close()-ed more than once Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throw on enqueue() after close() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then respond() and close() in pull() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read() twice, then enqueue() twice Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view), close() and respond() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view), big enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Multiple read(view) and multiple enqueue() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with passing undefined as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) with passing an empty object as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read() on an errored stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(), then error() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view) on an errored stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: read(view), then error() Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull function must error the stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respond() twice on the same byobRequest should throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respondWithNewView() twice on the same byobRequest should throw Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL calling respond(0) twice on the same byobRequest should throw even when closed Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL pull() resolving should not make releaseLock() possible Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader can be constructed directly Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires a ReadableStream argument Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires an unlocked ReadableStream Failed to construct 'ReadableStream': bytes type is not yet implemented -FAIL ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes" Failed to construct 'ReadableStream': bytes type is not yet implemented -PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/subresource-integrity/DIR_METADATA b/third_party/blink/web_tests/external/wpt/subresource-integrity/DIR_METADATA new file mode 100644 index 0000000..56cf7f3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/subresource-integrity/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>SecurityFeature" +} +team_email: "security-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/subresource-integrity/OWNERS b/third_party/blink/web_tests/external/wpt/subresource-integrity/OWNERS index e8e1bb11..75bf0dee 100644 --- a/third_party/blink/web_tests/external/wpt/subresource-integrity/OWNERS +++ b/third_party/blink/web_tests/external/wpt/subresource-integrity/OWNERS
@@ -1,4 +1,2 @@ -# TEAM: security-dev@chromium.org -# COMPONENT: Blink>SecurityFeature mkwst@chromium.org jochen@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/svg/DIR_METADATA b/third_party/blink/web_tests/external/wpt/svg/DIR_METADATA new file mode 100644 index 0000000..9468b404 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>SVG" +} +team_email: "paint-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/svg/OWNERS b/third_party/blink/web_tests/external/wpt/svg/OWNERS deleted file mode 100644 index cf0ed9aa..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: paint-dev@chromium.org -# COMPONENT: Blink>SVG -# WPT-NOTIFY: true \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/touch-events/DIR_METADATA b/third_party/blink/web_tests/external/wpt/touch-events/DIR_METADATA new file mode 100644 index 0000000..4a2c8aa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/touch-events/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/touch-events/OWNERS b/third_party/blink/web_tests/external/wpt/touch-events/OWNERS index 46d4a5d..9258d11 100644 --- a/third_party/blink/web_tests/external/wpt/touch-events/OWNERS +++ b/third_party/blink/web_tests/external/wpt/touch-events/OWNERS
@@ -1,4 +1 @@ -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input -# WPT-NOTIFY: true nzolghadr@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/DIR_METADATA b/third_party/blink/web_tests/external/wpt/trusted-types/DIR_METADATA new file mode 100644 index 0000000..56cf7f3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/trusted-types/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>SecurityFeature" +} +team_email: "security-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/OWNERS b/third_party/blink/web_tests/external/wpt/trusted-types/OWNERS index 43db381..3f84563 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/OWNERS +++ b/third_party/blink/web_tests/external/wpt/trusted-types/OWNERS
@@ -1,3 +1 @@ -# TEAM: security-dev@chromium.org -# COMPONENT: Blink>SecurityFeature mkwst@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/uievents/DIR_METADATA b/third_party/blink/web_tests/external/wpt/uievents/DIR_METADATA new file mode 100644 index 0000000..4a2c8aa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/uievents/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/uievents/OWNERS b/third_party/blink/web_tests/external/wpt/uievents/OWNERS index 8ad136a..26a49787 100644 --- a/third_party/blink/web_tests/external/wpt/uievents/OWNERS +++ b/third_party/blink/web_tests/external/wpt/uievents/OWNERS
@@ -1,4 +1 @@ -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input -# WPT-NOTIFY: true dtapuska@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/DIR_METADATA b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/DIR_METADATA new file mode 100644 index 0000000..56cf7f3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>SecurityFeature" +} +team_email: "security-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/OWNERS b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/OWNERS index 43db381..3f84563 100644 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/OWNERS +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/OWNERS
@@ -1,3 +1 @@ -# TEAM: security-dev@chromium.org -# COMPONENT: Blink>SecurityFeature mkwst@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/url/DIR_METADATA b/third_party/blink/web_tests/external/wpt/url/DIR_METADATA new file mode 100644 index 0000000..72f55a0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/url/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>Network" +} +team_email: "blink-network-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/url/OWNERS b/third_party/blink/web_tests/external/wpt/url/OWNERS deleted file mode 100644 index 8263c35..0000000 --- a/third_party/blink/web_tests/external/wpt/url/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: blink-network-dev@chromium.org -# COMPONENT: Blink>Network
diff --git a/third_party/blink/web_tests/external/wpt/user-timing/DIR_METADATA b/third_party/blink/web_tests/external/wpt/user-timing/DIR_METADATA new file mode 100644 index 0000000..45b72a6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/user-timing/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>PerformanceAPIs" +} +team_email: "speed-metrics-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/user-timing/OWNERS b/third_party/blink/web_tests/external/wpt/user-timing/OWNERS deleted file mode 100644 index f4011d2b..0000000 --- a/third_party/blink/web_tests/external/wpt/user-timing/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: speed-metrics-dev@chromium.org -# COMPONENT: Blink>PerformanceAPIs -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/vibration/DIR_METADATA b/third_party/blink/web_tests/external/wpt/vibration/DIR_METADATA new file mode 100644 index 0000000..e66495f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/vibration/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>Vibration" +} +team_email: "platform-capabilities@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/vibration/OWNERS b/third_party/blink/web_tests/external/wpt/vibration/OWNERS deleted file mode 100644 index 4d14efd..0000000 --- a/third_party/blink/web_tests/external/wpt/vibration/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: platform-capabilities@chromium.org -# COMPONENT: Blink>Vibration
diff --git a/third_party/blink/web_tests/external/wpt/visual-viewport/DIR_METADATA b/third_party/blink/web_tests/external/wpt/visual-viewport/DIR_METADATA new file mode 100644 index 0000000..4a2c8aa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/visual-viewport/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/visual-viewport/OWNERS b/third_party/blink/web_tests/external/wpt/visual-viewport/OWNERS index e7e04516..9f9aedfa 100644 --- a/third_party/blink/web_tests/external/wpt/visual-viewport/OWNERS +++ b/third_party/blink/web_tests/external/wpt/visual-viewport/OWNERS
@@ -1,4 +1 @@ -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input -# WPT-NOTIFY: true bokan@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/wasm/DIR_METADATA b/third_party/blink/web_tests/external/wpt/wasm/DIR_METADATA new file mode 100644 index 0000000..cb8992c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/wasm/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Blink>JavaScript>WebAssembly" +}
diff --git a/third_party/blink/web_tests/external/wpt/wasm/OWNERS b/third_party/blink/web_tests/external/wpt/wasm/OWNERS index 317ea70..633a0b1 100644 --- a/third_party/blink/web_tests/external/wpt/wasm/OWNERS +++ b/third_party/blink/web_tests/external/wpt/wasm/OWNERS
@@ -1,2 +1 @@ -# COMPONENT: Blink>JavaScript>WebAssembly binji@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/DIR_METADATA b/third_party/blink/web_tests/external/wpt/web-animations/DIR_METADATA new file mode 100644 index 0000000..d7b326b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>Animation" +} +team_email: "animations-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/OWNERS b/third_party/blink/web_tests/external/wpt/web-animations/OWNERS index 9bafb3b..50e5c84 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/OWNERS +++ b/third_party/blink/web_tests/external/wpt/web-animations/OWNERS
@@ -1,3 +1 @@ -# TEAM: animations-dev@chromium.org -# COMPONENT: Blink>Animation meade@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/web-locks/DIR_METADATA b/third_party/blink/web_tests/external/wpt/web-locks/DIR_METADATA new file mode 100644 index 0000000..cc6fcfa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-locks/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>Storage" +} +team_email: "storage-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/web-locks/OWNERS b/third_party/blink/web_tests/external/wpt/web-locks/OWNERS deleted file mode 100644 index 5ca6cf5f..0000000 --- a/third_party/blink/web_tests/external/wpt/web-locks/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -# TEAM: storage-dev@chromium.org -# COMPONENT: Blink>Storage
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/DIR_METADATA b/third_party/blink/web_tests/external/wpt/web-nfc/DIR_METADATA new file mode 100644 index 0000000..b409764 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-nfc/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>NFC" +} +team_email: "device-dev@chromium.org"
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/OWNERS b/third_party/blink/web_tests/external/wpt/web-nfc/OWNERS index 2a0e8201..0243a40 100644 --- a/third_party/blink/web_tests/external/wpt/web-nfc/OWNERS +++ b/third_party/blink/web_tests/external/wpt/web-nfc/OWNERS
@@ -1,4 +1,2 @@ -# TEAM: device-dev@chromium.org -# COMPONENT: Blink>NFC kenneth.r.christiansen@intel.com rijubrata.bhaumik@intel.com
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/DIR_METADATA b/third_party/blink/web_tests/external/wpt/webaudio/DIR_METADATA new file mode 100644 index 0000000..4130bdc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webaudio/DIR_METADATA
@@ -0,0 +1,6 @@ +monorail { + component: "Blink>WebAudio" +} +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/OWNERS b/third_party/blink/web_tests/external/wpt/webaudio/OWNERS index a4cc14b..a837fc9b 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/OWNERS +++ b/third_party/blink/web_tests/external/wpt/webaudio/OWNERS
@@ -1,4 +1,2 @@ -# COMPONENT: Blink>WebAudio -# WPT-NOTIFY: true hongchan@chromium.org rtoy@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/DIR_METADATA b/third_party/blink/web_tests/external/wpt/webauthn/DIR_METADATA new file mode 100644 index 0000000..177a021 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webauthn/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>WebAuthentication" +} +team_email: "identity-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/OWNERS b/third_party/blink/web_tests/external/wpt/webauthn/OWNERS index b694735f..bf4ea08 100644 --- a/third_party/blink/web_tests/external/wpt/webauthn/OWNERS +++ b/third_party/blink/web_tests/external/wpt/webauthn/OWNERS
@@ -1,6 +1,2 @@ file://device/fido/OWNERS nsatragno@chromium.org - -# COMPONENT: Blink>WebAuthentication -# TEAM: identity-dev@chromium.org -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/DIR_METADATA b/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/DIR_METADATA new file mode 100644 index 0000000..4a2c8aa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/DIR_METADATA
@@ -0,0 +1,7 @@ +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/OWNERS b/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/OWNERS deleted file mode 100644 index 1775c1c..0000000 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input -# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/webgpu/DIR_METADATA b/third_party/blink/web_tests/external/wpt/webgpu/DIR_METADATA new file mode 100644 index 0000000..1bd921c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webgpu/DIR_METADATA
@@ -0,0 +1,6 @@ +monorail { + component: "Blink>WebGPU" +} +wpt { + notify: YES +}
diff --git a/third_party/blink/web_tests/external/wpt/webgpu/OWNERS b/third_party/blink/web_tests/external/wpt/webgpu/OWNERS index 0902cf56..2e37d5e 100644 --- a/third_party/blink/web_tests/external/wpt/webgpu/OWNERS +++ b/third_party/blink/web_tests/external/wpt/webgpu/OWNERS
@@ -1,3 +1 @@ -# COMPONENT: Blink>WebGPU -# WPT-NOTIFY: true file://third_party/blink/renderer/modules/webgpu/OWNERS
diff --git a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/002.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/002.worker-expected.txt index 3e0b101..f37a7e7 100644 --- a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/002.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/002.worker-expected.txt
@@ -17,9 +17,9 @@ PASS The PageTransitionEvent interface object should not be exposed. PASS The DOMImplementation interface object should not be exposed. FAIL The ReadableStreamDefaultReader interface object should not be exposed. assert_false: expected false got true -PASS The ReadableStreamBYOBReader interface object should not be exposed. +FAIL The ReadableStreamBYOBReader interface object should not be exposed. assert_false: expected false got true PASS The ReadableStreamDefaultController interface object should not be exposed. -PASS The ReadableByteStreamController interface object should not be exposed. +FAIL The ReadableByteStreamController interface object should not be exposed. assert_false: expected false got true FAIL The WritableStreamDefaultWriter interface object should not be exposed. assert_false: expected false got true PASS The WritableStreamDefaultController interface object should not be exposed. PASS The IDBEnvironment interface object should not be exposed.
diff --git a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.sharedworker-expected.txt index 7e4635f..8d98263 100644 --- a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.sharedworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.sharedworker-expected.txt
@@ -15,9 +15,9 @@ PASS The HashChangeEvent interface object should not be exposed PASS The PageTransitionEvent interface object should not be exposed FAIL The ReadableStreamDefaultReader interface object should not be exposed assert_false: expected false got true -PASS The ReadableStreamBYOBReader interface object should not be exposed +FAIL The ReadableStreamBYOBReader interface object should not be exposed assert_false: expected false got true PASS The ReadableStreamDefaultController interface object should not be exposed -PASS The ReadableByteStreamController interface object should not be exposed +FAIL The ReadableByteStreamController interface object should not be exposed assert_false: expected false got true FAIL The WritableStreamDefaultWriter interface object should not be exposed assert_false: expected false got true PASS The WritableStreamDefaultController interface object should not be exposed PASS The IDBEnvironment interface object should not be exposed
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-1-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-1-expected.txt deleted file mode 100644 index 3e4dfa22..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-1-expected.txt +++ /dev/null
@@ -1,72 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: multipleVariableDeclarations -====== 8< ------ -var a = 1 - , b = {} - , c = 2 - , d = "hello world"; -var a, b, c, d = 2, e, f = 3; - ------- >8 ====== -Correct mapping for <{}> -Correct mapping for <hello> -Correct mapping for <;> - -Running: emptyObjectExpression -====== 8< ------ -var a = {} - ------- >8 ====== -Correct mapping for <{> -Correct mapping for <}> -Correct mapping for <a> - -Running: breakContinueStatements -====== 8< ------ -for (var i in set) - if (i % 2 === 0) - break; - else - continue; - ------- >8 ====== -Correct mapping for <break> -Correct mapping for <continue> -Correct mapping for <2> -Correct mapping for <else> - -Running: chainedIfStatements -====== 8< ------ -if (a % 7 === 0) - b = 1; -else if (a % 9 === 1) - b = 2; -else if (a % 5 === 3) { - b = a / 2; - b++; -} else - b = 3; - ------- >8 ====== -Correct mapping for <7> -Correct mapping for <9> -Correct mapping for <3> -Correct mapping for <++> - -Running: tryCatchStatement -====== 8< ------ -try { - a(b()); -} catch (e) { - f() -} finally { - f(); -} - ------- >8 ====== -Correct mapping for <try> -Correct mapping for <catch> -Correct mapping for <finally> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-1.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-1.js deleted file mode 100644 index 9bc0928..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-1.js +++ /dev/null
@@ -1,40 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('debugger/resources/obfuscated.js'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function multipleVariableDeclarations(next) { - var mappingQueries = ['{}', 'hello', ';']; - testJSFormatter('var a=1,b={},c=2,d="hello world";var a,b,c,d=2,e,f=3;', mappingQueries, next); - }, - - function emptyObjectExpression(next) { - var mappingQueries = ['{', '}', 'a']; - testJSFormatter('var a={}', mappingQueries, next); - }, - - function breakContinueStatements(next) { - var mappingQueries = ['break', 'continue', '2', 'else']; - testJSFormatter('for(var i in set)if(i%2===0)break;else continue;', mappingQueries, next); - }, - - function chainedIfStatements(next) { - var mappingQueries = ['7', '9', '3', '++']; - testJSFormatter( - 'if(a%7===0)b=1;else if(a%9===1) b = 2;else if(a%5===3){b=a/2;b++;} else b= 3;', mappingQueries, next); - }, - - function tryCatchStatement(next) { - var mappingQueries = ['try', 'catch', 'finally']; - testJSFormatter('try{a(b());}catch(e){f()}finally{f();}', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-10-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-10-expected.txt deleted file mode 100644 index 5999afb7..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-10-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: objectSpread -====== 8< ------ -const a = { - a: 4, - ...{ - a: 5, - b: 42 - } -}; - ------- >8 ====== -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-10.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-10.js deleted file mode 100644 index dd401786..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-10.js +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function objectSpread(next) { - var mappingQueries = []; - testJSFormatter('const a = {a:4,...{a: 5,b: 42}};', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-2-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-2-expected.txt deleted file mode 100644 index 627afa41..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-2-expected.txt +++ /dev/null
@@ -1,63 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: forLoopWithIfStatementWithoutBlockStatements -====== 8< ------ -for (var value of map) - if (value.length % 3 === 0) - console.log(value); - ------- >8 ====== -Correct mapping for <length> -Correct mapping for <console> -Correct mapping for <of> - -Running: objectExpressionProperties -====== 8< ------ -var mapping = { - original: [1, 2, 3], - formatted: [], - count: 0 -} - ------- >8 ====== -Correct mapping for <mapping> -Correct mapping for <original> -Correct mapping for <formatted> - -Running: blockFormatting -====== 8< ------ -{ - print(1); - print(2); -} - ------- >8 ====== -Correct mapping for <(1)> -Correct mapping for <(2)> - -Running: assignmentFormatting -====== 8< ------ -var exp = 'a string'; -c = +a + (0 > a ? b : 0); -c = (1); -var a = (1); - ------- >8 ====== -Correct mapping for <string> - -Running: objectLiteralFormatting -====== 8< ------ -var obj = { - 'foo': 1, - bar: "2", - cat: { - dog: '1989' - } -} - ------- >8 ====== -Correct mapping for <dog> -Correct mapping for <1989> -Correct mapping for <foo> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-2.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-2.js deleted file mode 100644 index 00879c8..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-2.js +++ /dev/null
@@ -1,39 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('debugger/resources/obfuscated.js'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function forLoopWithIfStatementWithoutBlockStatements(next) { - var mappingQueries = ['length', 'console', 'of']; - testJSFormatter('for(var value of map)if (value.length%3===0)console.log(value);', mappingQueries, next); - }, - - function objectExpressionProperties(next) { - var mappingQueries = ['mapping', 'original', 'formatted']; - testJSFormatter('var mapping={original:[1,2,3],formatted:[],count:0}', mappingQueries, next); - }, - - function blockFormatting(next) { - var mappingQueries = ['(1)', '(2)']; - testJSFormatter('{ print(1); print(2); }', mappingQueries, next); - }, - - function assignmentFormatting(next) { - var mappingQueries = ['string']; - testJSFormatter('var exp=\'a string\';c=+a+(0>a?b:0);c=(1);var a=(1);', mappingQueries, next); - }, - - function objectLiteralFormatting(next) { - var mappingQueries = ['dog', '1989', 'foo']; - testJSFormatter('var obj={\'foo\':1,bar:"2",cat:{dog:\'1989\'}}', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-3-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-3-expected.txt deleted file mode 100644 index c90de76..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-3-expected.txt +++ /dev/null
@@ -1,66 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: ifStatements -====== 8< ------ -if (a < b) - log(a); -else - log(b); -if (a < b) { - log(a) -} else { - log(b); -} -if (a === b) - log('equals'); -if (a !== b) { - log('non-eq'); -} - ------- >8 ====== -Correct mapping for <===> -Correct mapping for <!==> -Correct mapping for <non-eq> - -Running: arrayLiteralFormatting -====== 8< ------ -var arr = [3, 2, 1, 0] - ------- >8 ====== -Correct mapping for <3> -Correct mapping for <2> -Correct mapping for <1> -Correct mapping for <0> - -Running: ifFormatting -====== 8< ------ -if (a > b && b > c) { - print(a); - print(b); -} - ------- >8 ====== -Correct mapping for <&&> -Correct mapping for <print(a)> - -Running: ternarOperatorFormatting -====== 8< ------ -a > b ? a : b - ------- >8 ====== -Correct mapping for <?> -Correct mapping for <:> - -Running: labeledStatementFormatting -====== 8< ------ -firstLoop: while (true) { - break firstLoop; - continue firstLoop; -} - ------- >8 ====== -Correct mapping for <break> -Correct mapping for <continue> -Correct mapping for <while> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-3.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-3.js deleted file mode 100644 index dea1308..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-3.js +++ /dev/null
@@ -1,41 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('debugger/resources/obfuscated.js'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function ifStatements(next) { - var mappingQueries = ['===', '!==', 'non-eq']; - testJSFormatter( - 'if(a<b)log(a);else log(b);if(a<b){log(a)}else{log(b);}if(a===b)log(\'equals\');if(a!==b){log(\'non-eq\');}', - mappingQueries, next); - }, - - function arrayLiteralFormatting(next) { - var mappingQueries = ['3', '2', '1', '0']; - testJSFormatter('var arr=[3,2,1,0]', mappingQueries, next); - }, - - function ifFormatting(next) { - var mappingQueries = ['&&', 'print(a)']; - testJSFormatter('if(a>b&&b>c){print(a);print(b);}', mappingQueries, next); - }, - - function ternarOperatorFormatting(next) { - var mappingQueries = ['?', ':']; - testJSFormatter('a>b?a:b', mappingQueries, next); - }, - - function labeledStatementFormatting(next) { - var mappingQueries = ['break', 'continue', 'while']; - testJSFormatter('firstLoop:while(true){break firstLoop;continue firstLoop;}', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-4-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-4-expected.txt deleted file mode 100644 index 96f3d48..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-4-expected.txt +++ /dev/null
@@ -1,76 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: withStatementFormatting -====== 8< ------ -with (obj) - log('first'); -with (nice) { - log(1); - log(2); -} -done(); - ------- >8 ====== -Correct mapping for <first> -Correct mapping for <obj> -Correct mapping for <nice> -Correct mapping for <1> -Correct mapping for <2> -Correct mapping for <done> - -Running: switchStatementFormatting -====== 8< ------ -switch (a) { -case 1, 3: - log("odd"); - break; -case 2: - log("even"); - break; -case 42: -case 89: - log(a); -default: - log("interesting"); - log(a); -} -log("done"); - ------- >8 ====== -Correct mapping for <even> -Correct mapping for <odd> -Correct mapping for <89> -Correct mapping for <done> - -Running: whileFormatting -====== 8< ------ -while (true) { - print('infinity'); -} - ------- >8 ====== -Correct mapping for <while> -Correct mapping for <infinity> -Correct mapping for <);> - -Running: doWhileFormatting -====== 8< ------ -do { - print('infinity'); -} while (true); ------- >8 ====== -Correct mapping for <while> -Correct mapping for <infinity> - -Running: functionFormatting -====== 8< ------ -function test(a, b, c) { - a *= b; - return c + a; -} - ------- >8 ====== -Correct mapping for <return> -Correct mapping for <*=> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-4.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-4.js deleted file mode 100644 index f400481..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-4.js +++ /dev/null
@@ -1,41 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('debugger/resources/obfuscated.js'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function withStatementFormatting(next) { - var mappingQueries = ['first', 'obj', 'nice', '1', '2', 'done']; - testJSFormatter('with(obj)log(\'first\');with(nice){log(1);log(2);}done();', mappingQueries, next); - }, - - function switchStatementFormatting(next) { - var mappingQueries = ['even', 'odd', '89', 'done']; - testJSFormatter( - 'switch (a) { case 1, 3: log("odd");break;case 2:log("even");break;case 42:case 89: log(a);default:log("interesting");log(a);}log("done");', - mappingQueries, next); - }, - - function whileFormatting(next) { - var mappingQueries = ['while', 'infinity', ');']; - testJSFormatter('while(true){print(\'infinity\');}', mappingQueries, next); - }, - - function doWhileFormatting(next) { - var mappingQueries = ['while', 'infinity']; - testJSFormatter('do{print(\'infinity\');}while(true);', mappingQueries, next); - }, - - function functionFormatting(next) { - var mappingQueries = ['return', '*=']; - testJSFormatter('function test(a,b,c){a*=b;return c+a;}', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-5-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-5-expected.txt deleted file mode 100644 index be3d728..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-5-expected.txt +++ /dev/null
@@ -1,125 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: forInFormatting -====== 8< ------ -for (var key in myMap) - print(key); - ------- >8 ====== -Correct mapping for <myMap> -Correct mapping for <print> - -Running: forOfFormatting -====== 8< ------ -for (var value of myMap) - print(value); - ------- >8 ====== -Correct mapping for <myMap> -Correct mapping for <print> - -Running: commaBetweenStatementsFormatting -====== 8< ------ -rebuild(), -show(), -hasNew ? refresh() : noop(); - ------- >8 ====== -Correct mapping for <noop> -Correct mapping for <hasNew> - -Running: complexScriptFormatting -====== 8< ------ -function formatted1() { - var variable1 = 0; -} - -function withComments() { - // comment - return "functionWithComments"; -} - -try { - onmessage = function(event) { - var source = event.data; - var formattedSource = beautify(source); - var mapping = buildMapping(source, formattedSource); - postMessage({ - formattedSource: formattedSource, - mapping: mapping - }) - } - ; - function beautify(source) { - var ast = parse.parse(source); - var beautifyOptions = { - indent_level: 4, - indent_start: 0, - quote_keys: false, - space_colon: false - }; - return process.gen_code(ast, beautifyOptions) - } - function buildMapping(source, formattedSource) { - var mapping = { - original: [], - formatted: [] - }; - var lastPosition = 0; - var regexp = /(^|[^\\])\b((?=\D)[\$\.\w]+)\b/g; - while (true) { - var match = regexp.exec(formattedSource); - if (!match) - break; - var position = source.indexOf(match[2], lastPosition); - if (position === -1) - throw "No match found in original source for " + match[2]; - mapping.original.push(position); - mapping.formatted.push(match.index + match[1].length); - lastPosition = position + match[2].length - } - return mapping - } - function require() { - return parse - } - var exports = {}; - importScripts("UglifyJS/parse-js.js"); - var parse = exports; - var exports = {}; - importScripts("UglifyJS/process.js"); - var process = exports; -} catch (e) {} - -function formatted2() { - var variable2 = 0; -} - ------- >8 ====== -Correct mapping for <function> -Correct mapping for <formatted1> -Correct mapping for <variable1> -Correct mapping for < return "functionWithComments"> -Correct mapping for <onmessage> -Correct mapping for <indent_start> -Correct mapping for <function require> -Correct mapping for <var regexp> -Correct mapping for <importScripts> -Correct mapping for <formatted2> - -Running: ifStatementIndentRegression -====== 8< ------ -{ - if (a > b) { - a(); - pretty(); - } else if (a + b) - e(); - reset(); -} - ------- >8 ====== -Correct mapping for <pretty> -Correct mapping for <reset> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-5.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-5.js deleted file mode 100644 index 2d33571..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-5.js +++ /dev/null
@@ -1,46 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('debugger/resources/obfuscated.js'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function forInFormatting(next) { - var mappingQueries = ['myMap', 'print']; - testJSFormatter('for(var key in myMap)print(key);', mappingQueries, next); - }, - - function forOfFormatting(next) { - var mappingQueries = ['myMap', 'print']; - testJSFormatter('for(var value of myMap)print(value);', mappingQueries, next); - }, - - function commaBetweenStatementsFormatting(next) { - var mappingQueries = ['noop', 'hasNew']; - testJSFormatter('rebuild(),show(),hasNew?refresh():noop();', mappingQueries, next); - }, - - function complexScriptFormatting(next) { - SourcesTestRunner.showScriptSource('obfuscated.js', didShowScriptSource); - - function didShowScriptSource(sourceFrame) { - var mappingQueries = [ - 'function', 'formatted1', 'variable1', ' return "functionWithComments"', 'onmessage', 'indent_start', - 'function require', 'var regexp', 'importScripts', 'formatted2' - ]; - testJSFormatter(sourceFrame._textEditor.text(), mappingQueries, next); - } - }, - - function ifStatementIndentRegression(next) { - var mappingQueries = ['pretty', 'reset']; - testJSFormatter('{if (a>b){a();pretty();}else if (a+b)e();reset();}', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-6-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-6-expected.txt deleted file mode 100644 index ab1a048..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-6-expected.txt +++ /dev/null
@@ -1,101 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: trailingCommentsTest -====== 8< ------ -noop(); -//#sourceMappingURL=program.js.map - ------- >8 ====== - -Running: inlinedScriptFormatting -====== 8< ------ -<html> - <body> - <script> - function f() {} - </script> - <script> - function g() { - var a; - window.return = 10; - if (a) - return; - } - </script> - </body> -</html> - ------- >8 ====== - -Running: generatorFormatter -====== 8< ------ -function *max() { - var a = yield; - var b = yield 10; - if (a > b) - return a; - else - return b; -} - ------- >8 ====== -Correct mapping for <max> -Correct mapping for <*> -Correct mapping for <else> - -Running: blockCommentFormatter -====== 8< ------ -/** this - * is - * block - * comment - */ -var a = 10; - ------- >8 ====== -Correct mapping for <this> -Correct mapping for <is> -Correct mapping for <block> -Correct mapping for <comment> -Correct mapping for <var> -Correct mapping for <10> - -Running: lexicalScoping -====== 8< ------ -for (var i = 0; i < names.length; ++i) { - let name = names[i]; - let person = persons[i]; -} - ------- >8 ====== -Correct mapping for <for> -Correct mapping for <person> -Correct mapping for <name> -Correct mapping for <}> - -Running: anonimousFunctionAsParameter -====== 8< ------ -setTimeout(function() { - alert(1); -}, 2000); - ------- >8 ====== -Correct mapping for <setTimeout> -Correct mapping for <function> -Correct mapping for <alert> -Correct mapping for <2000> - -Running: arrowFunction -====== 8< ------ -function test(arg) { - console.log(arg); -} -test(a=>a + 2); - ------- >8 ====== -Correct mapping for <function> -Correct mapping for <console> -Correct mapping for <=>> -Correct mapping for <2> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-6.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-6.js deleted file mode 100644 index 26bf696c..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-6.js +++ /dev/null
@@ -1,53 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('debugger/resources/obfuscated.js'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function trailingCommentsTest(next) { - var mappingQueries = []; - testJSFormatter('noop(); //#sourceMappingURL=program.js.map', mappingQueries, next); - }, - - function inlinedScriptFormatting(next) { - var content = '<html><body><script>function f(){}<' + - '/script><script>function g(){var a;window.return = 10;if (a) return;}<' + - '/script></body></html>'; - SourcesTestRunner.testPrettyPrint('text/html', content, [], next); - }, - - function generatorFormatter(next) { - var mappingQueries = ['max', '*', 'else']; - testJSFormatter( - 'function *max(){var a=yield;var b=yield 10;if(a>b)return a;else return b;}', mappingQueries, next); - }, - - function blockCommentFormatter(next) { - var mappingQueries = ['this', 'is', 'block', 'comment', 'var', '10']; - testJSFormatter('/** this\n * is\n * block\n * comment\n */\nvar a=10;', mappingQueries, next); - }, - - function lexicalScoping(next) { - var mappingQueries = ['for', 'person', 'name', '}']; - testJSFormatter( - 'for(var i=0;i<names.length;++i){let name=names[i];let person=persons[i];}', mappingQueries, next); - }, - - function anonimousFunctionAsParameter(next) { - var mappingQueries = ['setTimeout', 'function', 'alert', '2000']; - testJSFormatter('setTimeout(function(){alert(1);},2000);', mappingQueries, next); - }, - - function arrowFunction(next) { - var mappingQueries = ['function', 'console', '=>', '2']; - testJSFormatter('function test(arg){console.log(arg);}test(a=>a+2);', mappingQueries, next); - } - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-7-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-7-expected.txt deleted file mode 100644 index 95982df..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-7-expected.txt +++ /dev/null
@@ -1,90 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: semicolonAfterFunctionExpression -====== 8< ------ -var onClick = function() { - console.log('click!'); -}; -console.log('done'); - ------- >8 ====== -Correct mapping for <onClick> -Correct mapping for <function> -Correct mapping for <console> -Correct mapping for <log> -Correct mapping for <click!> -Correct mapping for <done> - -Running: semicolonAfterMultipleFunctionExpressions -====== 8< ------ -var onStart = function() { - a(); -} - , onFinish = function() { - b(); -}; - ------- >8 ====== -Correct mapping for <onStart> -Correct mapping for <onFinish> -Correct mapping for <a()> -Correct mapping for <b()> - -Running: semicolonAfterEmptyFunctionExpressions -====== 8< ------ -var onStart = function() {} - , delay = 1000 - , belay = document.activeElement; - ------- >8 ====== -Correct mapping for <onStart> -Correct mapping for <delay> -Correct mapping for <1000> -Correct mapping for <belay> -Correct mapping for <activeElement> - -Running: continueStatementFormatting -====== 8< ------ -function foo() { - while (1) { - if (a) - continue; - test(); - } -} - ------- >8 ====== -Correct mapping for <function> -Correct mapping for <1> -Correct mapping for <continue> -Correct mapping for <test> - -Running: inconsistentSpaceAfterNull -====== 8< ------ -1 || null; - ------- >8 ====== -Correct mapping for <||> -Correct mapping for <null> -Correct mapping for <;> - -Running: squashMultipleNewlines -====== 8< ------ -a(); - -b(); - ------- >8 ====== -Correct mapping for <a> -Correct mapping for <b> - -Running: ensureExponentialOperator -====== 8< ------ -2 ** 3 - ------- >8 ====== -Correct mapping for <2> -Correct mapping for <**> -Correct mapping for <3> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-7.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-7.js deleted file mode 100644 index 000a4aaa..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-7.js +++ /dev/null
@@ -1,49 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function semicolonAfterFunctionExpression(next) { - var mappingQueries = ['onClick', 'function', 'console', 'log', 'click!', 'done']; - testJSFormatter( - 'var onClick = function() { console.log(\'click!\'); };console.log(\'done\');', mappingQueries, next); - }, - - function semicolonAfterMultipleFunctionExpressions(next) { - var mappingQueries = ['onStart', 'onFinish', 'a()', 'b()']; - testJSFormatter('var onStart = function() { a(); }, onFinish = function() { b(); };', mappingQueries, next); - }, - - function semicolonAfterEmptyFunctionExpressions(next) { - var mappingQueries = ['onStart', 'delay', '1000', 'belay', 'activeElement']; - testJSFormatter('var onStart = function() {}, delay=1000, belay=document.activeElement;', mappingQueries, next); - }, - - function continueStatementFormatting(next) { - var mappingQueries = ['function', '1', 'continue', 'test']; - testJSFormatter('function foo(){while(1){if (a)continue;test();}}', mappingQueries, next); - }, - - function inconsistentSpaceAfterNull(next) { - var mappingQueries = ['||', 'null', ';']; - testJSFormatter('1||null;', mappingQueries, next); - }, - - function squashMultipleNewlines(next) { - var mappingQueries = ['a', 'b']; - testJSFormatter('a();\n\n\n\n\n\n\n\n\nb();', mappingQueries, next); - }, - - function ensureExponentialOperator(next) { - var mappingQueries = ['2', '**', '3']; - testJSFormatter('2**3', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-8-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-8-expected.txt deleted file mode 100644 index 6c3f1cf..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-8-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: asyncAwaitSupport -====== 8< ------ -async function foo() { - return await Promise.resolve(1); -} - ------- >8 ====== -Correct mapping for <async> -Correct mapping for <function> -Correct mapping for <foo> -Correct mapping for <return> -Correct mapping for <Promise> -Correct mapping for <resolve> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-8.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-8.js deleted file mode 100644 index 90b4112..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-8.js +++ /dev/null
@@ -1,18 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function asyncAwaitSupport(next) { - var mappingQueries = ['async', 'function', 'foo', 'return', 'Promise', 'resolve']; - testJSFormatter('async function foo() {return await Promise.resolve(1);}', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-9-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-9-expected.txt deleted file mode 100644 index 100a911..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-9-expected.txt +++ /dev/null
@@ -1,38 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: parenthesizedExpressions -====== 8< ------ -if ((a)) - ((b)); -else - (c); - ------- >8 ====== -Correct mapping for <if> -Correct mapping for <((a))> -Correct mapping for <((b));> -Correct mapping for <else> -Correct mapping for <(c)> - -Running: objectDesctructuring -====== 8< ------ -let {x, y} = getXYFromTouchOrPointer(e); - ------- >8 ====== -Correct mapping for <let> -Correct mapping for <y> -Correct mapping for <getXYFromTouchOrPointer> -Correct mapping for <e> - -Running: objectDesctructuringInFunctionExpression -====== 8< ------ -var test = function({x, y}) { - foo(x, y); -} - ------- >8 ====== -Correct mapping for <test> -Correct mapping for <function> -Correct mapping for <foo> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-9.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-9.js deleted file mode 100644 index 448d5c63..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-9.js +++ /dev/null
@@ -1,28 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function parenthesizedExpressions(next) { - var mappingQueries = ['if', '((a))', '((b));', 'else', '(c)']; - testJSFormatter('if((a))((b));else (c);', mappingQueries, next); - }, - - function objectDesctructuring(next) { - var mappingQueries = ['let', 'y', 'getXYFromTouchOrPointer', 'e']; - testJSFormatter('let{x,y}=getXYFromTouchOrPointer(e);', mappingQueries, next); - }, - - function objectDesctructuringInFunctionExpression(next) { - var mappingQueries = ['test', 'function', 'foo']; - testJSFormatter('var test = function({x,y}){foo(x,y);}', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-classes-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-classes-expected.txt deleted file mode 100644 index 06080dc..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-classes-expected.txt +++ /dev/null
@@ -1,103 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: emptyClass -====== 8< ------ -class Test { -} - ------- >8 ====== -Correct mapping for <Test> -Correct mapping for <class> - -Running: emptyConstructor -====== 8< ------ -class Test { - constructor() {} -} - ------- >8 ====== -Correct mapping for <Test> -Correct mapping for <class> -Correct mapping for <constructor> - -Running: simpleClass -====== 8< ------ -class Test { - constructor() { - this.bar = 10; - } - givemebar() { - return this.bar; - } -} - ------- >8 ====== -Correct mapping for <Test> -Correct mapping for <class> -Correct mapping for <constructor> - -Running: extendedClass -====== 8< ------ -class Foo extends Bar { - constructor(name) { - super(name); - } - getName() { - return super.getName(); - } -} - ------- >8 ====== -Correct mapping for <Foo> -Correct mapping for <Bar> -Correct mapping for <extends> -Correct mapping for <super> -Correct mapping for <name> - -Running: twoConsecutiveClasses -====== 8< ------ -class A { -} -class B extends A { - constructor() { - super(); - } -} - ------- >8 ====== -Correct mapping for <B> -Correct mapping for <extends> -Correct mapping for <constructor> -Correct mapping for <super> - -Running: staticMethod -====== 8< ------ -class Employer { - static count() { - this._counter = (this._counter || 0) + 1; - return this._counter; - } -} - ------- >8 ====== -Correct mapping for <Employer> -Correct mapping for <static> -Correct mapping for <1> -Correct mapping for <return> - -Running: classExpression -====== 8< ------ -new (class { - constructor() { - debugger - } -} -) - ------- >8 ====== -Correct mapping for <new> -Correct mapping for <class> -Correct mapping for <constructor> -Correct mapping for <debugger> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-classes.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-classes.js deleted file mode 100644 index ad2bf4c..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-classes.js +++ /dev/null
@@ -1,53 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('debugger/resources/obfuscated.js'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function emptyClass(next) { - var mappingQueries = ['Test', 'class']; - testJSFormatter('class Test{}', mappingQueries, next); - }, - - function emptyConstructor(next) { - var mappingQueries = ['Test', 'class', 'constructor']; - testJSFormatter('class Test{constructor(){}}', mappingQueries, next); - }, - - function simpleClass(next) { - var mappingQueries = ['Test', 'class', 'constructor']; - testJSFormatter('class Test{constructor(){this.bar=10;}givemebar(){return this.bar;}}', mappingQueries, next); - }, - - function extendedClass(next) { - var mappingQueries = ['Foo', 'Bar', 'extends', 'super', 'name']; - testJSFormatter( - 'class Foo extends Bar{constructor(name){super(name);}getName(){return super.getName();}}', mappingQueries, - next); - }, - - function twoConsecutiveClasses(next) { - var mappingQueries = ['B', 'extends', 'constructor', 'super']; - testJSFormatter('class A{}class B extends A{constructor(){super();}}', mappingQueries, next); - }, - - function staticMethod(next) { - var mappingQueries = ['Employer', 'static', '1', 'return']; - testJSFormatter( - 'class Employer{static count(){this._counter = (this._counter || 0) + 1; return this._counter;}}', - mappingQueries, next); - }, - - function classExpression(next) { - var mappingQueries = ['new', 'class', 'constructor', 'debugger']; - testJSFormatter('new(class{constructor(){debugger}})', mappingQueries, next); - }, - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-template-literals-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-template-literals-expected.txt deleted file mode 100644 index 925409b..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-template-literals-expected.txt +++ /dev/null
@@ -1,51 +0,0 @@ -Verifies JavaScript pretty-printing functionality. - - -Running: simpleLiteral -====== 8< ------ -var foo = `bar`; - ------- >8 ====== -Correct mapping for <foo> -Correct mapping for <bar> - -Running: multilineLiteral -====== 8< ------ -var foo = `this -bar`; - ------- >8 ====== -Correct mapping for <foo> -Correct mapping for <bar> - -Running: stringSubstitution -====== 8< ------ -var a = `I have ${credit + cash}$`; - ------- >8 ====== -Correct mapping for <credit> -Correct mapping for <cash> - -Running: multipleStringSubstitution -====== 8< ------ -var a = `${name} has ${credit + cash}${currency ? currency : "$"}`; - ------- >8 ====== -Correct mapping for <credit> -Correct mapping for <cash> - -Running: taggedTemplate -====== 8< ------ -escapeHtml`<div class=${classnName} width=${a + b}/>`; - ------- >8 ====== -Correct mapping for <escapeHtml> -Correct mapping for <width> - -Running: escapedApostrophe -====== 8< ------ -var a=`That`s great!`; ------- >8 ====== -Correct mapping for <That> -Correct mapping for <great> -
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-template-literals.js b/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-template-literals.js deleted file mode 100644 index 9c97d7cb..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/sources/pretty-print-javascript-template-literals.js +++ /dev/null
@@ -1,44 +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. - -(async function() { - TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); - await TestRunner.loadModule('sources_test_runner'); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('debugger/resources/obfuscated.js'); - - var testJSFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/javascript'); - - TestRunner.runTestSuite([ - function simpleLiteral(next) { - var mappingQueries = ['foo', 'bar']; - testJSFormatter('var foo = `bar`;', mappingQueries, next); - }, - - function multilineLiteral(next) { - var mappingQueries = ['foo', 'bar']; - testJSFormatter('var foo = `this\nbar`;', mappingQueries, next); - }, - - function stringSubstitution(next) { - var mappingQueries = ['credit', 'cash']; - testJSFormatter('var a=`I have ${credit+cash}$`;', mappingQueries, next); - }, - - function multipleStringSubstitution(next) { - var mappingQueries = ['credit', 'cash']; - testJSFormatter('var a=`${name} has ${credit+cash}${currency?currency:"$"}`;', mappingQueries, next); - }, - - function taggedTemplate(next) { - var mappingQueries = ['escapeHtml', 'width']; - testJSFormatter('escapeHtml`<div class=${classnName} width=${a+b}/>`;', mappingQueries, next); - }, - - function escapedApostrophe(next) { - var mappingQueries = ['That', 'great']; - testJSFormatter('var a=`That\`s great!`;', mappingQueries, next); - } - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 8eb814b..8e2f361 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1278,6 +1278,14 @@ method receiveDatagrams method receiveStreams method sendDatagrams +interface ReadableByteStreamController + attribute @@toStringTag + getter byobRequest + getter desiredSize + method close + method constructor + method enqueue + method error interface ReadableStream attribute @@toStringTag getter locked @@ -1287,6 +1295,19 @@ method pipeThrough method pipeTo method tee +interface ReadableStreamBYOBReader + attribute @@toStringTag + getter closed + method cancel + method constructor + method read + method releaseLock +interface ReadableStreamBYOBRequest + attribute @@toStringTag + getter view + method constructor + method respond + method respondWithNewView interface ReadableStreamDefaultReader attribute @@toStringTag getter closed
diff --git a/third_party/blink/web_tests/http/tests/streams/chromium/get-reader-byob.html b/third_party/blink/web_tests/http/tests/streams/chromium/get-reader-byob.html deleted file mode 100644 index 61a03225..0000000 --- a/third_party/blink/web_tests/http/tests/streams/chromium/get-reader-byob.html +++ /dev/null
@@ -1,11 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -test(() => { - const rs = new ReadableStream(); - assert_throws_js(TypeError, () => rs.getReader({mode: 'byob'}), - 'a TypeError should be thrown'); -}, 'getReader() with mode "byob" should throw a TypeError'); -</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index a4ddbb8..0d43280 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -1262,6 +1262,14 @@ [Worker] method receiveDatagrams [Worker] method receiveStreams [Worker] method sendDatagrams +[Worker] interface ReadableByteStreamController +[Worker] attribute @@toStringTag +[Worker] getter byobRequest +[Worker] getter desiredSize +[Worker] method close +[Worker] method constructor +[Worker] method enqueue +[Worker] method error [Worker] interface ReadableStream [Worker] attribute @@toStringTag [Worker] getter locked @@ -1271,6 +1279,19 @@ [Worker] method pipeThrough [Worker] method pipeTo [Worker] method tee +[Worker] interface ReadableStreamBYOBReader +[Worker] attribute @@toStringTag +[Worker] getter closed +[Worker] method cancel +[Worker] method constructor +[Worker] method read +[Worker] method releaseLock +[Worker] interface ReadableStreamBYOBRequest +[Worker] attribute @@toStringTag +[Worker] getter view +[Worker] method constructor +[Worker] method respond +[Worker] method respondWithNewView [Worker] interface ReadableStreamDefaultReader [Worker] attribute @@toStringTag [Worker] getter closed
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 9ad654c..0203a5d7 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
@@ -6615,6 +6615,14 @@ method setStartBefore method surroundContents method toString +interface ReadableByteStreamController + attribute @@toStringTag + getter byobRequest + getter desiredSize + method close + method constructor + method enqueue + method error interface ReadableStream attribute @@toStringTag getter locked @@ -6624,6 +6632,19 @@ method pipeThrough method pipeTo method tee +interface ReadableStreamBYOBReader + attribute @@toStringTag + getter closed + method cancel + method constructor + method read + method releaseLock +interface ReadableStreamBYOBRequest + attribute @@toStringTag + getter view + method constructor + method respond + method respondWithNewView interface ReadableStreamDefaultReader attribute @@toStringTag getter closed
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index 014ca2839..678e6108 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -1167,6 +1167,14 @@ [Worker] method receiveDatagrams [Worker] method receiveStreams [Worker] method sendDatagrams +[Worker] interface ReadableByteStreamController +[Worker] attribute @@toStringTag +[Worker] getter byobRequest +[Worker] getter desiredSize +[Worker] method close +[Worker] method constructor +[Worker] method enqueue +[Worker] method error [Worker] interface ReadableStream [Worker] attribute @@toStringTag [Worker] getter locked @@ -1176,6 +1184,19 @@ [Worker] method pipeThrough [Worker] method pipeTo [Worker] method tee +[Worker] interface ReadableStreamBYOBReader +[Worker] attribute @@toStringTag +[Worker] getter closed +[Worker] method cancel +[Worker] method constructor +[Worker] method read +[Worker] method releaseLock +[Worker] interface ReadableStreamBYOBRequest +[Worker] attribute @@toStringTag +[Worker] getter view +[Worker] method constructor +[Worker] method respond +[Worker] method respondWithNewView [Worker] interface ReadableStreamDefaultReader [Worker] attribute @@toStringTag [Worker] getter closed
diff --git a/third_party/boringssl/DIR_METADATA b/third_party/boringssl/DIR_METADATA new file mode 100644 index 0000000..72c19cd --- /dev/null +++ b/third_party/boringssl/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Internals>Network>SSL" +} +team_email: "net-dev@chromium.org"
diff --git a/third_party/boringssl/OWNERS b/third_party/boringssl/OWNERS index 54fb4be..411f841 100644 --- a/third_party/boringssl/OWNERS +++ b/third_party/boringssl/OWNERS
@@ -2,6 +2,3 @@ davidben@chromium.org rsleevi@chromium.org svaldez@chromium.org - -# COMPONENT: Internals>Network>SSL -# TEAM: net-dev@chromium.org
diff --git a/third_party/bouncycastle/DIR_METADATA b/third_party/bouncycastle/DIR_METADATA new file mode 100644 index 0000000..5abea21 --- /dev/null +++ b/third_party/bouncycastle/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Test>Android" +}
diff --git a/third_party/bouncycastle/OWNERS b/third_party/bouncycastle/OWNERS index 8fd43ad6..d107d25c 100644 --- a/third_party/bouncycastle/OWNERS +++ b/third_party/bouncycastle/OWNERS
@@ -1,5 +1,3 @@ bjoyce@chromium.org hypan@google.com yzjr@google.com - -# COMPONENT: Test>Android
diff --git a/third_party/breakpad/DIR_METADATA b/third_party/breakpad/DIR_METADATA new file mode 100644 index 0000000..2028e515 --- /dev/null +++ b/third_party/breakpad/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Internals>CrashReporting" +} +team_email: "google-breakpad-dev@googlegroups.com"
diff --git a/third_party/breakpad/OWNERS b/third_party/breakpad/OWNERS index c70e545..d38d4ab 100644 --- a/third_party/breakpad/OWNERS +++ b/third_party/breakpad/OWNERS
@@ -1,5 +1,2 @@ mark@chromium.org thestig@chromium.org - -# TEAM: google-breakpad-dev@googlegroups.com -# COMPONENT: Internals>CrashReporting
diff --git a/third_party/brotli/DIR_METADATA b/third_party/brotli/DIR_METADATA new file mode 100644 index 0000000..be778358 --- /dev/null +++ b/third_party/brotli/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>WebFonts" +} +team_email: "loading-dev@chromium.org"
diff --git a/third_party/brotli/OWNERS b/third_party/brotli/OWNERS index 9416e2a3..458697e6 100644 --- a/third_party/brotli/OWNERS +++ b/third_party/brotli/OWNERS
@@ -1,5 +1,2 @@ ksakamoto@chromium.org bashi@chromium.org - -# COMPONENT: Blink>WebFonts -# TEAM: loading-dev@chromium.org
diff --git a/third_party/bspatch/DIR_METADATA b/third_party/bspatch/DIR_METADATA new file mode 100644 index 0000000..9123604d --- /dev/null +++ b/third_party/bspatch/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>Installer" +}
diff --git a/third_party/bspatch/OWNERS b/third_party/bspatch/OWNERS index c11ac94..e69de29 100644 --- a/third_party/bspatch/OWNERS +++ b/third_party/bspatch/OWNERS
@@ -1 +0,0 @@ -# COMPONENT: Internals>Installer
diff --git a/third_party/byte_buddy/DIR_METADATA b/third_party/byte_buddy/DIR_METADATA new file mode 100644 index 0000000..5abea21 --- /dev/null +++ b/third_party/byte_buddy/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Test>Android" +}
diff --git a/third_party/byte_buddy/OWNERS b/third_party/byte_buddy/OWNERS index 8fd43ad6..d107d25c 100644 --- a/third_party/byte_buddy/OWNERS +++ b/third_party/byte_buddy/OWNERS
@@ -1,5 +1,3 @@ bjoyce@chromium.org hypan@google.com yzjr@google.com - -# COMPONENT: Test>Android
diff --git a/third_party/ced/DIR_METADATA b/third_party/ced/DIR_METADATA new file mode 100644 index 0000000..cde4806c --- /dev/null +++ b/third_party/ced/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Blink>TextEncoding" +}
diff --git a/third_party/ced/OWNERS b/third_party/ced/OWNERS index 38383bf..885c9ea 100644 --- a/third_party/ced/OWNERS +++ b/third_party/ced/OWNERS
@@ -1,3 +1,2 @@ jinsukkim@chromium.org -jshin@chromium.org -# COMPONENT: Blink>TextEncoding +jshin@chromium.org \ No newline at end of file
diff --git a/third_party/chaijs/DIR_METADATA b/third_party/chaijs/DIR_METADATA new file mode 100644 index 0000000..8325efa --- /dev/null +++ b/third_party/chaijs/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>WebUI" +}
diff --git a/third_party/chaijs/OWNERS b/third_party/chaijs/OWNERS index ceda05c..241797ac 100644 --- a/third_party/chaijs/OWNERS +++ b/third_party/chaijs/OWNERS
@@ -1,2 +1 @@ -dpapad@chromium.org -# COMPONENT: UI>Browser>WebUI +dpapad@chromium.org \ No newline at end of file
diff --git a/third_party/chromevox/DIR_METADATA b/third_party/chromevox/DIR_METADATA new file mode 100644 index 0000000..299fade --- /dev/null +++ b/third_party/chromevox/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "UI>Accessibility" +} +team_email: "chromium-accessibility@chromium.org"
diff --git a/third_party/chromevox/OWNERS b/third_party/chromevox/OWNERS index 7d496ba..dfab84a0 100644 --- a/third_party/chromevox/OWNERS +++ b/third_party/chromevox/OWNERS
@@ -2,6 +2,3 @@ dmazzoni@chromium.org dtseng@chromium.org plundblad@chromium.org - -# TEAM: chromium-accessibility@chromium.org -# COMPONENT: UI>Accessibility
diff --git a/third_party/cld_3/DIR_METADATA b/third_party/cld_3/DIR_METADATA new file mode 100644 index 0000000..f750899 --- /dev/null +++ b/third_party/cld_3/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>Language>Translate" +}
diff --git a/third_party/cld_3/OWNERS b/third_party/cld_3/OWNERS index 8fc87a1..99c5de0 100644 --- a/third_party/cld_3/OWNERS +++ b/third_party/cld_3/OWNERS
@@ -1,3 +1,2 @@ andrewhayden@chromium.org -abakalov@chromium.org -# COMPONENT: UI>Browser>Language>Translate +abakalov@chromium.org \ No newline at end of file
diff --git a/third_party/closure_compiler/DIR_METADATA b/third_party/closure_compiler/DIR_METADATA new file mode 100644 index 0000000..8325efa --- /dev/null +++ b/third_party/closure_compiler/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>WebUI" +}
diff --git a/third_party/closure_compiler/OWNERS b/third_party/closure_compiler/OWNERS index 350e69a..e889f3e 100644 --- a/third_party/closure_compiler/OWNERS +++ b/third_party/closure_compiler/OWNERS
@@ -1,4 +1,3 @@ calamity@chromium.org dpapad@chromium.org -fukino@chromium.org -# COMPONENT: UI>Browser>WebUI +fukino@chromium.org \ No newline at end of file
diff --git a/third_party/closure_compiler/externs/DIR_METADATA b/third_party/closure_compiler/externs/DIR_METADATA new file mode 100644 index 0000000..8325efa --- /dev/null +++ b/third_party/closure_compiler/externs/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>WebUI" +}
diff --git a/third_party/closure_compiler/externs/OWNERS b/third_party/closure_compiler/externs/OWNERS index fa50a87..45dc7b4 100644 --- a/third_party/closure_compiler/externs/OWNERS +++ b/third_party/closure_compiler/externs/OWNERS
@@ -6,5 +6,4 @@ per-file automation.js=file://ui/accessibility/OWNERS per-file file_manager_private.js=file://ui/file_manager/OWNERS per-file input_method_private.js=file://ui/base/ime/OWNERS -per-file terminal_private.js=file://chrome/browser/chromeos/guest_os/OWNERS -# COMPONENT: UI>Browser>WebUI +per-file terminal_private.js=file://chrome/browser/chromeos/guest_os/OWNERS \ No newline at end of file
diff --git a/third_party/colorama/DIR_METADATA b/third_party/colorama/DIR_METADATA new file mode 100644 index 0000000..983ea01 --- /dev/null +++ b/third_party/colorama/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Tools" +}
diff --git a/third_party/colorama/OWNERS b/third_party/colorama/OWNERS index 32e3eca0..e69de29 100644 --- a/third_party/colorama/OWNERS +++ b/third_party/colorama/OWNERS
@@ -1 +0,0 @@ -# COMPONENT: Tools
diff --git a/third_party/crashpad/DIR_METADATA b/third_party/crashpad/DIR_METADATA new file mode 100644 index 0000000..ab965ef --- /dev/null +++ b/third_party/crashpad/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Internals>CrashReporting" +} +team_email: "crashpad-dev@chromium.org"
diff --git a/third_party/crashpad/OWNERS b/third_party/crashpad/OWNERS index fa76be3f..7c6c8b82 100644 --- a/third_party/crashpad/OWNERS +++ b/third_party/crashpad/OWNERS
@@ -11,6 +11,3 @@ mark@chromium.org rsesek@chromium.org scottmg@chromium.org - -# TEAM: crashpad-dev@chromium.org -# COMPONENT: Internals>CrashReporting
diff --git a/third_party/d3/DIR_METADATA b/third_party/d3/DIR_METADATA new file mode 100644 index 0000000..11910074 --- /dev/null +++ b/third_party/d3/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "OS>Systems>Diagnostics" +}
diff --git a/third_party/d3/OWNERS b/third_party/d3/OWNERS index 1cebebb..98e270d 100644 --- a/third_party/d3/OWNERS +++ b/third_party/d3/OWNERS
@@ -1,6 +1,3 @@ siggi@chromium.org chrisha@chromium.org joonbug@chromium.org - -# COMPONENT: Internals>ResourceCoordinator -# COMPONENT: OS>Systems>Diagnostics \ No newline at end of file
diff --git a/third_party/dav1d/DIR_METADATA b/third_party/dav1d/DIR_METADATA new file mode 100644 index 0000000..e7517784 --- /dev/null +++ b/third_party/dav1d/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>Media>Codecs" +}
diff --git a/third_party/dav1d/OWNERS b/third_party/dav1d/OWNERS index eace771..df9058b 100644 --- a/third_party/dav1d/OWNERS +++ b/third_party/dav1d/OWNERS
@@ -1,2 +1 @@ -# COMPONENT: Internals>Media>Codecs -file://media/OWNERS +file://media/OWNERS \ No newline at end of file
diff --git a/third_party/decklink/DIR_METADATA b/third_party/decklink/DIR_METADATA new file mode 100644 index 0000000..cb95d8a --- /dev/null +++ b/third_party/decklink/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>GetUserMedia" +} +team_email: "webrtc-dev@chromium.org"
diff --git a/third_party/decklink/OWNERS b/third_party/decklink/OWNERS index 4aa9f9c..7fb3670 100644 --- a/third_party/decklink/OWNERS +++ b/third_party/decklink/OWNERS
@@ -1,5 +1,2 @@ magjed@chromium.org tommi@chromium.org - -# TEAM: webrtc-dev@chromium.org -# COMPONENT: Blink>GetUserMedia
diff --git a/third_party/devscripts/DIR_METADATA b/third_party/devscripts/DIR_METADATA new file mode 100644 index 0000000..14b5edb --- /dev/null +++ b/third_party/devscripts/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals" +}
diff --git a/third_party/devscripts/OWNERS b/third_party/devscripts/OWNERS index 48b47ad0..17e4b81 100644 --- a/third_party/devscripts/OWNERS +++ b/third_party/devscripts/OWNERS
@@ -1,2 +1 @@ -thestig@chromium.org -# COMPONENT: Internals +thestig@chromium.org \ No newline at end of file
diff --git a/third_party/dom_distiller_js/DIR_METADATA b/third_party/dom_distiller_js/DIR_METADATA new file mode 100644 index 0000000..56645bbf --- /dev/null +++ b/third_party/dom_distiller_js/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "UI>Browser>ReaderMode" +} +team_email: "dom-distiller-eng@google.com"
diff --git a/third_party/dom_distiller_js/OWNERS b/third_party/dom_distiller_js/OWNERS index 0501554..c7686a9 100644 --- a/third_party/dom_distiller_js/OWNERS +++ b/third_party/dom_distiller_js/OWNERS
@@ -2,6 +2,3 @@ nyquist@chromium.org wychen@chromium.org yfriedman@chromium.org - -# COMPONENT: UI>Browser>ReaderMode -# TEAM: dom-distiller-eng@google.com
diff --git a/third_party/dpkg-shlibdeps/DIR_METADATA b/third_party/dpkg-shlibdeps/DIR_METADATA new file mode 100644 index 0000000..983ea01 --- /dev/null +++ b/third_party/dpkg-shlibdeps/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Tools" +}
diff --git a/third_party/dpkg-shlibdeps/OWNERS b/third_party/dpkg-shlibdeps/OWNERS index 65ca995..296dc0d 100644 --- a/third_party/dpkg-shlibdeps/OWNERS +++ b/third_party/dpkg-shlibdeps/OWNERS
@@ -1,4 +1,2 @@ thestig@chromium.org thomasanderson@chromium.org - -# COMPONENT: Tools
diff --git a/third_party/eigen3/DIR_METADATA b/third_party/eigen3/DIR_METADATA new file mode 100644 index 0000000..f21921424 --- /dev/null +++ b/third_party/eigen3/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>OptimizationGuide" +}
diff --git a/third_party/eigen3/OWNERS b/third_party/eigen3/OWNERS index f14a8b97..d9918ce6 100644 --- a/third_party/eigen3/OWNERS +++ b/third_party/eigen3/OWNERS
@@ -1,4 +1,3 @@ mcrouse@chromium.org sophiechang@chromium.org -tbansal@chromium.org -# COMPONENT: Internals>OptimizationGuide +tbansal@chromium.org \ No newline at end of file
diff --git a/third_party/emoji-segmenter/DIR_METADATA b/third_party/emoji-segmenter/DIR_METADATA new file mode 100644 index 0000000..7cf5d55 --- /dev/null +++ b/third_party/emoji-segmenter/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Blink>Fonts>Emoji" +}
diff --git a/third_party/emoji-segmenter/OWNERS b/third_party/emoji-segmenter/OWNERS index b937818..a0d6c05 100644 --- a/third_party/emoji-segmenter/OWNERS +++ b/third_party/emoji-segmenter/OWNERS
@@ -1,5 +1,3 @@ behdad@chromium.org drott@chromium.org eae@chromium.org - -# COMPONENT: Blink>Fonts>Emoji
diff --git a/third_party/espresso/DIR_METADATA b/third_party/espresso/DIR_METADATA new file mode 100644 index 0000000..5abea21 --- /dev/null +++ b/third_party/espresso/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Test>Android" +}
diff --git a/third_party/espresso/OWNERS b/third_party/espresso/OWNERS index 8fd43ad6..d107d25c 100644 --- a/third_party/espresso/OWNERS +++ b/third_party/espresso/OWNERS
@@ -1,5 +1,3 @@ bjoyce@chromium.org hypan@google.com yzjr@google.com - -# COMPONENT: Test>Android
diff --git a/third_party/expat/DIR_METADATA b/third_party/expat/DIR_METADATA new file mode 100644 index 0000000..a224a64 --- /dev/null +++ b/third_party/expat/DIR_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "Blink>XML" +} +team_email: "skia-discuss@googlegroups.com"
diff --git a/third_party/expat/OWNERS b/third_party/expat/OWNERS index 029bb66..ae8e6d3 100644 --- a/third_party/expat/OWNERS +++ b/third_party/expat/OWNERS
@@ -1,4 +1,2 @@ bungeman@chromium.org -dcheng@chromium.org -# COMPONENT: Blink>XML -# TEAM: skia-discuss@googlegroups.com +dcheng@chromium.org \ No newline at end of file
diff --git a/third_party/farmhash/DIR_METADATA b/third_party/farmhash/DIR_METADATA new file mode 100644 index 0000000..f21921424 --- /dev/null +++ b/third_party/farmhash/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>OptimizationGuide" +}
diff --git a/third_party/farmhash/OWNERS b/third_party/farmhash/OWNERS index f14a8b97..d9918ce6 100644 --- a/third_party/farmhash/OWNERS +++ b/third_party/farmhash/OWNERS
@@ -1,4 +1,3 @@ mcrouse@chromium.org sophiechang@chromium.org -tbansal@chromium.org -# COMPONENT: Internals>OptimizationGuide +tbansal@chromium.org \ No newline at end of file
diff --git a/third_party/protobuf/BUILD.gn b/third_party/protobuf/BUILD.gn index a916f19e..64add5c 100644 --- a/third_party/protobuf/BUILD.gn +++ b/third_party/protobuf/BUILD.gn
@@ -217,6 +217,14 @@ } } +source_set("delimited_mesage_util") { + sources = [ + "src/google/protobuf/util/delimited_message_util.cc", + "src/google/protobuf/util/delimited_message_util.h", + ] + deps = [ ":protobuf_lite" ] +} + # This is the full, heavy protobuf lib that's needed for c++ .protos that don't # specify the LITE_RUNTIME option. The protocol compiler itself (protoc) falls # into that category. Do not use in Chrome code.
diff --git a/third_party/protobuf/README.chromium b/third_party/protobuf/README.chromium index 4cc54da..ec90f30 100644 --- a/third_party/protobuf/README.chromium +++ b/third_party/protobuf/README.chromium
@@ -79,4 +79,9 @@ - 0022-Allow-deprecated-fields.patch - Allows depreacated fields to be used without extra C++ compiler warnings. \ No newline at end of file + Allows depreacated fields to be used without extra C++ compiler warnings. + +- 0023-fix-delimited-message-parsing.patch + + Fixes a bug in delimited message parsing and serialization, as fixed in + protobuf commit with hash bd9a7104e11740e4bcfbde46c190c2d908ef331a
diff --git a/third_party/protobuf/patches/0023-fix-delimited-message-parsing.patch b/third_party/protobuf/patches/0023-fix-delimited-message-parsing.patch new file mode 100644 index 0000000..808d476 --- /dev/null +++ b/third_party/protobuf/patches/0023-fix-delimited-message-parsing.patch
@@ -0,0 +1,63 @@ +diff --git a/src/google/protobuf/util/delimited_message_util.cc b/src/google/protobuf/util/delimited_message_util.cc +index 425dc2cfdff8..80cab309be3d 100644 +--- a/src/google/protobuf/util/delimited_message_util.cc ++++ b/src/google/protobuf/util/delimited_message_util.cc +@@ -74,12 +74,18 @@ bool ParseDelimitedFromCodedStream(MessageLite* message, + return false; + } + ++ // Get the position after any size bytes have been read (and only the message ++ // itself remains). ++ int position_after_size = input->CurrentPosition(); ++ + // Tell the stream not to read beyond that size. + io::CodedInputStream::Limit limit = input->PushLimit(size); + + // Parse the message. + if (!message->MergeFromCodedStream(input)) return false; + if (!input->ConsumedEntireMessage()) return false; ++ if (input->CurrentPosition() - position_after_size != static_cast<int>(size)) ++ return false; + + // Release the limit. + input->PopLimit(limit); +diff --git a/src/google/protobuf/util/delimited_message_util_test.cc b/src/google/protobuf/util/delimited_message_util_test.cc +index 9ed67784ee1c..9483a646e738 100644 +--- a/src/google/protobuf/util/delimited_message_util_test.cc ++++ b/src/google/protobuf/util/delimited_message_util_test.cc +@@ -82,6 +82,35 @@ TEST(DelimitedMessageUtilTest, DelimitedMessages) { + } + } + ++TEST(DelimitedMessageUtilTest, FailsAtEndOfStream) { ++ std::stringstream full_stream; ++ std::stringstream partial_stream; ++ ++ { ++ protobuf_unittest::ForeignMessage message; ++ message.set_c(42); ++ message.set_d(24); ++ EXPECT_TRUE(SerializeDelimitedToOstream(message, &full_stream)); ++ ++ std::string full_output = full_stream.str(); ++ ASSERT_GT(full_output.size(), size_t{2}); ++ ASSERT_EQ(full_output[0], 4); ++ ++ partial_stream << full_output[0] << full_output[1] << full_output[2]; ++ } ++ ++ { ++ bool clean_eof; ++ io::IstreamInputStream zstream(&partial_stream); ++ ++ protobuf_unittest::ForeignMessage message; ++ clean_eof = true; ++ EXPECT_FALSE(ParseDelimitedFromZeroCopyStream(&message, ++ &zstream, &clean_eof)); ++ EXPECT_FALSE(clean_eof); ++ } ++} ++ + } // namespace util + } // namespace protobuf + } // namespace google
diff --git a/third_party/protobuf/src/google/protobuf/util/delimited_message_util.cc b/third_party/protobuf/src/google/protobuf/util/delimited_message_util.cc index 425dc2cf..80cab309 100644 --- a/third_party/protobuf/src/google/protobuf/util/delimited_message_util.cc +++ b/third_party/protobuf/src/google/protobuf/util/delimited_message_util.cc
@@ -74,12 +74,18 @@ return false; } + // Get the position after any size bytes have been read (and only the message + // itself remains). + int position_after_size = input->CurrentPosition(); + // Tell the stream not to read beyond that size. io::CodedInputStream::Limit limit = input->PushLimit(size); // Parse the message. if (!message->MergeFromCodedStream(input)) return false; if (!input->ConsumedEntireMessage()) return false; + if (input->CurrentPosition() - position_after_size != static_cast<int>(size)) + return false; // Release the limit. input->PopLimit(limit);
diff --git a/third_party/protobuf/src/google/protobuf/util/delimited_message_util_test.cc b/third_party/protobuf/src/google/protobuf/util/delimited_message_util_test.cc index 9ed6778..9483a64 100644 --- a/third_party/protobuf/src/google/protobuf/util/delimited_message_util_test.cc +++ b/third_party/protobuf/src/google/protobuf/util/delimited_message_util_test.cc
@@ -82,6 +82,35 @@ } } +TEST(DelimitedMessageUtilTest, FailsAtEndOfStream) { + std::stringstream full_stream; + std::stringstream partial_stream; + + { + protobuf_unittest::ForeignMessage message; + message.set_c(42); + message.set_d(24); + EXPECT_TRUE(SerializeDelimitedToOstream(message, &full_stream)); + + std::string full_output = full_stream.str(); + ASSERT_GT(full_output.size(), size_t{2}); + ASSERT_EQ(full_output[0], 4); + + partial_stream << full_output[0] << full_output[1] << full_output[2]; + } + + { + bool clean_eof; + io::IstreamInputStream zstream(&partial_stream); + + protobuf_unittest::ForeignMessage message; + clean_eof = true; + EXPECT_FALSE(ParseDelimitedFromZeroCopyStream(&message, + &zstream, &clean_eof)); + EXPECT_FALSE(clean_eof); + } +} + } // namespace util } // namespace protobuf } // namespace google
diff --git a/third_party/zlib/google/zip_reader.cc b/third_party/zlib/google/zip_reader.cc index 8b4bb4a..96e9ff0 100644 --- a/third_party/zlib/google/zip_reader.cc +++ b/third_party/zlib/google/zip_reader.cc
@@ -10,10 +10,9 @@ #include "base/files/file.h" #include "base/logging.h" #include "base/macros.h" -#include "base/single_thread_task_runner.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/thread_task_runner_handle.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "build/build_config.h" #include "third_party/zlib/google/zip_internal.h" @@ -296,11 +295,11 @@ // If this is a directory, just create it and return. if (current_entry_info()->is_directory()) { if (base::CreateDirectory(output_file_path)) { - base::ThreadTaskRunnerHandle::Get()->PostTask( + base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, std::move(success_callback)); } else { DVLOG(1) << "Unzip failed: unable to create directory."; - base::ThreadTaskRunnerHandle::Get()->PostTask( + base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, std::move(failure_callback)); } return; @@ -308,16 +307,16 @@ if (unzOpenCurrentFile(zip_file_) != UNZ_OK) { DVLOG(1) << "Unzip failed: unable to open current zip entry."; - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - std::move(failure_callback)); + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, std::move(failure_callback)); return; } base::FilePath output_dir_path = output_file_path.DirName(); if (!base::CreateDirectory(output_dir_path)) { DVLOG(1) << "Unzip failed: unable to create containing directory."; - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - std::move(failure_callback)); + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, std::move(failure_callback)); return; } @@ -327,12 +326,12 @@ if (!output_file.IsValid()) { DVLOG(1) << "Unzip failed: unable to create platform file at " << output_file_path.value(); - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - std::move(failure_callback)); + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, std::move(failure_callback)); return; } - base::ThreadTaskRunnerHandle::Get()->PostTask( + base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&ZipReader::ExtractChunk, weak_ptr_factory_.GetWeakPtr(), Passed(std::move(output_file)), @@ -434,7 +433,7 @@ progress_callback.Run(current_progress); - base::ThreadTaskRunnerHandle::Get()->PostTask( + base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&ZipReader::ExtractChunk, weak_ptr_factory_.GetWeakPtr(), Passed(std::move(output_file)),
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d810b8e..f6cc4305 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -3446,6 +3446,13 @@ <int value="9" label="Timeout"/> </enum> +<enum name="ArcProvisioningCheckInError"> + <summary>Defines ARC GMS check-in failure reasons</summary> + <int value="1" label="Check-in failed"/> + <int value="2" label="Timeout"/> + <int value="3" label="Internal error"/> +</enum> + <!-- These values must be in sync with ProvisionConstants in CloudDPC code --> <enum name="ArcProvisioningCloudFlowError"> @@ -3487,6 +3494,9 @@ </enum> <enum name="ArcProvisioningResult"> + <obsolete> + Removed in Dec 2020. Replaced by ArcProvisioningStatus. + </obsolete> <summary>Defines Arc Provisioning success and failure reasons</summary> <int value="0" label="Success"/> <int value="1" label="Unclassified failure"/> @@ -3515,6 +3525,34 @@ <int value="24" label="Cloud provision flow failed"/> </enum> +<enum name="ArcProvisioningSignInError"> + <summary>Defines ARC GMS sign-in failure reasons</summary> + <int value="1" label="Network error"/> + <int value="2" label="Sign-in service unavailble"/> + <int value="3" label="Bad authentication"/> + <int value="4" label="Unknown error"/> + <int value="5" label="Timeout"/> + <int value="6" label="Internal error"/> +</enum> + +<enum name="ArcProvisioningStatus"> + <summary>Defines ARC GMS check-in failure reasons</summary> + <int value="0" label="Success"/> + <int value="1" label="Unclassified failure"/> + <int value="2" label="GMS sign-in failed"/> + <int value="3" label="GMS check-in failed"/> + <int value="4" label="Cloud provision flow failed"/> + <int value="5" label="Mojo version mistmached"/> + <int value="6" label="ARC provisioning timeout"/> + <int value="7" label="Chrome provisioning timeout"/> + <int value="8" label="ARC instance is stopped before complete provisioning"/> + <int value="9" label="Disabled"/> + <int value="10" label="Chrome server communication error"/> + <int value="11" label="Network is unavailable"/> + <int value="12" label="Unsupported account type"/> + <int value="13" label="Account is not present in Chrome"/> +</enum> + <enum name="ArcSdkVersionUpgradeType"> <summary>Defines the types of ARC SDK version upgrade</summary> <int value="0" label="NO_UPGRADE"/> @@ -16883,6 +16921,7 @@ <int value="2" label="Status Bar Issues Counter"/> <int value="3" label="Hamburger Menu"/> <int value="4" label="Adorner"/> + <int value="5" label="Command Menu"/> </enum> <enum name="DevToolsIssuesPanelResourceOpened"> @@ -30425,6 +30464,8 @@ <int value="3738" label="CrossOriginJsonTypeForScript"/> <int value="3739" label="SameOriginStrictNosniffWouldBlock"/> <int value="3740" label="CrossOriginStrictNosniffWouldBlock"/> + <int value="3741" label="CSSSelectorPseudoDir"/> + <int value="3742" label="CrossOriginSubframeWithoutEmbeddingControl"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -45333,6 +45374,7 @@ <int value="1343516821" label="ignore-previews-blocklist"/> <int value="1343713259" label="ArcPrintSpoolerExperiment:disabled"/> <int value="1344833841" label="ImeThread:enabled"/> + <int value="1345192233" label="VaapiVideoDecoder:enabled"/> <int value="1346994602" label="SyncPseudoUSSDictionary:enabled"/> <int value="1349100152" label="AutofillEnablePasswordInfoBarAccountIndicationFooter:disabled"/> @@ -45357,6 +45399,7 @@ <int value="1361073386" label="ContentSuggestionsNotifications:enabled"/> <int value="1363136936" label="VrCustomTabBrowsing:enabled"/> <int value="1363151585" label="SyncPseudoUSSAppList:enabled"/> + <int value="1367406392" label="VaapiVideoDecoder:disabled"/> <int value="1367467733" label="AutoplayIgnoreWebAudio:enabled"/> <int value="1367487214" label="VaapiJpegImageDecodeAcceleration:enabled"/> <int value="1367529437" label="NTPAssetDownloadSuggestions:enabled"/> @@ -50379,6 +50422,13 @@ <int value="8" label="Unsupported attachment type"/> </enum> +<enum name="NearbyShareVisibility"> + <int value="0" label="Unknown"/> + <int value="1" label="No one"/> + <int value="2" label="All contacts"/> + <int value="3" label="Selected contacts"/> +</enum> + <enum name="NearOomDetectionEndReason"> <obsolete> Removed in Feb 2020.
diff --git a/tools/metrics/histograms/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml index 60002d6..6e407c0 100644 --- a/tools/metrics/histograms/histograms_xml/android/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml
@@ -2432,7 +2432,7 @@ </histogram> <histogram name="Android.WebView.Gfx.HardwareDrawType" - enum="WebViewDrawAndSubmissionType" expires_after="2020-12-15"> + enum="WebViewDrawAndSubmissionType" expires_after="2021-06-15"> <owner>vasilyt@chromium.org</owner> <owner>boliu@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/arc/histograms.xml b/tools/metrics/histograms/histograms_xml/arc/histograms.xml index 076f8a03..d3a32b4 100644 --- a/tools/metrics/histograms/histograms_xml/arc/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/arc/histograms.xml
@@ -864,8 +864,20 @@ <summary>Time taken for ARC to render a PDF for print preview.</summary> </histogram> +<histogram base="true" name="Arc.Provisioning.CheckInError" + enum="ArcProvisioningCheckInError" expires_after="2021-12-01"> +<!-- Name completed by histogram_suffixes name="ArcUserTypes" --> + + <owner>mhasank@google.com</owner> + <owner>arc-core@google.com</owner> + <summary> + The error that occurred during GMS check-in operation. Recorded when ARC++ + provisioning flow fails. + </summary> +</histogram> + <histogram base="true" name="Arc.Provisioning.CloudFlowError" - enum="ArcProvisioningCloudFlowError" expires_after="2021-07-01"> + enum="ArcProvisioningCloudFlowError" expires_after="2021-12-01"> <!-- Name completed by histogram_suffixes name="ArcUserTypes" --> <owner>mhasank@google.com</owner> @@ -878,6 +890,9 @@ <histogram base="true" name="Arc.Provisioning.Result" enum="ArcProvisioningResult" expires_after="2021-07-01"> + <obsolete> + Removed in Dec 2020. Now reported as Arc.Provisioning.Status. + </obsolete> <!-- Name completed by histogram_suffixes name="ArcUserTypes" --> <owner>alexchau@google.com</owner> @@ -888,6 +903,27 @@ </summary> </histogram> +<histogram base="true" name="Arc.Provisioning.SignInError" + enum="ArcProvisioningSignInError" expires_after="2021-12-01"> +<!-- Name completed by histogram_suffixes name="ArcUserTypes" --> + + <owner>mhasank@google.com</owner> + <owner>arc-core@google.com</owner> + <summary> + The error that occured during GMS sign-in operation. Recorded when ARC++ + provisioning flow fails. + </summary> +</histogram> + +<histogram base="true" name="Arc.Provisioning.Status" + enum="ArcProvisioningStatus" expires_after="2021-12-01"> +<!-- Name completed by histogram_suffixes name="ArcUserTypes" --> + + <owner>mhasank@google.com</owner> + <owner>arc-core@google.com</owner> + <summary>The status (success or error) of ARC++ provisioning.</summary> +</histogram> + <histogram name="Arc.Provisioning.TimeDelta.Failure" units="ms" expires_after="2021-05-02"> <!-- Name completed by histogram_suffixes name="ArcUserTypes" --> @@ -911,11 +947,12 @@ </summary> </histogram> -<histogram name="Arc.Reauthorization.Result" enum="ArcProvisioningResult" +<histogram name="Arc.Reauthorization.Result" enum="ArcProvisioningStatus" expires_after="2021-02-07"> <!-- Name completed by histogram_suffixes name="ArcUserTypes" --> <owner>khmel@google.com</owner> + <owner>arc-core@gmail.com</owner> <summary> The result (success or the type of failure) of ARC reauthorization. </summary> @@ -978,7 +1015,7 @@ </summary> </histogram> -<histogram name="Arc.Secondary.Signin.Result" enum="ArcProvisioningResult" +<histogram name="Arc.Secondary.Signin.Result" enum="ArcProvisioningStatus" expires_after="2021-05-16"> <owner>sinhak@google.com</owner> <owner>jhorwich@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml index ea1d9d9..cde6379 100644 --- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -1023,8 +1023,11 @@ <affected-histogram name="Arc.PlayAutoInstallRequest.State"/> <affected-histogram name="Arc.PlayAutoInstallRequest.TimeDelta"/> <affected-histogram name="Arc.PlayStoreShown.TimeDelta"/> + <affected-histogram name="Arc.Provisioning.CheckInError"/> <affected-histogram name="Arc.Provisioning.CloudFlowError"/> <affected-histogram name="Arc.Provisioning.Result"/> + <affected-histogram name="Arc.Provisioning.SignInError"/> + <affected-histogram name="Arc.Provisioning.Status"/> <affected-histogram name="Arc.Provisioning.TimeDelta.Failure"/> <affected-histogram name="Arc.Provisioning.TimeDelta.Success"/> <affected-histogram name="Arc.Reauthorization.Result"/>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index 06b3dc03..af8b247 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -9984,6 +9984,17 @@ </token> </histogram> +<histogram name="Nearby.Share.VisibilityChoice" enum="NearbyShareVisibility" + expires_after="2021-08-19"> + <owner>nohle@chromium.org</owner> + <owner>better-together-dev@google.com</owner> + <summary> + Records the user's chosen degree of visibility to their contacts, selected + during onboarding or updated in settings. Emitted at login for users that + have Nearby Share enabled. + </summary> +</histogram> + <histogram name="net.HttpIdentSrcURL" units="requests" expires_after="M85"> <owner>tsepez@chromium.org</owner> <summary> @@ -11674,17 +11685,21 @@ </histogram> <histogram name="Privacy.CookieControlsSetting" enum="CookieControlsMode" - expires_after="M89"> + expires_after="never"> +<!-- expires-never: tracked as an important privacy metric. --> + <owner>dullweber@chromium.org</owner> <owner>huanzhong@chromium.org</owner> <summary> - Whether the cookie controls setting is enabled. Recorded at the Profile - startup. + Whether third-party cookies are blocked in incognito mode or completely. + Recorded at the Profile startup. </summary> </histogram> <histogram name="Privacy.DoNotTrackSetting" enum="BooleanEnabled" - expires_after="2021-05-16"> + expires_after="never"> +<!-- expires-never: tracked as an important privacy metric. --> + <owner>mkwst@chromium.org</owner> <owner>msramek@chromium.org</owner> <summary> @@ -11694,7 +11709,7 @@ </histogram> <histogram name="Privacy.ThirdPartyCookieBlockingEnabledForSite" enum="Boolean" - expires_after="M89"> + expires_after="M93"> <owner>dullweber@chromium.org</owner> <owner>huanzhong@chromium.org</owner> <summary> @@ -17708,7 +17723,7 @@ </histogram> <histogram name="WebsiteSettings.Action" enum="WebsiteSettingsAction" - expires_after="M90"> + expires_after="M93"> <owner>estark@chromium.org</owner> <owner>dullweber@chromium.org</owner> <summary>
diff --git a/tools/privacy_budget/blink_apis/BUILD.gn b/tools/privacy_budget/blink_apis/BUILD.gn index 4da17c0..5fba75b 100644 --- a/tools/privacy_budget/blink_apis/BUILD.gn +++ b/tools/privacy_budget/blink_apis/BUILD.gn
@@ -20,7 +20,8 @@ inputs = [ web_idl_database_filepath, "blink_api_proto.py", - "generate_blink_api_db.py" + "generate_blink_api_db.py", + "web_feature.py", ] output_data_file = "${root_build_dir}/blink_apis.textpb" outputs = [ output_data_file ] @@ -30,6 +31,10 @@ rebase_path(web_idl_database_filepath, root_build_dir), "--output", rebase_path(output_data_file, root_build_dir), + "--web_feature_mojom", + rebase_path( + "//third_party/blink/public/mojom/web_feature/web_feature.mojom", + root_build_dir), "--path", string_join(":", [
diff --git a/tools/privacy_budget/blink_apis/blink_api_proto.py b/tools/privacy_budget/blink_apis/blink_api_proto.py index 6830e93..e3ed7060 100644 --- a/tools/privacy_budget/blink_apis/blink_api_proto.py +++ b/tools/privacy_budget/blink_apis/blink_api_proto.py
@@ -14,10 +14,13 @@ """BlinkApiProto converts a WebIdlDatabase to a identifiability.blink_apis.Snapshot proto defined in proto/blink_apis.proto""" - def __init__(self, web_idl_pickle, proto_out_file, chromium_revision): + + def __init__(self, web_idl_pickle, proto_out_file, chromium_revision, + web_features): self.web_idl_database = web_idl.Database.read_from_file(web_idl_pickle) self.proto_out_file = proto_out_file self.snapshot = pb.Snapshot() + self.web_features = web_features if chromium_revision: self.snapshot.chromium_revision = chromium_revision @@ -41,7 +44,7 @@ for function in self.web_idl_database.callback_functions: self._ConvertIdlOperation(self.snapshot.callback_functions.add(), - function) + function, None) for interface in self.web_idl_database.callback_interfaces: self._ConvertIdlInterfaceLike( @@ -64,22 +67,43 @@ return pb.HIGH_ENTROPY_DIRECT assert False, "Unknown HighEntropy value {}".format(val) - def _GetUseCounter(self, parent, measure, measure_as): - if measure_as: - return measure_as.value - if measure: - use_counter = capitalize(parent.identifier) - if not isinstance(parent, web_idl.Interface): - use_counter = (capitalize(parent.owner.identifier) + '_' + - use_counter) - return use_counter - return None + def _GetUseCounter(self, member, parent, ext_attrs): + assert isinstance(ext_attrs, web_idl.ExtendedAttributes) + assert parent is None or hasattr(parent, 'identifier') + + if 'MeasureAs' in ext_attrs: + return ext_attrs.value_of('MeasureAs') + + if 'Measure' not in ext_attrs: + return None + + if parent is not None: + prefix = '%s_%s' % (capitalize( + parent.identifier), capitalize(member.identifier)) + else: + prefix = capitalize(member.identifier) + + suffix = "" + if isinstance(member, web_idl.FunctionLike): + if len(member.arguments) == 0 and member.is_getter: + suffix = "AttributeGetter" + elif len(member.arguments) == 1 and member.is_setter: + suffix = "AttributeSetter" + else: + suffix = "Method" + elif isinstance(member, web_idl.Attribute): + suffix = "AttributeGetter" + else: + assert False, repr(member) + + return "V8" + prefix + "_" + suffix def _ConvertIdlType(self, dest, idl_type): assert isinstance(idl_type, web_idl.IdlType) dest.idl_type_string = idl_type.type_name_without_extended_attributes - self._ConvertExtendedAttributes(dest.extended_attributes, idl_type) + self._ConvertExtendedAttributes(dest.extended_attributes, idl_type, + None) # Only look at named definitions. Simple, primitive types don't define # named identifiers. @@ -96,8 +120,8 @@ depends_on.remove(idl_type.type_name_without_extended_attributes) dest.depends_on[:] = list(depends_on) - def _ConvertExtendedAttributes(self, dest, parent): - attr = parent.extended_attributes + def _ConvertExtendedAttributes(self, dest, member, interface): + attr = member.extended_attributes assert isinstance(attr, web_idl.ExtendedAttributes) dest.cross_origin_isolated = ('CrossOriginIsolated' in attr) if 'Exposed' in attr: @@ -111,25 +135,27 @@ for v in exposed.values: e = dest.exposed.add() e.interface = v - e.member = parent.identifier + e.member = member.identifier setattr(dest, 'global', ('Global' in attr)) dest.same_object = ('SameObject' in attr) dest.secure_context = ('SecureContext' in attr) dest.high_entropy = self._GetHighEntropyType(attr.get('HighEntropy')) if 'Measure' in attr or 'MeasureAs' in attr: - dest.use_counter = self._GetUseCounter(parent, attr.get('Measure'), - attr.get('MeasureAs')) + dest.use_counter = self._GetUseCounter(member, interface, attr) + dest.use_counter_feature_value = self.web_features[ + dest.use_counter] if 'RuntimeEnabled' in attr: dest.runtime_enabled = attr.value_of('RuntimeEnabled') if 'ImplementedAs' in attr: dest.implemented_as = attr.value_of('ImplementedAs') - def _ConvertIdlAttribute(self, dest, attr): + def _ConvertIdlAttribute(self, dest, attr, interface): dest.name = attr.identifier dest.is_static = attr.is_static dest.is_readonly = attr.is_readonly - self._ConvertExtendedAttributes(dest.extended_attributes, attr) + self._ConvertExtendedAttributes(dest.extended_attributes, attr, + interface) self._ConvertIdlType(dest.idl_type, attr.idl_type) self._ConvertSourceLocation(dest.source_location, attr.debug_info) @@ -144,12 +170,13 @@ return pb.SPECIAL_OP_STRINGIFIER return pb.SPECIAL_OP_UNSPECIFIED - def _ConvertIdlOperation(self, dest, op): + def _ConvertIdlOperation(self, dest, op, parent): dest.name = op.identifier dest.static = op.is_static dest.special_op_type = self._GetSpecialOperationType(op) self._ConvertIdlType(dest.return_type, op.return_type) self._ConvertSourceLocation(dest.source_location, op.debug_info) + self._ConvertExtendedAttributes(dest.extended_attributes, op, parent) for arg in op.arguments: self._ConvertIdlType(dest.arguments.add(), arg.idl_type) @@ -158,30 +185,32 @@ dest.values[:] = enumer.values self._ConvertSourceLocation(dest.source_location, enumer.debug_info) - def _ConvertIdlConstant(self, dest, constant): + def _ConvertIdlConstant(self, dest, constant, parent): dest.name = constant.identifier dest.value = constant.value.literal - self._ConvertExtendedAttributes(dest.extended_attributes, constant) + self._ConvertExtendedAttributes(dest.extended_attributes, constant, + parent) self._ConvertIdlType(dest.idl_type, constant.idl_type) self._ConvertSourceLocation(dest.source_location, constant.debug_info) - def _ConvertIdlInterfaceLike(self, dest, interface): - dest.name = interface.identifier - if hasattr(interface, 'inherited') and interface.inherited: - dest.inherits_from = interface.inherited.identifier - self._ConvertExtendedAttributes(dest.extended_attributes, interface) - self._ConvertSourceLocation(dest.source_location, interface.debug_info) - for attr in interface.attributes: - self._ConvertIdlAttribute(dest.attributes.add(), attr) - for op in interface.operations: - self._ConvertIdlOperation(dest.operations.add(), op) - for constant in interface.constants: - self._ConvertIdlConstant(dest.constants.add(), constant) + def _ConvertIdlInterfaceLike(self, dest, parent): + dest.name = parent.identifier + if hasattr(parent, 'inherited') and parent.inherited: + dest.inherits_from = parent.inherited.identifier + self._ConvertExtendedAttributes(dest.extended_attributes, parent, None) + self._ConvertSourceLocation(dest.source_location, parent.debug_info) + for attr in parent.attributes: + self._ConvertIdlAttribute(dest.attributes.add(), attr, parent) + for op in parent.operations: + self._ConvertIdlOperation(dest.operations.add(), op, parent) + for constant in parent.constants: + self._ConvertIdlConstant(dest.constants.add(), constant, parent) - def _ConvertDictionaryMember(self, dest, member): + def _ConvertDictionaryMember(self, dest, member, interface): assert isinstance(member, web_idl.DictionaryMember) dest.name = member.identifier - self._ConvertExtendedAttributes(dest.extended_attributes, member) + self._ConvertExtendedAttributes(dest.extended_attributes, member, + interface) self._ConvertIdlType(dest.idl_type, member.idl_type) self._ConvertSourceLocation(dest.source_location, member.debug_info) @@ -193,7 +222,8 @@ if dictionary.inherited: dest.inherits_from = dictionary.inherited.identifier for member in dictionary.members: - self._ConvertDictionaryMember(dest.members.add(), member) + self._ConvertDictionaryMember(dest.members.add(), member, + dictionary) def _ConvertIdlTypedef(self, dest, typedef): assert isinstance(typedef, web_idl.Typedef) @@ -217,4 +247,5 @@ if source_file: dest.filename = source_file + dest.line = line_no
diff --git a/tools/privacy_budget/blink_apis/generate_blink_api_db.py b/tools/privacy_budget/blink_apis/generate_blink_api_db.py index 0a8d3de..98a25a59 100755 --- a/tools/privacy_budget/blink_apis/generate_blink_api_db.py +++ b/tools/privacy_budget/blink_apis/generate_blink_api_db.py
@@ -17,7 +17,6 @@ # > # # [VPYTHON:END] - """ Generate a database of Blink APIs. @@ -51,39 +50,44 @@ def parse_options(): - parser = argparse.ArgumentParser(description="%prog [options]") - parser.add_argument("--web_idl_database", - type=str, - help="filepath of the input database") - parser.add_argument("--output", type=str, help="filepath of output file") - parser.add_argument("--path", type=str, help="Additions to sys.path") - parser.add_argument( - "--chromium_revision", - type=str, - help="Chromium revision (git hash) for the source of Blink WebIDL DB") - args = parser.parse_args() + parser = argparse.ArgumentParser(description="%prog [options]") + parser.add_argument("--web_idl_database", + type=str, + help="filepath of the input database") + parser.add_argument("--web_feature_mojom", + type=str, + help="path of web_feature.mojom") + parser.add_argument("--output", type=str, help="filepath of output file") + parser.add_argument("--path", type=str, help="Additions to sys.path") + parser.add_argument( + "--chromium_revision", + type=str, + help="Chromium revision (git hash) for the source of Blink WebIDL DB") + args = parser.parse_args() - required_option_names = ("web_idl_database", "output") - for opt_name in required_option_names: - if getattr(args, opt_name) is None: - parser.error("--{} is a required option.".format(opt_name)) + required_option_names = ("web_idl_database", "output", "web_feature_mojom") + for opt_name in required_option_names: + if getattr(args, opt_name) is None: + parser.error("--{} is a required option.".format(opt_name)) - if args.path: - for p in args.path.split(':'): - sys.path.append(p) + if args.path: + for p in args.path.split(':'): + sys.path.append(p) - return args + return args def main(): - args = parse_options() + args = parse_options() - from blink_api_proto import BlinkApiProto - p = BlinkApiProto(args.web_idl_database, args.output, - args.chromium_revision) - p.Parse() - p.WriteTo(args.output) + from blink_api_proto import BlinkApiProto + from web_feature import WebFeature + w = WebFeature(args.web_feature_mojom) + p = BlinkApiProto(args.web_idl_database, args.output, + args.chromium_revision, w) + p.Parse() + p.WriteTo(args.output) if __name__ == '__main__': - main() + main()
diff --git a/tools/privacy_budget/blink_apis/proto/blink_apis.proto b/tools/privacy_budget/blink_apis/proto/blink_apis.proto index 87272e5..cba0a51 100644 --- a/tools/privacy_budget/blink_apis/proto/blink_apis.proto +++ b/tools/privacy_budget/blink_apis/proto/blink_apis.proto
@@ -40,6 +40,7 @@ // // The latter are described in: // https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLExtendedAttributes.md +// Next ID: 13 message ExtendedAttributes { // https://heycam.github.io/webidl/#CrossOriginIsolated bool cross_origin_isolated = 1; @@ -74,6 +75,9 @@ // https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLExtendedAttributes.md#measure_i_m_a_c string use_counter = 7; + // The numeric value of the Use Counter feature constant. + int64 use_counter_feature_value = 12; + // Value of [RuntimeEnabled] // https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLExtendedAttributes.md#runtimeenabled_i_m_a_c // Empty or undefined string is equivalent to there not being
diff --git a/tools/privacy_budget/blink_apis/web_feature.py b/tools/privacy_budget/blink_apis/web_feature.py new file mode 100644 index 0000000..249a5ec6 --- /dev/null +++ b/tools/privacy_budget/blink_apis/web_feature.py
@@ -0,0 +1,29 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import re + + +class WebFeature(object): + def __init__(self, web_feature_path): + assert os.path.isfile( + web_feature_path), "%s not found" % (web_feature_path) + + const_def = re.compile(r'\s*k(\w*)\s*=\s*(\d*)\s*,.*') + + self.features = {} + + with open(web_feature_path, 'r') as f: + for line in f.readlines(): + match = const_def.match(line) + if match: + self.features[match.group(1)] = int(match.group(2)) + + def __contains__(self, val): + return val in self.features + + def __getitem__(self, val): + assert val in self, "%s not in mojom" % (val) + return self.features[val]
diff --git a/ui/chromeos/file_manager_strings.grdp b/ui/chromeos/file_manager_strings.grdp index e1770b7..e2badd0 100644 --- a/ui/chromeos/file_manager_strings.grdp +++ b/ui/chromeos/file_manager_strings.grdp
@@ -871,6 +871,15 @@ <message name="IDS_FILE_BROWSER_DELETE_ERROR" desc="Message informing about error while deleting an item or items."> An error occurred. Some items may not have been deleted. </message> + <message name="IDS_FILE_BROWSER_RESTORE_FROM_TRASH_FILE_NAME" desc="File Manager status message shown when restoring items from trash / recycle bin."> + Restoring "<ph name="FILENAME">$1<ex>photo.jpg</ex></ph>"... + </message> + <message name="IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ITEMS_REMAINING" desc="File Manager status message shown when restoring items from trash / recycle bin. 'Item' is used here as a generic term for file or directory."> + Restoring <ph name="COUNT">$1<ex>10</ex></ph> items... + </message> + <message name="IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ERROR" desc="Message informing about error while restoring an item or items from the trash / recycle bin."> + An error occurred. Some items may not have been restored. + </message> <message name="IDS_FILE_BROWSER_COPY_PROGRESS_SUMMARY" desc="Summary message for multiple copying tasks above the progress bar."> Copying...
diff --git a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ERROR.png.sha1 b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ERROR.png.sha1 new file mode 100644 index 0000000..89c54252 --- /dev/null +++ b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ERROR.png.sha1
@@ -0,0 +1 @@ +42de77dc9621353c359adc8c7680cfdc3779fe02 \ No newline at end of file
diff --git a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_RESTORE_FROM_TRASH_FILE_NAME.png.sha1 b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_RESTORE_FROM_TRASH_FILE_NAME.png.sha1 new file mode 100644 index 0000000..ce408ad --- /dev/null +++ b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_RESTORE_FROM_TRASH_FILE_NAME.png.sha1
@@ -0,0 +1 @@ +c2db6f361fb7903ba2bc4a6358ca6789d637bfd6 \ No newline at end of file
diff --git a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ITEMS_REMAINING.png.sha1 b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ITEMS_REMAINING.png.sha1 new file mode 100644 index 0000000..60ff5838 --- /dev/null +++ b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_RESTORE_FROM_TRASH_ITEMS_REMAINING.png.sha1
@@ -0,0 +1 @@ +783c32c08aa357b08961501189b7258e54aa3406 \ No newline at end of file
diff --git a/ui/compositor/BUILD.gn b/ui/compositor/BUILD.gn index bc03547..9383a56 100644 --- a/ui/compositor/BUILD.gn +++ b/ui/compositor/BUILD.gn
@@ -69,8 +69,6 @@ "throughput_tracker.cc", "throughput_tracker.h", "throughput_tracker_host.h", - "total_animation_throughput_reporter.cc", - "total_animation_throughput_reporter.h", "transform_animation_curve_adapter.cc", "transform_animation_curve_adapter.h", "transform_recorder.cc", @@ -240,7 +238,6 @@ "layer_owner_unittest.cc", "layer_unittest.cc", "run_all_unittests.cc", - "total_animation_throughput_reporter_unittest.cc", "transform_animation_curve_adapter_unittest.cc", ]
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index d0ffe90..07c2a39 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -576,23 +576,13 @@ } void Compositor::AddAnimationObserver(CompositorAnimationObserver* observer) { - if (!animation_observer_list_.has_observers()) { - for (auto& obs : observer_list_) - obs.OnFirstAnimationStarted(this); - } animation_observer_list_.AddObserver(observer); host_->SetNeedsAnimate(); } void Compositor::RemoveAnimationObserver( CompositorAnimationObserver* observer) { - if (!animation_observer_list_.HasObserver(observer)) - return; animation_observer_list_.RemoveObserver(observer); - if (!animation_observer_list_.has_observers()) { - for (auto& obs : observer_list_) - obs.OnLastAnimationEnded(this); - } } bool Compositor::HasAnimationObserver(
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index f9bf9e1..bb08a017 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -409,7 +409,6 @@ private: friend class base::RefCounted<Compositor>; - friend class TotalAnimationThroughputReporter; // Called when collected metrics for the tracker of |tracker_id| is ready. void ReportMetricsForTracker(
diff --git a/ui/compositor/compositor_observer.h b/ui/compositor/compositor_observer.h index a14b75b5..32c6e49 100644 --- a/ui/compositor/compositor_observer.h +++ b/ui/compositor/compositor_observer.h
@@ -60,9 +60,6 @@ virtual void OnDidPresentCompositorFrame( uint32_t frame_token, const gfx::PresentationFeedback& feedback) {} - - virtual void OnFirstAnimationStarted(Compositor* compositor) {} - virtual void OnLastAnimationEnded(Compositor* compositor) {} }; } // namespace ui
diff --git a/ui/compositor/total_animation_throughput_reporter.cc b/ui/compositor/total_animation_throughput_reporter.cc deleted file mode 100644 index 2d85c436..0000000 --- a/ui/compositor/total_animation_throughput_reporter.cc +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/compositor/total_animation_throughput_reporter.h" - -#include "base/logging.h" -#include "ui/compositor/compositor.h" - -namespace ui { - -TotalAnimationThroughputReporter::TotalAnimationThroughputReporter( - ui::Compositor* compositor, - ReportOnceCallback once_callback, - bool should_delete) - : TotalAnimationThroughputReporter(compositor, - ReportRepeatingCallback(), - std::move(once_callback), - should_delete) {} - -TotalAnimationThroughputReporter::TotalAnimationThroughputReporter( - ui::Compositor* compositor, - ReportRepeatingCallback repeating_callback) - : TotalAnimationThroughputReporter(compositor, - repeating_callback, - ReportOnceCallback(), - /*should_delete=*/false) {} - -TotalAnimationThroughputReporter::~TotalAnimationThroughputReporter() { - if (throughput_tracker_) - throughput_tracker_->Cancel(); - if (compositor_) - compositor_->RemoveObserver(this); -} - -void TotalAnimationThroughputReporter::OnFirstAnimationStarted( - ui::Compositor* compositor) { - throughput_tracker_ = compositor->RequestNewThroughputTracker(); - throughput_tracker_->Start(base::BindRepeating( - &TotalAnimationThroughputReporter::Report, ptr_factory_.GetWeakPtr())); -} - -void TotalAnimationThroughputReporter::OnLastAnimationEnded( - ui::Compositor* compositor) { - throughput_tracker_->Stop(); - throughput_tracker_.reset(); -} - -void TotalAnimationThroughputReporter::OnCompositingShuttingDown( - ui::Compositor* compositor) { - if (throughput_tracker_) { - throughput_tracker_->Cancel(); - throughput_tracker_.reset(); - } - compositor->RemoveObserver(this); - compositor_ = nullptr; - if (should_delete_) - delete this; -} - -TotalAnimationThroughputReporter::TotalAnimationThroughputReporter( - ui::Compositor* compositor, - ReportRepeatingCallback repeating_callback, - ReportOnceCallback once_callback, - bool should_delete) - : compositor_(compositor), - report_repeating_callback_(repeating_callback), - report_once_callback_(std::move(once_callback)), - should_delete_(should_delete) { - DCHECK_NE(report_repeating_callback_.is_null(), - report_once_callback_.is_null()); - - compositor_->AddObserver(this); - if (compositor->animation_observer_list_.has_observers()) - OnFirstAnimationStarted(compositor_); -} - -void TotalAnimationThroughputReporter::Report( - const cc::FrameSequenceMetrics::CustomReportData& data) { - if (!report_once_callback_.is_null()) { - compositor_->RemoveObserver(this); - std::move(report_once_callback_).Run(data); - if (should_delete_) - delete this; - return; - } - if (!report_repeating_callback_.is_null()) - report_repeating_callback_.Run(data); -} - -} // namespace ui
diff --git a/ui/compositor/total_animation_throughput_reporter.h b/ui/compositor/total_animation_throughput_reporter.h deleted file mode 100644 index 6edc347..0000000 --- a/ui/compositor/total_animation_throughput_reporter.h +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_COMPOSITOR_TOTAL_ANIMATION_THROUGHPUT_REPORTER_H_ -#define UI_COMPOSITOR_TOTAL_ANIMATION_THROUGHPUT_REPORTER_H_ - -#include <memory> - -#include "base/callback_forward.h" -#include "base/memory/weak_ptr.h" -#include "base/optional.h" -#include "cc/metrics/frame_sequence_metrics.h" -#include "ui/compositor/compositor_export.h" -#include "ui/compositor/compositor_observer.h" -#include "ui/compositor/throughput_tracker.h" - -namespace ui { - -// Reports cc::FrameSequenceMetrics::ThroughputData between the first animation -// start and the last animation ends on a compositor. -// -// Please see AnimationThroughputReporter for the definition of the throughput -// and jack metrics. -// -// See also docs/speed/graphics_metrics_definitions.md. -// -// cc::FrameSequenceMetrics::CustomReportData contains the numbers of produced -// frames, expected frames and jank count. -// -// The tracking starts when the first animation observer is added to the -// compositor, then stopped when the last animation observer is removed. The -// report callback is invoked on the next begin frame if there is enough data. -// Since this observes multiple animations, aborting one of animations will -// not cancel the tracking, and the data will be reported as normal. -class COMPOSITOR_EXPORT TotalAnimationThroughputReporter - : public CompositorObserver { - public: - using ReportOnceCallback = base::OnceCallback<void( - const cc::FrameSequenceMetrics::CustomReportData& data)>; - using ReportRepeatingCallback = base::RepeatingCallback<void( - const cc::FrameSequenceMetrics::CustomReportData& data)>; - - // Create a TotalAnimationThroughputReporter that observes - // the total animation throughput just once. If |should_delete| - // is true, then the object will be deleted after callback is - // invoked. - TotalAnimationThroughputReporter(Compositor* compositor, - ReportOnceCallback callback, - bool should_delete); - - // Create a persistent TotalAnimationThroughputReporter, which - // will call the callback every time the last animation is finished. - TotalAnimationThroughputReporter(Compositor* compositor, - ReportRepeatingCallback callback); - - TotalAnimationThroughputReporter(const TotalAnimationThroughputReporter&) = - delete; - TotalAnimationThroughputReporter& operator=( - const TotalAnimationThroughputReporter&) = delete; - ~TotalAnimationThroughputReporter() override; - - // CompositorObserver: - void OnFirstAnimationStarted(Compositor* compositor) override; - void OnLastAnimationEnded(Compositor* compositor) override; - void OnCompositingShuttingDown(Compositor* compositor) override; - - bool IsMeasuringForTesting() const { return bool{throughput_tracker_}; } - - private: - TotalAnimationThroughputReporter(Compositor* compositor, - ReportRepeatingCallback repeating_callback, - ReportOnceCallback once_callback, - bool should_delete); - - void Report(const cc::FrameSequenceMetrics::CustomReportData& data); - - Compositor* compositor_; - ReportRepeatingCallback report_repeating_callback_; - ReportOnceCallback report_once_callback_; - bool should_delete_ = false; - base::Optional<ThroughputTracker> throughput_tracker_; - - base::WeakPtrFactory<TotalAnimationThroughputReporter> ptr_factory_{this}; -}; - -} // namespace ui - -#endif // UI_COMPOSITOR_TOTAL_ANIMATION_THROUGHPUT_REPORTER_H_
diff --git a/ui/compositor/total_animation_throughput_reporter_unittest.cc b/ui/compositor/total_animation_throughput_reporter_unittest.cc deleted file mode 100644 index 9b61549..0000000 --- a/ui/compositor/total_animation_throughput_reporter_unittest.cc +++ /dev/null
@@ -1,380 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/compositor/total_animation_throughput_reporter.h" - -#include <memory> - -#include "base/run_loop.h" -#include "base/test/bind.h" -#include "base/time/time.h" -#include "build/build_config.h" -#include "cc/metrics/frame_sequence_metrics.h" -#include "ui/compositor/layer.h" -#include "ui/compositor/layer_animation_sequence.h" -#include "ui/compositor/layer_animator.h" -#include "ui/compositor/scoped_layer_animation_settings.h" -#include "ui/compositor/test/animation_throughput_reporter_test_base.h" -#include "ui/gfx/geometry/rect.h" - -#if defined(OS_WIN) -// TestCompositor doesn't work with MOCK_TIME on Windows. crbug.com/1152103 -#define MAYBE_SingleAnimation DISABLED_SingleAnimation -#define MAYBE_StopAnimation DISABLED_StopAnimation -#define MAYBE_MultipleAnimations DISABLED_MultipleAnimations -#define MAYBE_MultipleAnimationsOnSingleLayer \ - DISABLED_MultipleAnimationsOnSingleLayer -#define MAYBE_AddAnimationWhileAnimating DISABLED_AddAnimationWhileAnimating -#define MAYBE_RemoveWhileAnimating DISABLED_RemoveWhileAnimating -#define MAYBE_StartWhileAnimating DISABLED_StartWhileAnimating -#define MAYBE_PersistedAnimation DISABLED_PersistedAnimation -#define MAYBE_OnceReporter DISABLED_OnceReporter -#define MAYBE_OnceReporterShouldDelete DISABLED_OnceReporterShouldDelete -#else -#define MAYBE_SingleAnimation SingleAnimation -#define MAYBE_StopAnimation StopAnimation -#define MAYBE_MultipleAnimations MultipleAnimations -#define MAYBE_MultipleAnimationsOnSingleLayer MultipleAnimationsOnSingleLayer -#define MAYBE_AddAnimationWhileAnimating AddAnimationWhileAnimating -#define MAYBE_RemoveWhileAnimating RemoveWhileAnimating -#define MAYBE_StartWhileAnimating StartWhileAnimating -#define MAYBE_PersistedAnimation PersistedAnimation -#define MAYBE_OnceReporter OnceReporter -#define MAYBE_OnceReporterShouldDelete OnceReporterShouldDelete -#endif - -namespace ui { -namespace { - -class TestReporter : public TotalAnimationThroughputReporter { - public: - explicit TestReporter(ui::Compositor* compositor) - : ui::TotalAnimationThroughputReporter( - compositor, - base::BindRepeating(&TestReporter::Reported, - base::Unretained(this))) {} - TestReporter(ui::Compositor* compositor, bool should_delete) - : ui::TotalAnimationThroughputReporter( - compositor, - base::BindOnce(&TestReporter::Reported, base::Unretained(this)), - should_delete) {} - - TestReporter(const TestReporter&) = delete; - TestReporter& operator=(const TestReporter&) = delete; - ~TestReporter() override = default; - - bool reported() const { return reported_; } - - void reset() { reported_ = false; } - - private: - void Reported(const cc::FrameSequenceMetrics::CustomReportData&) { - reported_ = true; - } - - bool reported_ = false; -}; - -} // namespace - -using TotalAnimationThroughputReporterTest = - AnimationThroughputReporterTestBase; - -TEST_F(TotalAnimationThroughputReporterTest, MAYBE_SingleAnimation) { - Layer layer; - layer.SetOpacity(0.5f); - root_layer()->Add(&layer); - - TestReporter reporter(compositor()); - { - LayerAnimator* animator = layer.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(48)); - layer.SetOpacity(1.0f); - } - Advance(base::TimeDelta::FromMilliseconds(32)); - EXPECT_FALSE(reporter.reported()); - Advance(base::TimeDelta::FromMilliseconds(32)); - EXPECT_TRUE(reporter.reported()); -} - -// Tests the stopping last animation will trigger the animation. -TEST_F(TotalAnimationThroughputReporterTest, MAYBE_StopAnimation) { - Layer layer; - layer.SetOpacity(0.5f); - root_layer()->Add(&layer); - - TestReporter reporter(compositor()); - { - LayerAnimator* animator = layer.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(48)); - layer.SetOpacity(1.0f); - } - - Advance(base::TimeDelta::FromMilliseconds(16)); - EXPECT_FALSE(reporter.reported()); - layer.GetAnimator()->StopAnimating(); - Advance(base::TimeDelta::FromMilliseconds(16)); - EXPECT_TRUE(reporter.reported()); -} - -// Tests the longest animation will trigger the report. -TEST_F(TotalAnimationThroughputReporterTest, MAYBE_MultipleAnimations) { - Layer layer1; - layer1.SetOpacity(0.5f); - root_layer()->Add(&layer1); - - TestReporter reporter(compositor()); - { - LayerAnimator* animator = layer1.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(48)); - layer1.SetOpacity(1.0f); - } - Layer layer2; - layer2.SetOpacity(0.5f); - root_layer()->Add(&layer2); - - { - LayerAnimator* animator = layer2.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(96)); - layer2.SetOpacity(1.0f); - } - - Advance(base::TimeDelta::FromMilliseconds(32)); - EXPECT_FALSE(reporter.reported()); - Advance(base::TimeDelta::FromMilliseconds(32)); - EXPECT_FALSE(reporter.reported()); - Advance(base::TimeDelta::FromMilliseconds(200)); - EXPECT_TRUE(reporter.reported()); -} - -// Tests the longest animation on a single layer will triger the report. -TEST_F(TotalAnimationThroughputReporterTest, - MAYBE_MultipleAnimationsOnSingleLayer) { - Layer layer; - layer.SetOpacity(0.5f); - layer.SetLayerBrightness(0.5f); - root_layer()->Add(&layer); - - TestReporter reporter(compositor()); - { - LayerAnimator* animator = layer.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(48)); - layer.SetOpacity(1.0f); - } - { - LayerAnimator* animator = layer.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(96)); - layer.SetLayerBrightness(1.0f); - } - - Advance(base::TimeDelta::FromMilliseconds(64)); - EXPECT_FALSE(reporter.reported()); - Advance(base::TimeDelta::FromMilliseconds(48)); - EXPECT_TRUE(reporter.reported()); -} - -// Tests adding new animation will extends the duration. -TEST_F(TotalAnimationThroughputReporterTest, MAYBE_AddAnimationWhileAnimating) { - Layer layer1; - layer1.SetOpacity(0.5f); - root_layer()->Add(&layer1); - - TestReporter reporter(compositor()); - { - LayerAnimator* animator = layer1.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(48)); - layer1.SetOpacity(1.0f); - } - - Advance(base::TimeDelta::FromMilliseconds(32)); - EXPECT_FALSE(reporter.reported()); - - // Add new animation while animating. - Layer layer2; - layer2.SetOpacity(0.5f); - root_layer()->Add(&layer2); - - { - LayerAnimator* animator = layer2.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(48)); - layer2.SetOpacity(1.0f); - } - - // The animation time is extended. - Advance(base::TimeDelta::FromMilliseconds(32)); - EXPECT_FALSE(reporter.reported()); - - Advance(base::TimeDelta::FromMilliseconds(32)); - EXPECT_TRUE(reporter.reported()); -} - -// Tests removing last animation will call report callback. -TEST_F(TotalAnimationThroughputReporterTest, MAYBE_RemoveWhileAnimating) { - auto layer1 = std::make_unique<Layer>(); - layer1->SetOpacity(0.5f); - root_layer()->Add(layer1.get()); - - TestReporter reporter(compositor()); - { - LayerAnimator* animator = layer1->GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100)); - layer1->SetOpacity(1.0f); - } - - Layer layer2; - layer2.SetOpacity(0.5f); - root_layer()->Add(&layer2); - - { - LayerAnimator* animator = layer2.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(48)); - layer2.SetOpacity(1.0f); - } - Advance(base::TimeDelta::FromMilliseconds(48)); - EXPECT_FALSE(reporter.reported()); - layer1.reset(); - // Aborting will be processed in next frame. - Advance(base::TimeDelta::FromMilliseconds(16)); - EXPECT_TRUE(reporter.reported()); -} - -// Make sure the reporter can start measuring even if the animation -// has started. -TEST_F(TotalAnimationThroughputReporterTest, MAYBE_StartWhileAnimating) { - Layer layer; - layer.SetOpacity(0.5f); - root_layer()->Add(&layer); - - { - LayerAnimator* animator = layer.GetAnimator(); - - ScopedLayerAnimationSettings settings(animator); - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(48)); - layer.SetOpacity(1.0f); - } - Advance(base::TimeDelta::FromMilliseconds(16)); - - TestReporter reporter(compositor()); - EXPECT_TRUE(reporter.IsMeasuringForTesting()); - Advance(base::TimeDelta::FromMilliseconds(100)); - EXPECT_TRUE(reporter.reported()); -} - -// Tests the reporter is called multiple times for persistent animation. -TEST_F(TotalAnimationThroughputReporterTest, MAYBE_PersistedAnimation) { - Layer layer; - layer.SetOpacity(0.5f); - root_layer()->Add(&layer); - - // Set a persisted animator to |layer|. - LayerAnimator* animator = - new LayerAnimator(base::TimeDelta::FromMilliseconds(48)); - layer.SetAnimator(animator); - - // |reporter| keeps reporting as long as it is alive. - TestReporter reporter(compositor()); - - // Report data for animation of opacity goes to 1. - layer.SetOpacity(1.0f); - Advance(base::TimeDelta::FromMilliseconds(100)); - EXPECT_TRUE(reporter.reported()); - - // Report data for animation of opacity goes to 0.5. - reporter.reset(); - layer.SetOpacity(0.5f); - Advance(base::TimeDelta::FromMilliseconds(100)); - EXPECT_TRUE(reporter.reported()); -} - -// Make sure the once reporter is called only once. -TEST_F(TotalAnimationThroughputReporterTest, MAYBE_OnceReporter) { - Layer layer; - layer.SetOpacity(0.5f); - root_layer()->Add(&layer); - - // Set a persisted animator to |layer|. - LayerAnimator* animator = - new LayerAnimator(base::TimeDelta::FromMilliseconds(32)); - layer.SetAnimator(animator); - - TestReporter reporter(compositor(), /*should_delete=*/false); - - // Report data for animation of opacity goes to 1. - layer.SetOpacity(1.0f); - Advance(base::TimeDelta::FromMilliseconds(100)); - EXPECT_TRUE(reporter.reported()); - - // Report data for animation of opacity goes to 0.5. - reporter.reset(); - layer.SetOpacity(1.0f); - Advance(base::TimeDelta::FromMilliseconds(100)); - EXPECT_FALSE(reporter.reported()); -} - -// One reporter marked as "should_delete" should be deleted when -// reported. -TEST_F(TotalAnimationThroughputReporterTest, MAYBE_OnceReporterShouldDelete) { - class DeleteTestReporter : public TotalAnimationThroughputReporter { - public: - DeleteTestReporter(Compositor* compositor, - ReportOnceCallback callback, - bool* deleted) - : TotalAnimationThroughputReporter(compositor, - std::move(callback), - true), - deleted_(deleted) {} - ~DeleteTestReporter() override { *deleted_ = true; } - - private: - bool* deleted_; - }; - - Layer layer; - layer.SetOpacity(0.5f); - root_layer()->Add(&layer); - - // Set a persisted animator to |layer|. - LayerAnimator* animator = - new LayerAnimator(base::TimeDelta::FromMilliseconds(32)); - layer.SetAnimator(animator); - - // |reporter| keeps reporting as long as it is alive. - bool reported = false; - bool deleted = false; - new DeleteTestReporter( - compositor(), - base::BindLambdaForTesting( - [&](const cc::FrameSequenceMetrics::CustomReportData&) { - reported = true; - }), - &deleted); - - // Report data for animation of opacity goes to 1. - layer.SetOpacity(1.0f); - Advance(base::TimeDelta::FromMilliseconds(100)); - EXPECT_TRUE(reported); - EXPECT_TRUE(deleted); -} - -} // namespace ui
diff --git a/ui/file_manager/externs/background/file_operation_manager.js b/ui/file_manager/externs/background/file_operation_manager.js index 8436bdf..0a7c74c 100644 --- a/ui/file_manager/externs/background/file_operation_manager.js +++ b/ui/file_manager/externs/background/file_operation_manager.js
@@ -66,9 +66,9 @@ deleteEntries(entries) {} /** - * Restores files from trash. + * Schedules the files to be restored. * - * @param {Array<!FilesAppEntry>} entries The trash entries. + * @param {!Array<!FilesAppEntry>} entries The trash entries. */ restoreDeleted(entries) {}
diff --git a/ui/file_manager/file_manager/background/js/file_operation_handler.js b/ui/file_manager/file_manager/background/js/file_operation_handler.js index 67dda3a4..48a2408 100644 --- a/ui/file_manager/file_manager/background/js/file_operation_handler.js +++ b/ui/file_manager/file_manager/background/js/file_operation_handler.js
@@ -122,8 +122,10 @@ } /** - * Handles the delete event. - * @param {Event} event The delete event. + * Handles the delete event, and also the restore event which is similar to + * delete in that as items complete, they are removed from the containing + * directory. + * @param {Event} event The delete or restore event. * @private */ onDeleteProgress_(event) { @@ -139,7 +141,7 @@ item = new ProgressCenterItem(); item.id = event.taskId; item.type = ProgressItemType.DELETE; - item.message = FileOperationHandler.getDeleteMessage_(event); + item.message = FileOperationHandler.getMessage_(event); item.progressMax = event.totalBytes; item.progressValue = event.processedBytes; item.cancelCallback = this.fileOperationManager_.requestTaskCancel.bind( @@ -158,7 +160,7 @@ console.error('Cannot find deleting item.'); return; } - item.message = FileOperationHandler.getDeleteMessage_(event); + item.message = FileOperationHandler.getMessage_(event); item.progressMax = event.totalBytes; item.progressValue = event.processedBytes; if (!pending) { @@ -179,7 +181,7 @@ } // Update the item. - item.message = FileOperationHandler.getDeleteMessage_(event); + item.message = FileOperationHandler.getMessage_(event); if (event.reason === EventType.SUCCESS) { item.state = ProgressItemState.COMPLETED; item.progressValue = item.progressMax; @@ -230,11 +232,11 @@ name += '/'; } switch (event.status.operationType) { - case 'COPY': + case util.FileOperationType.COPY: return strf('COPY_TARGET_EXISTS_ERROR', name); - case 'MOVE': + case util.FileOperationType.MOVE: return strf('MOVE_TARGET_EXISTS_ERROR', name); - case 'ZIP': + case util.FileOperationType.ZIP: return strf('ZIP_TARGET_EXISTS_ERROR', name); default: return strf('TRANSFER_TARGET_EXISTS_ERROR', name); @@ -243,11 +245,11 @@ case util.FileOperationErrorType.FILESYSTEM_ERROR: const detail = util.getFileErrorString(event.error.data.name); switch (event.status.operationType) { - case 'COPY': + case util.FileOperationType.COPY: return strf('COPY_FILESYSTEM_ERROR', detail); - case 'MOVE': + case util.FileOperationType.MOVE: return strf('MOVE_FILESYSTEM_ERROR', detail); - case 'ZIP': + case util.FileOperationType.ZIP: return strf('ZIP_FILESYSTEM_ERROR', detail); default: return strf('TRANSFER_FILESYSTEM_ERROR', detail); @@ -255,12 +257,16 @@ default: switch (event.status.operationType) { - case 'COPY': + case util.FileOperationType.COPY: return strf('COPY_UNEXPECTED_ERROR', event.error.code); - case 'MOVE': + case util.FileOperationType.MOVE: return strf('MOVE_UNEXPECTED_ERROR', event.error.code); - case 'ZIP': + case util.FileOperationType.ZIP: return strf('ZIP_UNEXPECTED_ERROR', event.error.code); + case util.FileOperationType.DELETE: + return str('DELETE_ERROR'); + case util.FileOperationType.RESTORE: + return str('RESTORE_FROM_TRASH_ERROR'); default: return strf('TRANSFER_UNEXPECTED_ERROR', event.error.code); } @@ -268,24 +274,32 @@ } else if (event.status.numRemainingItems === 1) { const name = event.status.processingEntryName; switch (event.status.operationType) { - case 'COPY': + case util.FileOperationType.COPY: return strf('COPY_FILE_NAME', name); - case 'MOVE': + case util.FileOperationType.MOVE: return strf('MOVE_FILE_NAME', name); - case 'ZIP': + case util.FileOperationType.ZIP: return strf('ZIP_FILE_NAME', name); + case util.FileOperationType.DELETE: + return strf('DELETE_FILE_NAME', name); + case util.FileOperationType.RESTORE: + return strf('RESTORE_FROM_TRASH_FILE_NAME', name); default: return strf('TRANSFER_FILE_NAME', name); } } else { const remainNumber = event.status.numRemainingItems; switch (event.status.operationType) { - case 'COPY': + case util.FileOperationType.COPY: return strf('COPY_ITEMS_REMAINING', remainNumber); - case 'MOVE': + case util.FileOperationType.MOVE: return strf('MOVE_ITEMS_REMAINING', remainNumber); - case 'ZIP': + case util.FileOperationType.ZIP: return strf('ZIP_ITEMS_REMAINING', remainNumber); + case util.FileOperationType.DELETE: + return strf('DELETE_ITEMS_REMAINING', remainNumber); + case util.FileOperationType.RESTORE: + return strf('RESTORE_FROM_TRASH_ITEMS_REMAINING', remainNumber); default: return strf('TRANSFER_ITEMS_REMAINING', remainNumber); } @@ -293,26 +307,6 @@ } /** - * Generates a delete message from the event. - * @param {Event} event Progress event. - * @return {string} message. - * @private - */ - static getDeleteMessage_(event) { - event = /** @type {FileOperationProgressEvent} */ (event); - if (event.reason === fileOperationUtil.EventRouter.EventType.ERROR) { - return str('DELETE_ERROR'); - } else if (event.entries.length == 1) { - const fileName = event.entries[0].name; - return strf('DELETE_FILE_NAME', fileName); - } else if (event.entries.length > 1) { - return strf('DELETE_ITEMS_REMAINING', event.entries.length); - } else { - return ''; - } - } - - /** * Obtains ProgressItemType from OperationType of FileTransferManager. * @param {string} operationType OperationType of FileTransferManager. * @return {ProgressItemType} corresponding to the specified operation type. @@ -320,11 +314,11 @@ */ static getType_(operationType) { switch (operationType) { - case 'COPY': + case util.FileOperationType.COPY: return ProgressItemType.COPY; - case 'MOVE': + case util.FileOperationType.MOVE: return ProgressItemType.MOVE; - case 'ZIP': + case util.FileOperationType.ZIP: return ProgressItemType.ZIP; default: console.error('Unknown operation type.');
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager.js b/ui/file_manager/file_manager/background/js/file_operation_manager.js index 9ee55cbb..bffc6d1b 100644 --- a/ui/file_manager/file_manager/background/js/file_operation_manager.js +++ b/ui/file_manager/file_manager/background/js/file_operation_manager.js
@@ -113,15 +113,16 @@ * Returns status information for a running task. * @param {fileOperationUtil.Task} task The task we use to retrieve status * from. - * @return {Object} Status object with optional volume information. + * @return {!fileOperationUtil.Status} Status object with optional volume + * information. */ getTaskStatus(task) { const status = task.getStatus(); // If there's no target directory name, use the volume name for UI display. - if (status['targetDirEntryName'] === '' && task.targetDirEntry) { + if (status.targetDirEntryName === '' && task.targetDirEntry) { const entry = /** {Entry} */ (task.targetDirEntry); if (this.volumeManager_) { - status['targetDirEntryName'] = this.getVolumeLabel_(entry); + status.targetDirEntryName = this.getVolumeLabel_(entry); } } return status; @@ -405,8 +406,20 @@ * @param {!Array<!Entry>} entries The entries. */ deleteEntries(entries) { + this.deleteOrRestore_(util.FileOperationType.DELETE, entries); + } + + /** + * Schedule delete or restore. + * + * @param {!util.FileOperationType} operationType DELETE or RESTORE. + * @param {!Array<!Entry|!TrashEntry>} entries The entries. + * @private + */ + deleteOrRestore_(operationType, entries) { const task = /** @type {!fileOperationUtil.DeleteTask} */ (Object.preventExtensions({ + operationType: operationType, entries: entries, taskId: this.generateTaskId(), entrySize: {}, @@ -447,10 +460,10 @@ } /** - * Service all pending delete tasks, as well as any that might appear during - * the deletion. + * Service all pending delete/restore tasks, as well as any that might appear + * during the deletion. * - * Must not be called if there is an in-flight delete task. + * Must not be called if there is an in-flight delete/restore task. * * @private */ @@ -472,16 +485,16 @@ } /** - * Performs the deletion. + * Performs the deletion or restore. * - * @param {!Object} task The delete task (see deleteEntries function). + * @param {!Object} task The delete task (see deleteOrRestore_()). * @param {function()} callback Callback run on task end. * @private */ serviceDeleteTask_(task, callback) { const queue = new AsyncUtil.Queue(); - // Delete each entry. + // Delete or restore each entry. let error = null; const deleteOneEntry = inCallback => { if (!task.entries.length || task.cancelRequested || error) { @@ -490,14 +503,34 @@ } this.eventRouter_.sendDeleteEvent( fileOperationUtil.EventRouter.EventType.PROGRESS, task); - this.trash_ - .removeFileOrDirectory( - assert(this.volumeManager_), task.entries[0], - /*permanentlyDelete=*/ false) - .then(trashEntry => { - if (trashEntry) { - task.trashedEntries.push(trashEntry); - } + + // Operation will be either delete, or restore. + let operation; + switch (task.operationType) { + case util.FileOperationType.DELETE: + operation = this.trash_ + .removeFileOrDirectory( + assert(this.volumeManager_), task.entries[0], + /*permanentlyDelete=*/ false) + .then(trashEntry => { + if (trashEntry) { + task.trashedEntries.push(trashEntry); + } + }); + break; + + case util.FileOperationType.RESTORE: + operation = + this.trash_.restore(assert(this.volumeManager_), task.entries[0]); + break; + + default: + operation = + Promise.reject('Unkonwn operation type ' + task.operationType); + } + + operation + .then(() => { this.eventRouter_.sendEntryChangedEvent( util.EntryChangedKind.DELETED, task.entries[0]); task.processedBytes += task.entrySize[task.entries[0].toURL()]; @@ -505,7 +538,7 @@ deleteOneEntry(inCallback); }) .catch(inError => { - error = inError; + error = inError.message; inCallback(); }); }; @@ -522,30 +555,22 @@ } else { reason = EventType.SUCCESS; } - this.eventRouter_.sendDeleteEvent(reason, task); + this.eventRouter_.sendDeleteEvent( + reason, task, + new fileOperationUtil.Error( + util.FileOperationErrorType.FILESYSTEM_ERROR, error)); inCallback(); callback(); }); } /** - * Restores files from trash. + * Schedules the files to be restored. * - * @param {Array<!TrashEntry>} entries The trash entries. + * @param {!Array<!TrashEntry>} entries The trash entries. */ restoreDeleted(entries) { - if (!this.volumeManager_) { - volumeManagerFactory.getInstance().then(volumeManager => { - this.volumeManager_ = volumeManager; - this.restoreDeleted(entries); - }); - return; - } - - while (entries.length) { - this.trash_.restore(assert(this.volumeManager_), entries.pop()) - .catch(e => console.error('Error restoring deleted file', e)); - } + this.deleteOrRestore_(util.FileOperationType.RESTORE, entries); } /**
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.js b/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.js index 36701088..068140d 100644 --- a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.js +++ b/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.js
@@ -153,7 +153,11 @@ * @return {?EntryLocation} */ getLocationInfo(entry) { - return null; + return /** @type {!EntryLocation} */ ({ + rootType: 'downloads', + volumeInfo: + {volumeType: 'downloads', label: 'Downloads', remoteMountPath: ''} + }); } } @@ -281,7 +285,9 @@ function setUp() { // Mock LoadTimeData strings. window.loadTimeData = { - data: {}, + data: { + 'FILES_TRASH_ENABLED': true, + }, getBoolean: function(key) { return window.loadTimeData.data[key]; }, @@ -868,19 +874,19 @@ reportPromise( waitForEvents(fileOperationManager).then(events => { assertEquals('delete', events[0].type); + assertEquals('DELETE', events[0].status.operationType); assertEquals('BEGIN', events[0].reason); - assertEquals(10, events[0].totalBytes); - assertEquals(0, events[0].processedBytes); + assertEquals(10, events[0].status.totalBytes); + assertEquals(0, events[0].status.processedBytes); const lastEvent = events[events.length - 1]; assertEquals('delete', lastEvent.type); + assertEquals('DELETE', lastEvent.status.operationType); assertEquals('SUCCESS', lastEvent.reason); - assertEquals(10, lastEvent.totalBytes); - assertEquals(10, lastEvent.processedBytes); + assertEquals(10, lastEvent.status.totalBytes); + assertEquals(10, lastEvent.status.processedBytes); - assertFalse(events.some(event => { - return event.type === 'copy-progress'; - })); + assertFalse(events.some(e => e.type === 'copy-progress')); }), callback); @@ -888,6 +894,57 @@ } /** + * Tests fileOperationManager.restore. + * @param {function(boolean)} callback Callback to be passed true on error. + */ +function testRestore(callback) { + // Prepare entries and their resolver. + const fileSystem = createTestFileSystem('testVolume', { + '/': DIRECTORY_SIZE, + '/test.txt': 10, + }); + window.webkitResolveLocalFileSystemURL = (url, success, failure) => { + resolveTestFileSystemURL(fileSystem, url, success, failure); + }; + + const onDeleted = (e) => { + if (e.status.operationType !== 'DELETE' || e.reason !== 'SUCCESS') { + return; + } + fileOperationManager.removeEventListener('delete', onDeleted); + + // Step 2. Once we receive 'DELETE' 'COMPLETED', observe 'RESTORE' events. + reportPromise( + waitForEvents(fileOperationManager).then(events => { + // Step 4. Validate restore events. + assertEquals('delete', events[0].type); + assertEquals('RESTORE', events[0].status.operationType); + assertEquals('BEGIN', events[0].reason); + assertEquals(10, events[0].status.totalBytes); + assertEquals(0, events[0].status.processedBytes); + + const lastEvent = events[events.length - 1]; + assertEquals('delete', lastEvent.type); + assertEquals('RESTORE', lastEvent.status.operationType); + assertEquals('SUCCESS', lastEvent.reason); + assertEquals(10, lastEvent.status.totalBytes); + assertEquals(10, lastEvent.status.processedBytes); + + assertFalse(events.some(e => e.type === 'copy-progress')); + }), + callback); + + // Step 3. Restore files. + fileOperationManager.restoreDeleted(e.trashedEntries); + }; + + + // Step 1. Delete files. + fileOperationManager.addEventListener('delete', onDeleted); + fileOperationManager.deleteEntries([fileSystem.entries['/test.txt']]); +} + +/** * Tests fileOperationManager.zipSelection. * @param {function(boolean)} callback Callback to be passed true on error. */
diff --git a/ui/file_manager/file_manager/background/js/file_operation_util.js b/ui/file_manager/file_manager/background/js/file_operation_util.js index 3ce5e64..082e6af 100644 --- a/ui/file_manager/file_manager/background/js/file_operation_util.js +++ b/ui/file_manager/file_manager/background/js/file_operation_util.js
@@ -665,7 +665,7 @@ /** * Get states of the task. * TODO(hirono): Removes this method and sets a task to progress events. - * @return {Object} Status object. + * @return {!fileOperationUtil.Status} Status object. */ getStatus() { const processingEntry = this.sourceEntries[this.processingSourceIndex_]; @@ -1247,6 +1247,22 @@ /** * @typedef {{ + * operationType: !util.FileOperationType, + * numRemainingItems: number, + * totalBytes: number, + * processedBytes: number, + * processingEntryName: string, + * targetDirEntryName: string, + * currentSpeed: number, + * averageSpeed: number, + * remainingTime: number, + * }} + */ +fileOperationUtil.Status; + +/** + * @typedef {{ + * operationType: !util.FileOperationType, * entries: Array<Entry>, * taskId: string, * entrySize: Object, @@ -1294,8 +1310,8 @@ * FileOperationManager status. If it is an ERROR event, error should be set. * * @param {fileOperationUtil.EventRouter.EventType} type Event type. - * @param {Object} status Current FileOperationManager's status. See also - * FileOperationManager.Task.getStatus(). + * @param {!fileOperationUtil.Status} status Current FileOperationManager's + * status. See also FileOperationManager.Task.getStatus(). * @param {string} taskId ID of task related with the event. * @param {fileOperationUtil.Error=} opt_error The info for the error. This * should be set iff the reason is "ERROR". @@ -1371,15 +1387,26 @@ * * @param {fileOperationUtil.EventRouter.EventType} reason Event type. * @param {!Object} task Delete task related with the event. + * @param {fileOperationUtil.Error=} error */ - sendDeleteEvent(reason, task) { + sendDeleteEvent(reason, task, error) { const event = /** @type {FileOperationProgressEvent} */ (new Event('delete')); event.reason = reason; + event.error = error; event.taskId = task.taskId; event.entries = task.entries; - event.totalBytes = task.totalBytes; - event.processedBytes = task.processedBytes; + event.status = { + operationType: task.operationType, + numRemainingItems: task.entries.length, + totalBytes: task.totalBytes, + processedBytes: task.processedBytes, + processingEntryName: task.entries.length > 0 ? task.entries[0].name : '', + targetDirEntryName: '', + currentSpeed: 0, + averageSpeed: 0, + remainingTime: 0, + }; event.trashedEntries = task.trashedEntries; this.dispatchEvent(event); }
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js index a8ad1ba..d1eb26d 100644 --- a/ui/file_manager/file_manager/common/js/util.js +++ b/ui/file_manager/file_manager/common/js/util.js
@@ -484,7 +484,9 @@ */ util.FileOperationType = { COPY: 'COPY', + DELETE: 'DELETE', MOVE: 'MOVE', + RESTORE: 'RESTORE', ZIP: 'ZIP', }; Object.freeze(util.FileOperationType);
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index e152ca08..87d11fd2 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -1211,7 +1211,8 @@ fileManager.ui.toast.show(message, { text: str('UNDO_DELETE_ACTION_LABEL'), callback: () => { - fileManager.fileOperationManager.restoreDeleted(e.trashedEntries); + fileManager.fileOperationManager.restoreDeleted( + assert(e.trashedEntries)); } }); }; @@ -1232,7 +1233,6 @@ fileManager.fileOperationManager.restoreDeleted(entries.map(e => { return /** @type {!TrashEntry} */ (e); })); - fileManager.directoryModel.rescanSoon(/*refresh=*/ false); } /** @override */
diff --git a/ui/gfx/skbitmap_operations.cc b/ui/gfx/skbitmap_operations.cc index 0a3fc8b..ed96883 100644 --- a/ui/gfx/skbitmap_operations.cc +++ b/ui/gfx/skbitmap_operations.cc
@@ -20,9 +20,16 @@ #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" +static bool IsUninitializedBitmap(const SkBitmap& bitmap) { + return bitmap.isNull() && bitmap.colorType() == kUnknown_SkColorType && + bitmap.alphaType() == kUnknown_SkAlphaType; +} + // static SkBitmap SkBitmapOperations::CreateInvertedBitmap(const SkBitmap& image) { - DCHECK(image.colorType() == kN32_SkColorType); + if (IsUninitializedBitmap(image)) + return image; + CHECK_EQ(image.colorType(), kN32_SkColorType); SkBitmap inverted; inverted.allocN32Pixels(image.width(), image.height()); @@ -46,10 +53,10 @@ const SkBitmap& second, double alpha) { DCHECK((alpha >= 0) && (alpha <= 1)); - DCHECK(first.width() == second.width()); - DCHECK(first.height() == second.height()); - DCHECK(first.bytesPerPixel() == second.bytesPerPixel()); - DCHECK(first.colorType() == kN32_SkColorType); + CHECK_EQ(first.width(), second.width()); + CHECK_EQ(first.height(), second.height()); + CHECK_EQ(first.colorType(), kN32_SkColorType); + CHECK_EQ(second.colorType(), kN32_SkColorType); // Optimize for case where we won't need to blend anything. static const double alpha_min = 1.0 / 255; @@ -92,11 +99,10 @@ // static SkBitmap SkBitmapOperations::CreateMaskedBitmap(const SkBitmap& rgb, const SkBitmap& alpha) { - DCHECK(rgb.width() == alpha.width()); - DCHECK(rgb.height() == alpha.height()); - DCHECK(rgb.bytesPerPixel() == alpha.bytesPerPixel()); - DCHECK(rgb.colorType() == kN32_SkColorType); - DCHECK(alpha.colorType() == kN32_SkColorType); + CHECK_EQ(rgb.width(), alpha.width()); + CHECK_EQ(rgb.height(), alpha.height()); + CHECK_EQ(rgb.colorType(), kN32_SkColorType); + CHECK_EQ(alpha.colorType(), kN32_SkColorType); SkBitmap masked; masked.allocN32Pixels(rgb.width(), rgb.height()); @@ -120,11 +126,8 @@ SkBitmap SkBitmapOperations::CreateButtonBackground(SkColor color, const SkBitmap& image, const SkBitmap& mask) { - // Despite this assert, it seems like image is actually unpremultiplied. - // The math producing dst_row[x] below is a correct SrcOver when - // bg_* are premultiplied and img_* are unpremultiplied. - DCHECK(image.colorType() == kN32_SkColorType); - DCHECK(mask.colorType() == kN32_SkColorType); + CHECK_EQ(image.colorType(), kN32_SkColorType); + CHECK_EQ(mask.colorType(), kN32_SkColorType); SkBitmap background; background.allocN32Pixels(mask.width(), mask.height()); @@ -476,6 +479,10 @@ SkBitmap SkBitmapOperations::CreateHSLShiftedBitmap( const SkBitmap& bitmap, const color_utils::HSL& hsl_shift) { + if (IsUninitializedBitmap(bitmap)) + return bitmap; + CHECK_EQ(bitmap.colorType(), kN32_SkColorType); + // Default to NOPs. HSLShift::OperationOnH H_op = HSLShift::kOpHNone; HSLShift::OperationOnS S_op = HSLShift::kOpSNone; @@ -520,7 +527,7 @@ SkBitmap SkBitmapOperations::CreateTiledBitmap(const SkBitmap& source, int src_x, int src_y, int dst_w, int dst_h) { - DCHECK(source.colorType() == kN32_SkColorType); + CHECK_EQ(source.colorType(), kN32_SkColorType); SkBitmap cropped; cropped.allocN32Pixels(dst_w, dst_h); @@ -563,6 +570,10 @@ // static SkBitmap SkBitmapOperations::DownsampleByTwo(const SkBitmap& bitmap) { + if (IsUninitializedBitmap(bitmap)) + return bitmap; + CHECK_EQ(bitmap.colorType(), kN32_SkColorType); + // Handle the nop case. if ((bitmap.width() <= 1) || (bitmap.height() <= 1)) return bitmap; @@ -626,12 +637,12 @@ // static SkBitmap SkBitmapOperations::UnPreMultiply(const SkBitmap& bitmap) { - if (bitmap.isNull()) + if (IsUninitializedBitmap(bitmap)) return bitmap; + CHECK_EQ(bitmap.colorType(), kN32_SkColorType); + if (bitmap.alphaType() != kPremul_SkAlphaType) return bitmap; - // It's expected this code is called with a 32bpp image. - CHECK_EQ(kN32_SkColorType, bitmap.colorType()); const SkImageInfo& opaque_info = bitmap.info().makeAlphaType(kUnpremul_SkAlphaType); @@ -652,7 +663,9 @@ // static SkBitmap SkBitmapOperations::CreateTransposedBitmap(const SkBitmap& image) { - DCHECK(image.colorType() == kN32_SkColorType); + if (IsUninitializedBitmap(image)) + return image; + CHECK_EQ(image.colorType(), kN32_SkColorType); SkBitmap transposed; transposed.allocN32Pixels(image.height(), image.width()); @@ -671,7 +684,7 @@ // static SkBitmap SkBitmapOperations::CreateColorMask(const SkBitmap& bitmap, SkColor c) { - DCHECK(bitmap.colorType() == kN32_SkColorType); + CHECK_EQ(bitmap.colorType(), kN32_SkColorType); SkBitmap color_mask; color_mask.allocN32Pixels(bitmap.width(), bitmap.height()); @@ -689,7 +702,7 @@ SkBitmap SkBitmapOperations::CreateDropShadow( const SkBitmap& bitmap, const gfx::ShadowValues& shadows) { - DCHECK(bitmap.colorType() == kN32_SkColorType); + CHECK_EQ(bitmap.colorType(), kN32_SkColorType); // Shadow margin insets are negative values because they grow outside. // Negate them here as grow direction is not important and only pixel value @@ -730,6 +743,9 @@ // static SkBitmap SkBitmapOperations::Rotate(const SkBitmap& source, RotationAmount rotation) { + if (IsUninitializedBitmap(source)) + return source; + CHECK_EQ(source.colorType(), kN32_SkColorType); // SkCanvas::drawBitmap() fails silently with unpremultiplied SkBitmap. DCHECK_NE(source.info().alphaType(), kUnpremul_SkAlphaType);
diff --git a/ui/ozone/platform/wayland/host/shell_surface_wrapper.h b/ui/ozone/platform/wayland/host/shell_surface_wrapper.h index a109023..ff5ab6c 100644 --- a/ui/ozone/platform/wayland/host/shell_surface_wrapper.h +++ b/ui/ozone/platform/wayland/host/shell_surface_wrapper.h
@@ -16,6 +16,19 @@ class WaylandConnection; +enum class DecorationMode { + // Client-side decoration for a window. + // In this case, the client is responsible for drawing decorations + // for a window (e.g. caption bar, close button). This is suitable for + // windows using custom frame. + kClientSide = 1, + // Server-side decoration for a window. + // In this case, the ash window manager is responsible for drawing + // decorations. This is suitable for windows using native frame. + // e.g. taskmanager. + kServerSide +}; + // Wrapper interface for different wayland shells shell versions. class ShellSurfaceWrapper { public: @@ -68,12 +81,10 @@ // .desktop file and use the icon set there. virtual void SetAppId(const std::string& app_id) = 0; - // If |is_server_side_decoration| is true, sets a server side decoration, - // and a client side decoration otherwise. - // - // This function sends a request to the wayland compositor to update - // the decoration mode for a surface associated with this top level window. - virtual void SetDecoration(bool is_server_side_decoration) = 0; + // In case of kClientSide or kServerSide, this function sends a + // request to the wayland compositor to update the decoration mode + // for a surface associated with this top level window. + virtual void SetDecoration(DecorationMode decoration) = 0; }; bool CheckIfWlArrayHasValue(struct wl_array* wl_array, uint32_t value);
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc index 6d3011d..309fc6c8f 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
@@ -66,7 +66,7 @@ #else shell_surface_->SetAppId(wm_class_class_); #endif - shell_surface_->SetDecoration(use_native_frame_); + SetDecorationMode(); shell_surface_->SetTitle(window_title_); SetSizeConstraints(); TriggerStateChanges(); @@ -248,7 +248,7 @@ return; use_native_frame_ = use_native_frame; if (shell_surface_) - shell_surface_->SetDecoration(use_native_frame); + SetDecorationMode(); } bool WaylandToplevelWindow::ShouldUseNativeFrame() const { @@ -478,4 +478,15 @@ } } +void WaylandToplevelWindow::SetDecorationMode() { + DCHECK(shell_surface_); + if (use_native_frame_) { + // Set server-side decoration for windows using a native frame, + // e.g. taskmanager + shell_surface_->SetDecoration(DecorationMode::kServerSide); + } else { + shell_surface_->SetDecoration(DecorationMode::kClientSide); + } +} + } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h index ca423d5..a9eff34 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
@@ -60,6 +60,8 @@ PlatformWindowState GetPlatformWindowState() const override; void SizeConstraintsChanged() override; std::string GetWindowUniqueId() const override; + // SetUseNativeFrame and ShouldUseNativeFrame decide on + // xdg-decoration mode for a window. void SetUseNativeFrame(bool use_native_frame) override; bool ShouldUseNativeFrame() const override; @@ -104,6 +106,9 @@ // is available. void InitializeAuraShellSurface(); + // Set decoration mode for a window. + void SetDecorationMode(); + // Wrappers around shell surface. std::unique_ptr<ShellSurfaceWrapper> shell_surface_; @@ -151,6 +156,10 @@ wl::Object<zaura_surface> aura_surface_; + // When use_native_frame is false, client-side decoration is set, + // e.g. lacros-browser. + // When use_native_frame is true, server-side decoration is set, + // e.g. lacros-taskmanager. bool use_native_frame_ = false; base::WeakPtrFactory<WaylandToplevelWindow> weak_ptr_factory_{this};
diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc index 0d49545..1957a55 100644 --- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc +++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc
@@ -11,6 +11,7 @@ #include "base/strings/utf_string_conversions.h" #include "ui/base/hit_test.h" #include "ui/ozone/platform/wayland/common/wayland_util.h" +#include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h" #include "ui/ozone/platform/wayland/host/wayland_window.h" @@ -18,7 +19,9 @@ XDGSurfaceWrapperImpl::XDGSurfaceWrapperImpl(WaylandWindow* wayland_window, WaylandConnection* connection) - : wayland_window_(wayland_window), connection_(connection) {} + : wayland_window_(wayland_window), + connection_(connection), + decoration_mode_(DecorationMode::kClientSide) {} XDGSurfaceWrapperImpl::~XDGSurfaceWrapperImpl() {} @@ -163,10 +166,8 @@ } } -void XDGSurfaceWrapperImpl::SetDecoration(bool is_server_side_decoration) { - SetTopLevelDecorationMode(is_server_side_decoration - ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE - : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); +void XDGSurfaceWrapperImpl::SetDecoration(DecorationMode decoration) { + SetTopLevelDecorationMode(decoration); } // static @@ -211,13 +212,13 @@ } void XDGSurfaceWrapperImpl::SetTopLevelDecorationMode( - zxdg_toplevel_decoration_v1_mode requested_mode) { + DecorationMode requested_mode) { if (!zxdg_toplevel_decoration_ || requested_mode == decoration_mode_) return; decoration_mode_ = requested_mode; zxdg_toplevel_decoration_v1_set_mode(zxdg_toplevel_decoration_.get(), - requested_mode); + static_cast<uint32_t>(requested_mode)); } // static @@ -278,8 +279,7 @@ uint32_t mode) { auto* surface = static_cast<XDGSurfaceWrapperImpl*>(data); DCHECK(surface); - surface->SetTopLevelDecorationMode( - static_cast<zxdg_toplevel_decoration_v1_mode>(mode)); + surface->SetTopLevelDecorationMode(static_cast<DecorationMode>(mode)); } bool XDGSurfaceWrapperImpl::InitializeStable(bool with_toplevel) { @@ -360,6 +360,8 @@ zxdg_toplevel_v6_add_listener(zxdg_toplevel_v6_.get(), &zxdg_toplevel_v6_listener, this); + InitializeXdgDecoration(); + wayland_window_->root_surface()->Commit(); connection_->ScheduleFlush(); return true;
diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h index 860301b..6cbb8b68 100644 --- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h +++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h
@@ -48,7 +48,7 @@ void SetMinSize(int32_t width, int32_t height) override; void SetMaxSize(int32_t width, int32_t height) override; void SetAppId(const std::string& app_id) override; - void SetDecoration(bool is_server_side_decoration) override; + void SetDecoration(DecorationMode decoration) override; // xdg_surface_listener static void ConfigureV6(void* data, @@ -75,8 +75,9 @@ static void CloseTopLevelV6(void* data, struct zxdg_toplevel_v6* zxdg_toplevel_v6); - void SetTopLevelDecorationMode( - zxdg_toplevel_decoration_v1_mode requested_mode); + // Send request to wayland compositor to enable a requested decoration mode. + void SetTopLevelDecorationMode(DecorationMode requested_mode); + // zxdg_decoration_listener static void ConfigureDecoration( void* data, @@ -109,10 +110,9 @@ bool surface_for_popup_ = false; - // Keeps track of the decoration mode currently in use if xdg-decoration - // protocol extension is available, otherwise CLIENT_SIDE is assumed. - enum zxdg_toplevel_decoration_v1_mode decoration_mode_ = - ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + // On client side, it keeps track of the decoration mode currently in + // use if xdg-decoration protocol extension is available. + DecorationMode decoration_mode_; }; } // namespace ui
diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc index 0762225e..faad061 100644 --- a/ui/views/controls/button/image_button.cc +++ b/ui/views/controls/button/image_button.cc
@@ -13,6 +13,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/scoped_canvas.h" +#include "ui/views/background.h" #include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/painter.h" #include "ui/views/widget/widget.h" @@ -246,6 +247,11 @@ } } +void ToggleImageButton::SetToggledBackground(std::unique_ptr<Background> b) { + toggled_background_ = std::move(b); + SchedulePaint(); +} + base::string16 ToggleImageButton::GetToggledTooltipText() const { return toggled_tooltip_text_; } @@ -290,6 +296,15 @@ PreferredSizeChanged(); } +void ToggleImageButton::OnPaintBackground(gfx::Canvas* canvas) { + if (toggled_ && toggled_background_) { + TRACE_EVENT0("views", "View::OnPaintBackground"); + toggled_background_->Paint(canvas, this); + } else { + ImageButton::OnPaintBackground(canvas); + } +} + //////////////////////////////////////////////////////////////////////////////// // ToggleImageButton, View overrides:
diff --git a/ui/views/controls/button/image_button.h b/ui/views/controls/button/image_button.h index 6ea3fdf..4584ae2 100644 --- a/ui/views/controls/button/image_button.h +++ b/ui/views/controls/button/image_button.h
@@ -138,6 +138,11 @@ // before the button is toggled. void SetToggledImage(ButtonState state, const gfx::ImageSkia* image); + // Like Views::SetBackground(), but to set the background color used for the + // "has been toggled" state. + void SetToggledBackground(std::unique_ptr<Background> b); + Background* toggled_background() { return toggled_background_.get(); } + // Get/Set the tooltip text displayed when the button is toggled. base::string16 GetToggledTooltipText() const; void SetToggledTooltipText(const base::string16& tooltip); @@ -153,6 +158,7 @@ // Overridden from View: base::string16 GetTooltipText(const gfx::Point& p) const override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; + void OnPaintBackground(gfx::Canvas* canvas) override; private: // The parent class's images_ member is used for the current images, @@ -163,6 +169,8 @@ // True if the button is currently toggled. bool toggled_ = false; + std::unique_ptr<Background> toggled_background_; + // The parent class's tooltip_text_ is displayed when not toggled, and // this one is shown when toggled. base::string16 toggled_tooltip_text_;
diff --git a/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc b/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc index ecb3fbe..d016279 100644 --- a/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc +++ b/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -45,7 +45,7 @@ void UrlCheckerDelegateImpl::MaybeDestroyPrerenderContents( content::WebContents::OnceGetter web_contents_getter) { - // Destroy the prefetch with FINAL_STATUS_SAFEBROSWING. + // Destroy the prefetch with FINAL_STATUS_SAFE_BROWSING. content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&DestroyPrerenderContents, std::move(web_contents_getter)));