diff --git a/AUTHORS b/AUTHORS index a448fc9..92071bd8 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -406,6 +406,7 @@ Jitendra Kumar Sahoo <jitendra.ks@samsung.com> Joachim Bauch <jbauch@webrtc.org> Joachim Bauch <mail@joachim-bauch.de> +Joanmarie Diggs <joanmarie.diggs@gmail.com> Joe Knoll <joe.knoll@workday.com> Joe Thomas <mhx348@motorola.com> Joel Stanley <joel@jms.id.au>
diff --git a/DEPS b/DEPS index 6f15e20c..4bb68764 100644 --- a/DEPS +++ b/DEPS
@@ -105,7 +105,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'a78b6dcb82d2f6c940e9c0a6bc14853f846344d0', + 'skia_revision': '9f7d4cd62a0bf201c65aa11498594b8c1dc17107', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -117,7 +117,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'e452382a61a185577d561cc7807b437f4db32d90', + 'angle_revision': '67c388e6c04ec35da3c72dd5fb3275a189c99fd1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -129,7 +129,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '8584902d81ffabc06bb4895f558e375e5429fe72', + 'pdfium_revision': 'b53ef1e52d40f586c401a7e3948259f8ebbfd3cc', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -165,7 +165,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '0f2c4fec12728f0ebf98a6afa4f8a18f2a9b2a0b', + 'catapult_revision': '65f883bb77390e3208346e653f3a518c3a63ded7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -564,7 +564,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'd795ab891c157bcda542f9cab5375805a19af7b0', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'b0e855a33353ca30a2ecb1c0e9084ca3ef26836a', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1034,7 +1034,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '21dbf06b5aa6c7dc8cf56314d4a3f96f57956c53', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '1bd66642c37083156c625578130dbed13f5fb32c', + Var('webrtc_git') + '/src.git' + '@' + '1899c1270f0ce4264c6a579c3d86f81ac0e98aea', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 5e71b48..6a72e23 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -2895,6 +2895,7 @@ results.extend(_CheckWATCHLISTS(input_api, output_api)) results.extend(input_api.RunTests( input_api.canned_checks.CheckVPythonSpec(input_api, output_api))) + results.extend(_CheckTranslationScreenshots(input_api, output_api)) for f in input_api.AffectedFiles(): path, name = input_api.os_path.split(f.LocalPath()) @@ -3344,3 +3345,178 @@ results.extend(input_api.canned_checks.CheckChangeHasDescription( input_api, output_api)) return results + + +def _CheckTranslationScreenshots(input_api, output_api): + PART_FILE_TAG = "part" + import os + import sys + from io import StringIO + + try: + old_sys_path = sys.path + sys.path = sys.path + [input_api.os_path.join( + input_api.PresubmitLocalPath(), 'tools', 'grit')] + import grit.grd_reader + import grit.node.message + import grit.util + finally: + sys.path = old_sys_path + + def _GetGrdMessages(grd_path_or_string, dir_path='.'): + """Load the grd file and return a dict of message ids to messages. + + Ignores any nested grdp files pointed by <part> tag. + """ + doc = grit.grd_reader.Parse(grd_path_or_string, dir_path, + stop_after=None, first_ids_file=None, + debug=False, defines=None, + tags_to_ignore=set([PART_FILE_TAG])) + return { + msg.attrs['name']:msg for msg in doc.GetChildrenOfType( + grit.node.message.MessageNode) + } + + def _GetGrdpMessagesFromString(grdp_string): + """Parses the contents of a grdp file given in grdp_string. + + grd_reader can't parse grdp files directly. Instead, this creates a + temporary directory with a grd file pointing to the grdp file, and loads the + grd from there. Any nested grdp files (pointed by <part> tag) are ignored. + """ + WRAPPER = """<?xml version="1.0" encoding="utf-8"?> + <grit latest_public_release="1" current_release="1"> + <release seq="1"> + <messages> + <part file="sub.grdp" /> + </messages> + </release> + </grit> + """ + with grit.util.TempDir({'main.grd': WRAPPER, + 'sub.grdp': grdp_string}) as temp_dir: + return _GetGrdMessages(temp_dir.GetPath('main.grd'), temp_dir.GetPath()) + + new_or_added_paths = set(f.LocalPath() + for f in input_api.AffectedFiles() + if (f.Action() == 'A' or f.Action() == 'M')) + removed_paths = set(f.LocalPath() + for f in input_api.AffectedFiles(include_deletes=True) + if f.Action() == 'D') + + affected_grds = [f for f in input_api.AffectedFiles() + if (f.LocalPath().endswith('.grd') or + f.LocalPath().endswith('.grdp'))] + affected_png_paths = [f.AbsoluteLocalPath() + for f in input_api.AffectedFiles() + if (f.LocalPath().endswith('.png'))] + + # Check for screenshots. Developers can upload screenshots using + # tools/translation/upload_screenshots.py which finds and uploads + # images associated with .grd files (e.g. test_grd/IDS_STRING.png for the + # message named IDS_STRING in test.grd) and produces a .sha1 file (e.g. + # test_grd/IDS_STRING.png.sha1) for each png when the upload is successful. + # + # The logic here is as follows: + # + # - If the CL has a .png file under the screenshots directory for a grd + # file, warn the developer. Actual images should never be checked into the + # Chrome repo. + # + # - If the CL contains modified or new messages in grd files and doesn't + # contain the corresponding .sha1 files, warn the developer to add images + # and upload them via tools/translation/upload_screenshots.py. + # + # - If the CL contains modified or new messages in grd files and the + # corresponding .sha1 files, everything looks good. + # + # - If the CL contains removed messages in grd files but the corresponding + # .sha1 files aren't removed, warn the developer to remove them. + unnecessary_screenshots = [] + missing_sha1 = [] + unnecessary_sha1_files = [] + + + def _CheckScreenshotAdded(screenshots_dir, message_id): + sha1_path = input_api.os_path.join( + screenshots_dir, message_id + '.png.sha1') + if sha1_path not in new_or_added_paths: + missing_sha1.append(sha1_path) + + + def _CheckScreenshotRemoved(screenshots_dir, message_id): + sha1_path = input_api.os_path.join( + screenshots_dir, message_id + '.png.sha1') + if sha1_path not in removed_paths: + unnecessary_sha1_files.append(sha1_path) + + + for f in affected_grds: + file_path = f.LocalPath() + old_id_to_msg_map = {} + new_id_to_msg_map = {} + if file_path.endswith('.grdp'): + if f.OldContents(): + old_id_to_msg_map = _GetGrdpMessagesFromString( + unicode('\n'.join(f.OldContents()))) + if f.NewContents(): + new_id_to_msg_map = _GetGrdpMessagesFromString( + unicode('\n'.join(f.NewContents()))) + else: + if f.OldContents(): + old_id_to_msg_map = _GetGrdMessages( + StringIO(unicode('\n'.join(f.OldContents())))) + if f.NewContents(): + new_id_to_msg_map = _GetGrdMessages( + StringIO(unicode('\n'.join(f.NewContents())))) + + # Compute added, removed and modified message IDs. + old_ids = set(old_id_to_msg_map) + new_ids = set(new_id_to_msg_map) + added_ids = new_ids - old_ids + removed_ids = old_ids - new_ids + modified_ids = set([]) + for key in old_ids.intersection(new_ids): + if (old_id_to_msg_map[key].FormatXml() + != new_id_to_msg_map[key].FormatXml()): + modified_ids.add(key) + + grd_name, ext = input_api.os_path.splitext( + input_api.os_path.basename(file_path)) + screenshots_dir = input_api.os_path.join( + input_api.os_path.dirname(file_path), grd_name + ext.replace('.', '_')) + + # Check the screenshot directory for .png files. Warn if there is any. + for png_path in affected_png_paths: + if png_path.startswith(screenshots_dir): + unnecessary_screenshots.append(png_path) + + for added_id in added_ids: + _CheckScreenshotAdded(screenshots_dir, added_id) + + for modified_id in modified_ids: + _CheckScreenshotAdded(screenshots_dir, modified_id) + + for removed_id in removed_ids: + _CheckScreenshotRemoved(screenshots_dir, removed_id) + + results = [] + if unnecessary_screenshots: + results.append(output_api.PresubmitNotifyResult( + 'Do not include actual screenshots in the changelist. Run ' + 'tools/translate/upload_screenshots.py to upload them instead:', + sorted(unnecessary_screenshots))) + + if missing_sha1: + results.append(output_api.PresubmitNotifyResult( + 'You are adding or modifying UI strings.\n' + 'To ensure the best translations, take screenshots of the relevant UI ' + '(https://g.co/chrome/translation) and add these files to your ' + 'changelist:', sorted(missing_sha1))) + + if unnecessary_sha1_files: + results.append(output_api.PresubmitNotifyResult( + 'You removed strings associated with these files. Remove:', + sorted(unnecessary_sha1_files))) + + return results
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index e5eb2ec..f1be4edea 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -1844,5 +1844,162 @@ self.assertEqual(0, len(results)) +class TranslationScreenshotsTest(unittest.TestCase): + # An empty grd file. + OLD_GRD_CONTENTS = """<?xml version="1.0" encoding="UTF-8"?> + <grit latest_public_release="1" current_release="1"> + <release seq="1"> + <messages></messages> + </release> + </grit> + """.splitlines() + # A grd file with a single message. + NEW_GRD_CONTENTS1 = """<?xml version="1.0" encoding="UTF-8"?> + <grit latest_public_release="1" current_release="1"> + <release seq="1"> + <messages> + <message name="IDS_TEST1"> + Test string 1 + </message> + </messages> + </release> + </grit> + """.splitlines() + # A grd file with two messages. + NEW_GRD_CONTENTS2 = """<?xml version="1.0" encoding="UTF-8"?> + <grit latest_public_release="1" current_release="1"> + <release seq="1"> + <messages> + <message name="IDS_TEST1"> + Test string 1 + </message> + <message name="IDS_TEST2"> + Test string 2 + </message> + </messages> + </release> + </grit> + """.splitlines() + + DO_NOT_UPLOAD_PNG_MESSAGE = ('Do not include actual screenshots in the ' + 'changelist. Run ' + 'tools/translate/upload_screenshots.py to ' + 'upload them instead:') + GENERATE_SIGNATURES_MESSAGE = ('You are adding or modifying UI strings.\n' + 'To ensure the best translations, take ' + 'screenshots of the relevant UI ' + '(https://g.co/chrome/translation) and add ' + 'these files to your changelist:') + REMOVE_SIGNATURES_MESSAGE = ('You removed strings associated with these ' + 'files. Remove:') + + def makeInputApi(self, files): + input_api = MockInputApi() + input_api.files = files + return input_api + + def testNoScreenshots(self): + # CL modified and added messages, but didn't add any screenshots. + input_api = self.makeInputApi([ + MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2, + self.OLD_GRD_CONTENTS, action='M')]) + warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, + MockOutputApi()) + self.assertEqual(1, len(warnings)) + self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[0].message) + self.assertEqual( + ['test_grd/IDS_TEST1.png.sha1', 'test_grd/IDS_TEST2.png.sha1'], + warnings[0].items) + + input_api = self.makeInputApi([ + MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2, + self.NEW_GRD_CONTENTS1, action='M')]) + warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, + MockOutputApi()) + self.assertEqual(1, len(warnings)) + self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[0].message) + self.assertEqual(['test_grd/IDS_TEST2.png.sha1'], warnings[0].items) + + + def testUnnecessaryScreenshots(self): + # CL added a single message and added the png file, but not the sha1 file. + input_api = self.makeInputApi([ + MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS1, + self.OLD_GRD_CONTENTS, action='M'), + MockAffectedFile('test_grd/IDS_TEST1.png', 'binary', action='A')]) + warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, + MockOutputApi()) + self.assertEqual(2, len(warnings)) + self.assertEqual(self.DO_NOT_UPLOAD_PNG_MESSAGE, warnings[0].message) + self.assertEqual(['test_grd/IDS_TEST1.png'], warnings[0].items) + self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[1].message) + self.assertEqual(['test_grd/IDS_TEST1.png.sha1'], warnings[1].items) + + # CL added two messages, one has a png. Expect two messages: + # - One for the unnecessary png. + # - Another one for missing .sha1 files. + input_api = self.makeInputApi([ + MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2, + self.OLD_GRD_CONTENTS, action='M'), + MockAffectedFile('test_grd/IDS_TEST1.png', 'binary', action='A')]) + warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, + MockOutputApi()) + self.assertEqual(2, len(warnings)) + self.assertEqual(self.DO_NOT_UPLOAD_PNG_MESSAGE, warnings[0].message) + self.assertEqual(['test_grd/IDS_TEST1.png'], warnings[0].items) + self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[1].message) + self.assertEqual(['test_grd/IDS_TEST1.png.sha1', + 'test_grd/IDS_TEST2.png.sha1'], warnings[1].items) + + def testScreenshotsWithSha1(self): + # CL added two messages and their corresponding .sha1 files. No warnings. + input_api = self.makeInputApi([ + MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2, + self.OLD_GRD_CONTENTS, action='M'), + MockFile('test_grd/IDS_TEST1.png.sha1', 'binary', action='A'), + MockFile('test_grd/IDS_TEST2.png.sha1', 'binary', action='A')]) + warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, + MockOutputApi()) + self.assertEqual([], warnings) + + def testScreenshotsRemovedWithSha1(self): + # Swap old contents with new contents, remove IDS_TEST1 and IDS_TEST2. The + # sha1 files associated with the messages should also be removed by the CL. + input_api = self.makeInputApi([ + MockAffectedFile('test.grd', self.OLD_GRD_CONTENTS, + self.NEW_GRD_CONTENTS2, action='M'), + MockFile('test_grd/IDS_TEST1.png.sha1', 'binary', ""), + MockFile('test_grd/IDS_TEST2.png.sha1', 'binary', "")]) + warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, + MockOutputApi()) + self.assertEqual(1, len(warnings)) + self.assertEqual(self.REMOVE_SIGNATURES_MESSAGE, warnings[0].message) + self.assertEqual(['test_grd/IDS_TEST1.png.sha1', + 'test_grd/IDS_TEST2.png.sha1'], warnings[0].items) + + # Same as above, but this time one of the .sha1 files is removed. + input_api = self.makeInputApi([ + MockAffectedFile('test.grd', self.OLD_GRD_CONTENTS, + self.NEW_GRD_CONTENTS2, action='M'), + MockFile('test_grd/IDS_TEST1.png.sha1', 'binary', ''), + MockAffectedFile('test_grd/IDS_TEST2.png.sha1', + '', 'old_contents', action='D')]) + warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, + MockOutputApi()) + self.assertEqual(1, len(warnings)) + self.assertEqual(self.REMOVE_SIGNATURES_MESSAGE, warnings[0].message) + self.assertEqual(['test_grd/IDS_TEST1.png.sha1'], warnings[0].items) + + # Remove both sha1 files. No presubmit warnings. + input_api = self.makeInputApi([ + MockAffectedFile('test.grd', self.OLD_GRD_CONTENTS, + self.NEW_GRD_CONTENTS2, action='M'), + MockFile('test_grd/IDS_TEST1.png.sha1', 'binary', action='D'), + MockFile('test_grd/IDS_TEST2.png.sha1', 'binary', action='D')]) + warnings = PRESUBMIT._CheckTranslationScreenshots(input_api, + MockOutputApi()) + self.assertEqual([], warnings) + + if __name__ == '__main__': unittest.main()
diff --git a/WATCHLISTS b/WATCHLISTS index d46b0af..2963302c5 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1989,8 +1989,7 @@ 'chrome_cleaner': ['csharp+watch@chromium.org', 'ftirelo+watch@chromium.org', 'joenotcharles+watch@chromium.org'], - 'chrome_elf': ['caitkp+watch@chromium.org', - 'pennymac+watch@chromium.org'], + 'chrome_elf': ['caitkp+watch@chromium.org'], 'chrome_grc': ['chrome-grc-reviews@chromium.org'], 'chrome_views': ['tfarina@chromium.org'], 'chromecast': ['alokp+watch@chromium.org', @@ -2119,7 +2118,6 @@ 'installer_linux': ['mmoss@chromium.org', 'raphael.kubo.da.costa@intel.com'], 'installer_win': ['grt+watch@chromium.org', - 'pennymac+watch@chromium.org', 'wfh+watch@chromium.org'], 'instant': ['dcblack@chromium.org', 'donnd+watch@chromium.org', @@ -2374,8 +2372,7 @@ 'markusheintz@chromium.org', 'msramek+watch@chromium.org', 'raymes+watch@chromium.org'], - 'windows_sandboxing': ['pennymac+watch@chromium.org', - 'wfh+watch@chromium.org'], + 'windows_sandboxing': ['wfh+watch@chromium.org'], 'x11': ['derat+watch@chromium.org', 'sadrul@chromium.org', 'yusukes+watch@chromium.org'],
diff --git a/ash/ash_service.cc b/ash/ash_service.cc index 5d01683..98a398ad 100644 --- a/ash/ash_service.cc +++ b/ash/ash_service.cc
@@ -173,8 +173,7 @@ ShellInitParams shell_init_params; shell_init_params.shell_port = std::make_unique<ash::ShellPortClassic>(); - shell_init_params.delegate = - std::make_unique<ShellDelegateMash>(context()->connector()); + shell_init_params.delegate = std::make_unique<ShellDelegateMash>(); shell_init_params.context_factory = context_factory_.get(); shell_init_params.context_factory_private = context_factory_->GetContextFactoryPrivate();
diff --git a/ash/dbus/display_service_provider.cc b/ash/dbus/display_service_provider.cc index 6f63026..52a0955b 100644 --- a/ash/dbus/display_service_provider.cc +++ b/ash/dbus/display_service_provider.cc
@@ -9,7 +9,6 @@ #include "ash/public/interfaces/ash_display_controller.mojom.h" #include "ash/public/interfaces/constants.mojom.h" #include "ash/shell.h" -#include "ash/shell_delegate.h" #include "ash/wm/screen_dimmer.h" #include "base/bind.h" #include "base/callback.h" @@ -56,8 +55,8 @@ bool DisplayServiceProvider::Impl::Connect() { if (ash_display_controller_) return true; - Shell::Get()->shell_delegate()->GetShellConnector()->BindInterface( - mojom::kServiceName, &ash_display_controller_); + Shell::Get()->connector()->BindInterface(mojom::kServiceName, + &ash_display_controller_); return !!ash_display_controller_; }
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc index 44c719a..7f52f9a 100644 --- a/ash/login/login_screen_controller.cc +++ b/ash/login/login_screen_controller.cc
@@ -315,11 +315,16 @@ } } -void LoginScreenController::SetUserList( - std::vector<mojom::LoginUserInfoPtr> users) { +void LoginScreenController::LoadUsers( + std::vector<mojom::LoginUserInfoPtr> users, + bool show_guest) { DCHECK(DataDispatcher()); DataDispatcher()->NotifyUsers(users); + Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) + ->shelf_widget() + ->login_shelf_view() + ->SetAllowLoginAsGuest(show_guest); } void LoginScreenController::SetPinEnabledForUser(const AccountId& account_id, @@ -409,19 +414,11 @@ ->SetKioskApps(std::move(kiosk_apps)); } -void LoginScreenController::NotifyOobeDialogState( - mojom::OobeDialogState state) { +void LoginScreenController::NotifyOobeDialogVisibility(bool visible) { Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) ->shelf_widget() ->login_shelf_view() - ->SetLoginDialogState(state); -} - -void LoginScreenController::SetAllowLoginAsGuest(bool allow_guest) { - Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) - ->shelf_widget() - ->login_shelf_view() - ->SetAllowLoginAsGuest(allow_guest); + ->SetLoginDialogVisible(visible); } void LoginScreenController::SetAddUserButtonEnabled(bool enable) {
diff --git a/ash/login/login_screen_controller.h b/ash/login/login_screen_controller.h index dff21e0..3aa7d02 100644 --- a/ash/login/login_screen_controller.h +++ b/ash/login/login_screen_controller.h
@@ -111,7 +111,8 @@ void SetAuthType(const AccountId& account_id, proximity_auth::mojom::AuthType auth_type, const base::string16& initial_value) override; - void SetUserList(std::vector<mojom::LoginUserInfoPtr> users) override; + void LoadUsers(std::vector<mojom::LoginUserInfoPtr> users, + bool show_guest) override; void SetPinEnabledForUser(const AccountId& account_id, bool is_enabled) override; void SetAvatarForUser(const AccountId& account_id, @@ -138,9 +139,8 @@ void SetFingerprintUnlockState(const AccountId& account_id, mojom::FingerprintUnlockState state) override; void SetKioskApps(std::vector<mojom::KioskAppInfoPtr> kiosk_apps) override; - void NotifyOobeDialogState(mojom::OobeDialogState state) override; + void NotifyOobeDialogVisibility(bool is_visible) override; void SetAddUserButtonEnabled(bool enable) override; - void SetAllowLoginAsGuest(bool allow_guest) override; // Flushes the mojo pipes - to be used in tests. void FlushForTesting();
diff --git a/ash/login/ui/image_parser.cc b/ash/login/ui/image_parser.cc index 9ddfc9d..9377654 100644 --- a/ash/login/ui/image_parser.cc +++ b/ash/login/ui/image_parser.cc
@@ -7,7 +7,6 @@ #include <utility> #include "ash/shell.h" -#include "ash/shell_delegate.h" #include "ipc/ipc_channel.h" #include "services/data_decoder/public/cpp/decode_image.h" @@ -40,9 +39,9 @@ // also goes through libpng, but APNG support is handled specifically by // blink's PNGImageReader.cpp. data_decoder::DecodeAnimation( - Shell::Get()->shell_delegate()->GetShellConnector(), image_data, - true /*shrink_to_fit*/, kMaxImageSizeInBytes, + Shell::Get()->connector(), image_data, true /*shrink_to_fit*/, + kMaxImageSizeInBytes, base::Bind(&ConvertToAnimationFrame, Passed(&on_decoded))); } -} // namespace ash \ No newline at end of file +} // namespace ash
diff --git a/ash/public/interfaces/login_screen.mojom b/ash/public/interfaces/login_screen.mojom index 08df062..2b9c593 100644 --- a/ash/public/interfaces/login_screen.mojom +++ b/ash/public/interfaces/login_screen.mojom
@@ -12,33 +12,6 @@ import "mojo/public/mojom/base/string16.mojom"; import "mojo/public/mojom/base/time.mojom"; -// State of the Oobe UI dialog. -enum OobeDialogState { - // Oobe UI dialog is currently hidden. - HIDDEN, - - // Showing gaia signin screen. - GAIA_SIGNIN, - - // Showing wrong hardware identification screen. - WRONG_HWID_WARNING, - - // Showing supervised user creation screen. - SUPERVISED_USER_CREATION_FLOW, - - // Showing SAML password confirmation screen. - SAML_PASSWORD_CONFIRM, - - // Showing password changed screen. - PASSWORD_CHANGED, - - // Showing device enrollment screen. - ENROLLMENT, - - // Showing error screen. - ERROR, -}; - // Allows clients (e.g. Chrome browser) to control the ash login/lock/user-add // screens. interface LoginScreen { @@ -86,9 +59,10 @@ proximity_auth.mojom.AuthType auth_type, mojo_base.mojom.String16 initial_value); - // Set the users who are displayed on the login UI. |users| is filtered - // and does not correspond to every user on the device. - SetUserList(array<LoginUserInfo> users); + // Requests to load users in the lock screen. + // |users|: A list of users who can unlock the device. + // |show_guest|: Whether to show guest session button. + LoadUsers(array<LoginUserInfo> users, bool show_guest); // Notification if pin is enabled or disabled for the given user. // |account_id|: The account id of the user in the user pod. @@ -156,17 +130,13 @@ // Update the kiosk app data for the login screen. SetKioskApps(array<KioskAppInfo> kiosk_apps); - // Called when the dialog hosting oobe has changed state. The oobe dialog + // Called when the dialog hosting oobe has changed visibility. The oobe dialog // provides support for any part of login that is implemented in JS/HTML, such // as add user or powerwash. - NotifyOobeDialogState(OobeDialogState state); + NotifyOobeDialogVisibility(bool is_visible); // Sets whether users can be added from the login screen. SetAddUserButtonEnabled(bool enable); - - // Sets if the guest button on the login shelf can be shown. Even if set to - // true the button may still not be visible. - SetAllowLoginAsGuest(bool allow_guest); }; // Allows ash lock screen to control a client (e.g. Chrome browser). Requests
diff --git a/ash/shelf/login_shelf_view.cc b/ash/shelf/login_shelf_view.cc index cfa2f6e..1cab347b 100644 --- a/ash/shelf/login_shelf_view.cc +++ b/ash/shelf/login_shelf_view.cc
@@ -410,8 +410,8 @@ UpdateUi(); } -void LoginShelfView::SetLoginDialogState(mojom::OobeDialogState state) { - dialog_state_ = state; +void LoginShelfView::SetLoginDialogVisible(bool visible) { + dialog_visible_ = visible; UpdateUi(); } @@ -478,33 +478,12 @@ // TODO(agawronska): Implement full list of conditions for buttons visibility, // when views based shelf if enabled during OOBE. https://crbug.com/798869 bool is_login_primary = (session_state == SessionState::LOGIN_PRIMARY); - bool dialog_visible = dialog_state_ != mojom::OobeDialogState::HIDDEN; - - // Show guest button if: - // 1. It's in login screen. - // 2. Guest login is allowed. - // 3. OOBE UI dialog is not currently showing wrong HWID warning screen or - // SAML password confirmation screen. GetViewByID(kBrowseAsGuest) - ->SetVisible( - allow_guest_ && - dialog_state_ != mojom::OobeDialogState::WRONG_HWID_WARNING && - dialog_state_ != mojom::OobeDialogState::SAML_PASSWORD_CONFIRM && - is_login_primary); - - // Show add user button when it's in login screen and OobeUI dialog is not - // visible. - GetViewByID(kAddUser)->SetVisible(!dialog_visible && is_login_primary); - - // Show kiosk apps button if: - // 1. It's in login screen. - // 2. There're Kiosk apps availble. - // 3. Oobe UI dialog is not visible or is currently showing gaia signin - // screen. + ->SetVisible(allow_guest_ && !dialog_visible_ && is_login_primary); + GetViewByID(kAddUser)->SetVisible(!dialog_visible_ && is_login_primary); kiosk_apps_button_->SetVisible( - (!dialog_visible || - dialog_state_ == mojom::OobeDialogState::GAIA_SIGNIN) && - kiosk_apps_button_->HasApps() && is_login_primary); + !dialog_visible_ && kiosk_apps_button_->HasApps() && is_login_primary); + Layout(); }
diff --git a/ash/shelf/login_shelf_view.h b/ash/shelf/login_shelf_view.h index 68e92bd..5e7ddbe 100644 --- a/ash/shelf/login_shelf_view.h +++ b/ash/shelf/login_shelf_view.h
@@ -10,7 +10,6 @@ #include "ash/ash_export.h" #include "ash/lock_screen_action/lock_screen_action_background_observer.h" #include "ash/public/interfaces/kiosk_app_info.mojom.h" -#include "ash/public/interfaces/login_screen.mojom.h" #include "ash/shutdown_controller.h" #include "ash/tray_action/tray_action_observer.h" #include "base/scoped_observer.h" @@ -64,8 +63,9 @@ // Sets the list of kiosk apps that can be launched from the login shelf. void SetKioskApps(std::vector<mojom::KioskAppInfoPtr> kiosk_apps); - // Sets the state of the login dialog. - void SetLoginDialogState(mojom::OobeDialogState state); + // Sets if the login dialog is visible. This hides some of the buttons on the + // LoginShelf. + void SetLoginDialogVisible(bool visible); // Sets if the guest button on the login shelf can be shown. Even if set to // true the button may still not be visible. @@ -101,7 +101,7 @@ // policy updates, session state changes etc. void UpdateUi(); - mojom::OobeDialogState dialog_state_ = mojom::OobeDialogState::HIDDEN; + bool dialog_visible_ = false; bool allow_guest_ = true; LockScreenActionBackgroundController* lock_screen_action_background_;
diff --git a/ash/shelf/login_shelf_view_unittest.cc b/ash/shelf/login_shelf_view_unittest.cc index 0b71fd8e..a15cdea 100644 --- a/ash/shelf/login_shelf_view_unittest.cc +++ b/ash/shelf/login_shelf_view_unittest.cc
@@ -291,68 +291,23 @@ // However, SetAllowLoginAsGuest(true) does not mean that the guest button is // always visible. - login_shelf_view_->SetLoginDialogState( - mojom::OobeDialogState::SAML_PASSWORD_CONFIRM); + login_shelf_view_->SetLoginDialogVisible(true); EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown})); } -TEST_F(LoginShelfViewTest, ShouldUpdateUiAfterDialogStateChange) { +TEST_F(LoginShelfViewTest, ShouldUpdateUiAfterDialogVisibilityChange) { NotifySessionStateChanged(SessionState::LOGIN_PRIMARY); EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kBrowseAsGuest, LoginShelfView::kAddUser})); - // Add user button is always hidden if dialog state != - // OobeDialogState::HIDDEN. - login_shelf_view_->SetLoginDialogState(mojom::OobeDialogState::GAIA_SIGNIN); - EXPECT_TRUE(ShowsShelfButtons( - {LoginShelfView::kShutdown, LoginShelfView::kBrowseAsGuest})); + login_shelf_view_->SetLoginDialogVisible(true); + EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown})); - login_shelf_view_->SetLoginDialogState(mojom::OobeDialogState::HIDDEN); + login_shelf_view_->SetLoginDialogVisible(false); EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kBrowseAsGuest, LoginShelfView::kAddUser})); - - // Guest button is hidden if dialog state == - // OobeDialogState::WRONG_HWID_WARNING or SAML_PASSWORD_CONFIRM. - login_shelf_view_->SetLoginDialogState( - mojom::OobeDialogState::WRONG_HWID_WARNING); - EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown})); - - login_shelf_view_->SetLoginDialogState( - mojom::OobeDialogState::SAML_PASSWORD_CONFIRM); - EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown})); - - login_shelf_view_->SetLoginDialogState(mojom::OobeDialogState::GAIA_SIGNIN); - EXPECT_TRUE(ShowsShelfButtons( - {LoginShelfView::kShutdown, LoginShelfView::kBrowseAsGuest})); - - // Guest button is hidden if SetAllowLoginAsGuest(false). - login_shelf_view_->SetAllowLoginAsGuest(false /*allow_guest*/); - EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown})); - - // Kiosk app button is visible when dialog state == OobeDialogState::HIDDEN - // or GAIA_SIGNIN. - login_shelf_view_->SetLoginDialogState(mojom::OobeDialogState::GAIA_SIGNIN); - std::vector<mojom::KioskAppInfoPtr> kiosk_apps; - kiosk_apps.push_back(mojom::KioskAppInfo::New()); - login_shelf_view_->SetKioskApps(std::move(kiosk_apps)); - EXPECT_TRUE( - ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kApps})); - - login_shelf_view_->SetLoginDialogState( - mojom::OobeDialogState::SAML_PASSWORD_CONFIRM); - EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown})); - - login_shelf_view_->SetLoginDialogState(mojom::OobeDialogState::HIDDEN); - EXPECT_TRUE( - ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kAddUser, - LoginShelfView::kApps})); - - // Kiosk app button is hidden when no app exists. - login_shelf_view_->SetKioskApps(std::vector<mojom::KioskAppInfoPtr>()); - EXPECT_TRUE( - ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kAddUser})); } TEST_F(LoginShelfViewTest, ClickShutdownButton) {
diff --git a/ash/shell.cc b/ash/shell.cc index 612cda9..1cc23be7 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -270,12 +270,13 @@ // static Shell* Shell::CreateInstance(ShellInitParams init_params) { CHECK(!instance_); - instance_ = new Shell(std::move(init_params.delegate), - std::move(init_params.shell_port)); - instance_->Init( - init_params.context_factory, init_params.context_factory_private, - std::move(init_params.initial_display_prefs), - std::move(init_params.gpu_interface_provider), init_params.connector); + instance_ = + new Shell(std::move(init_params.delegate), + std::move(init_params.shell_port), init_params.connector); + instance_->Init(init_params.context_factory, + init_params.context_factory_private, + std::move(init_params.initial_display_prefs), + std::move(init_params.gpu_interface_provider)); return instance_; } @@ -666,12 +667,14 @@ // Shell, private: Shell::Shell(std::unique_ptr<ShellDelegate> shell_delegate, - std::unique_ptr<ShellPort> shell_port) + std::unique_ptr<ShellPort> shell_port, + service_manager::Connector* connector) : shell_port_(std::move(shell_port)), ash_display_controller_(std::make_unique<AshDisplayController>()), brightness_control_delegate_( std::make_unique<system::BrightnessControllerChromeos>()), cast_config_(std::make_unique<CastConfigController>()), + connector_(connector), first_run_helper_(std::make_unique<FirstRunHelper>()), focus_cycler_(std::make_unique<FocusCycler>()), ime_controller_(std::make_unique<ImeController>()), @@ -684,8 +687,7 @@ login_screen_controller_(std::make_unique<LoginScreenController>()), media_controller_(std::make_unique<MediaController>()), new_window_controller_(std::make_unique<NewWindowController>()), - session_controller_(std::make_unique<SessionController>( - shell_delegate->GetShellConnector())), + session_controller_(std::make_unique<SessionController>(connector)), note_taking_controller_(std::make_unique<NoteTakingController>()), shell_delegate_(std::move(shell_delegate)), shell_state_(std::make_unique<ShellState>()), @@ -947,12 +949,9 @@ ui::ContextFactory* context_factory, ui::ContextFactoryPrivate* context_factory_private, std::unique_ptr<base::Value> initial_display_prefs, - std::unique_ptr<ui::ws2::GpuInterfaceProvider> gpu_interface_provider, - service_manager::Connector* connector) { + std::unique_ptr<ui::ws2::GpuInterfaceProvider> gpu_interface_provider) { const Config config = shell_port_->GetAshConfig(); - connector_ = connector; - // This creates the MessageCenter object which is used by some other objects // initialized here, so it needs to come early. message_center_controller_ = std::make_unique<MessageCenterController>(); @@ -971,24 +970,22 @@ screen_switch_check_controller_ = std::make_unique<ScreenSwitchCheckController>(); // Connector can be null in tests. - if (shell_delegate_->GetShellConnector() && - base::FeatureList::IsEnabled( - chromeos::features::kEnableUnifiedMultiDeviceSetup)) { + if (connector_ && base::FeatureList::IsEnabled( + chromeos::features::kEnableUnifiedMultiDeviceSetup)) { multidevice_notification_presenter_ = std::make_unique<MultiDeviceNotificationPresenter>( - message_center::MessageCenter::Get(), - shell_delegate_->GetShellConnector()); + message_center::MessageCenter::Get(), connector_); } // Connector can be null in tests. - if (shell_delegate_->GetShellConnector()) { + if (connector_) { // Connect to local state prefs now, but wait for an active user before // connecting to the profile pref service. The login screen has a temporary // user profile that is not associated with a real user. auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>(); RegisterLocalStatePrefs(pref_registry.get(), false); prefs::ConnectToPrefService( - shell_delegate_->GetShellConnector(), std::move(pref_registry), + connector_, std::move(pref_registry), base::Bind(&Shell::OnLocalStatePrefServiceInitialized, weak_factory_.GetWeakPtr()), prefs::mojom::kLocalStateServiceName); @@ -1001,8 +998,8 @@ accessibility_focus_ring_controller_ = std::make_unique<AccessibilityFocusRingController>(); accessibility_delegate_.reset(shell_delegate_->CreateAccessibilityDelegate()); - accessibility_controller_ = std::make_unique<AccessibilityController>( - shell_delegate_->GetShellConnector()); + accessibility_controller_ = + std::make_unique<AccessibilityController>(connector_); toast_manager_ = std::make_unique<ToastManager>(); // Install the custom factory early on so that views::FocusManagers for Tray, @@ -1137,11 +1134,10 @@ // Forward user activity from the window server to |user_activity_detector_|. // The connector is unavailable in some tests. - if (aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS && - shell_delegate_->GetShellConnector()) { + // TODO(sky): this is dead code, clean up. + if (aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS && connector_) { ui::mojom::UserActivityMonitorPtr user_activity_monitor; - shell_delegate_->GetShellConnector()->BindInterface(ui::mojom::kServiceName, - &user_activity_monitor); + connector_->BindInterface(ui::mojom::kServiceName, &user_activity_monitor); user_activity_forwarder_ = std::make_unique<aura::UserActivityForwarder>( std::move(user_activity_monitor), user_activity_detector_.get()); } @@ -1266,13 +1262,12 @@ display_manager_->CreateMirrorWindowAsyncIfAny(); // The show taps feature can be implemented with a separate mojo app. - // GetShellConnector() is null in unit tests. + // |connector_| is null in unit tests. // TODO(jamescook): Make this work in ash_shell_with_content. - if (shell_delegate_->GetShellConnector() && + if (connector_ && base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowTaps) && base::FeatureList::IsEnabled(features::kTapVisualizerApp)) { - shell_delegate_->GetShellConnector()->StartService( - tap_visualizer::mojom::kServiceName); + connector_->StartService(tap_visualizer::mojom::kServiceName); } window_service_owner_ = @@ -1326,10 +1321,10 @@ std::make_unique<ProjectingObserver>(display_configurator_.get()); if (!display_initialized) { + // TODO(sky): this is dead code, cleanup. if (config != Config::CLASSIC && !chromeos::IsRunningAsSystemCompositor()) { display::mojom::DevDisplayControllerPtr controller; - shell_delegate_->GetShellConnector()->BindInterface( - ui::mojom::kServiceName, &controller); + connector_->BindInterface(ui::mojom::kServiceName, &controller); display_manager_->SetDevDisplayController(std::move(controller)); }
diff --git a/ash/shell.h b/ash/shell.h index d9635dc3..7a67c84 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -648,15 +648,15 @@ friend class SmsObserverTest; Shell(std::unique_ptr<ShellDelegate> shell_delegate, - std::unique_ptr<ShellPort> shell_port); + std::unique_ptr<ShellPort> shell_port, + service_manager::Connector* connector); ~Shell() override; void Init( ui::ContextFactory* context_factory, ui::ContextFactoryPrivate* context_factory_private, std::unique_ptr<base::Value> initial_display_prefs, - std::unique_ptr<ui::ws2::GpuInterfaceProvider> gpu_interface_provider, - service_manager::Connector* connector); + std::unique_ptr<ui::ws2::GpuInterfaceProvider> gpu_interface_provider); // Initializes the display manager and related components. void InitializeDisplayManager(); @@ -717,7 +717,7 @@ std::unique_ptr<CastConfigController> cast_config_; std::unique_ptr<ClientImageRegistry> client_image_registry_; std::unique_ptr<CrosDisplayConfig> cros_display_config_; - service_manager::Connector* connector_ = nullptr; + service_manager::Connector* const connector_; std::unique_ptr<DetachableBaseHandler> detachable_base_handler_; std::unique_ptr<DetachableBaseNotificationController> detachable_base_notification_controller_;
diff --git a/ash/shell/content/client/shell_browser_main_parts.cc b/ash/shell/content/client/shell_browser_main_parts.cc index 2959913..28cce01 100644 --- a/ash/shell/content/client/shell_browser_main_parts.cc +++ b/ash/shell/content/client/shell_browser_main_parts.cc
@@ -95,6 +95,8 @@ init_params.context_factory_private = content::GetContextFactoryPrivate(); init_params.gpu_interface_provider = std::make_unique<ContentGpuInterfaceProvider>(); + init_params.connector = + content::ServiceManagerConnection::GetForProcess()->GetConnector(); ash::Shell::CreateInstance(std::move(init_params)); // Initialize session controller client and create fake user sessions. The
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc index e08334d..427f3c5 100644 --- a/ash/shell/shell_delegate_impl.cc +++ b/ash/shell/shell_delegate_impl.cc
@@ -17,10 +17,6 @@ ShellDelegateImpl::~ShellDelegateImpl() = default; -::service_manager::Connector* ShellDelegateImpl::GetShellConnector() const { - return nullptr; -} - bool ShellDelegateImpl::CanShowWindowForUser(aura::Window* window) const { return true; }
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h index 43a10bb5..00b94a479 100644 --- a/ash/shell/shell_delegate_impl.h +++ b/ash/shell/shell_delegate_impl.h
@@ -24,7 +24,6 @@ ~ShellDelegateImpl() override; // ShellDelegate: - ::service_manager::Connector* GetShellConnector() const override; bool CanShowWindowForUser(aura::Window* window) const override; void PreInit() override; std::unique_ptr<keyboard::KeyboardUI> CreateKeyboardUI() override;
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h index 4c884765..8e0dfc23 100644 --- a/ash/shell_delegate.h +++ b/ash/shell_delegate.h
@@ -20,10 +20,6 @@ class KeyboardUI; } -namespace service_manager { -class Connector; -} - namespace ui { class InputDeviceControllerClient; } @@ -39,9 +35,6 @@ // The Shell owns the delegate. virtual ~ShellDelegate() {} - // Returns the connector for the mojo service manager. Returns null in tests. - virtual service_manager::Connector* GetShellConnector() const = 0; - // Returns true if |window| can be shown for the delegate's concept of current // user. virtual bool CanShowWindowForUser(aura::Window* window) const = 0;
diff --git a/ash/shell_delegate_mash.cc b/ash/shell_delegate_mash.cc index bcd5ea4e..a686ac9 100644 --- a/ash/shell_delegate_mash.cc +++ b/ash/shell_delegate_mash.cc
@@ -9,6 +9,7 @@ #include "ash/accessibility/default_accessibility_delegate.h" #include "ash/screenshot_delegate.h" +#include "ash/shell.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "components/user_manager/user_info_impl.h" @@ -42,15 +43,10 @@ } // namespace -ShellDelegateMash::ShellDelegateMash(service_manager::Connector* connector) - : connector_(connector) {} +ShellDelegateMash::ShellDelegateMash() = default; ShellDelegateMash::~ShellDelegateMash() = default; -service_manager::Connector* ShellDelegateMash::GetShellConnector() const { - return connector_; -} - bool ShellDelegateMash::CanShowWindowForUser(aura::Window* window) const { NOTIMPLEMENTED_LOG_ONCE(); return true; @@ -76,12 +72,13 @@ ui::InputDeviceControllerClient* ShellDelegateMash::GetInputDeviceControllerClient() { - if (!connector_) + if (!Shell::Get()->connector()) return nullptr; // Happens in tests. if (!input_device_controller_client_) { input_device_controller_client_ = - std::make_unique<ui::InputDeviceControllerClient>(connector_); + std::make_unique<ui::InputDeviceControllerClient>( + Shell::Get()->connector()); } return input_device_controller_client_.get(); }
diff --git a/ash/shell_delegate_mash.h b/ash/shell_delegate_mash.h index 2ae8231..2b06e77 100644 --- a/ash/shell_delegate_mash.h +++ b/ash/shell_delegate_mash.h
@@ -10,19 +10,14 @@ #include "ash/shell_delegate.h" #include "base/macros.h" -namespace service_manager { -class Connector; -} - namespace ash { class ShellDelegateMash : public ShellDelegate { public: - explicit ShellDelegateMash(service_manager::Connector* connector); + ShellDelegateMash(); ~ShellDelegateMash() override; // ShellDelegate: - service_manager::Connector* GetShellConnector() const override; bool CanShowWindowForUser(aura::Window* window) const override; void PreInit() override; std::unique_ptr<keyboard::KeyboardUI> CreateKeyboardUI() override; @@ -31,9 +26,6 @@ ui::InputDeviceControllerClient* GetInputDeviceControllerClient() override; private: - // |connector_| may be null in tests. - service_manager::Connector* connector_; - std::unique_ptr<ui::InputDeviceControllerClient> input_device_controller_client_;
diff --git a/ash/system/flag_warning/flag_warning_tray.cc b/ash/system/flag_warning/flag_warning_tray.cc index e5edde6..2945633 100644 --- a/ash/system/flag_warning/flag_warning_tray.cc +++ b/ash/system/flag_warning/flag_warning_tray.cc
@@ -12,7 +12,6 @@ #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" -#include "ash/shell_delegate.h" #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_container.h" #include "base/logging.h" @@ -69,8 +68,8 @@ // Open the quick launch mojo mini-app to demonstrate that mini-apps work. mash::mojom::LaunchablePtr launchable; - Shell::Get()->shell_delegate()->GetShellConnector()->BindInterface( - quick_launch::mojom::kServiceName, &launchable); + Shell::Get()->connector()->BindInterface(quick_launch::mojom::kServiceName, + &launchable); launchable->Launch(mash::mojom::kWindow, mash::mojom::LaunchMode::DEFAULT); }
diff --git a/ash/test_shell_delegate.cc b/ash/test_shell_delegate.cc index 720a706f..595a0c1 100644 --- a/ash/test_shell_delegate.cc +++ b/ash/test_shell_delegate.cc
@@ -17,10 +17,6 @@ TestShellDelegate::~TestShellDelegate() = default; -::service_manager::Connector* TestShellDelegate::GetShellConnector() const { - return nullptr; -} - bool TestShellDelegate::CanShowWindowForUser(aura::Window* window) const { return true; }
diff --git a/ash/test_shell_delegate.h b/ash/test_shell_delegate.h index ab05b16..f40ee11 100644 --- a/ash/test_shell_delegate.h +++ b/ash/test_shell_delegate.h
@@ -18,7 +18,6 @@ ~TestShellDelegate() override; // Overridden from ShellDelegate: - ::service_manager::Connector* GetShellConnector() const override; bool CanShowWindowForUser(aura::Window* window) const override; void PreInit() override; std::unique_ptr<keyboard::KeyboardUI> CreateKeyboardUI() override;
diff --git a/ash/wallpaper/wallpaper_utils/wallpaper_decoder.cc b/ash/wallpaper/wallpaper_utils/wallpaper_decoder.cc index 98f37c5..f4831b4 100644 --- a/ash/wallpaper/wallpaper_utils/wallpaper_decoder.cc +++ b/ash/wallpaper/wallpaper_utils/wallpaper_decoder.cc
@@ -5,7 +5,6 @@ #include "ash/wallpaper/wallpaper_utils/wallpaper_decoder.h" #include "ash/shell.h" -#include "ash/shell_delegate.h" #include "ipc/ipc_channel.h" namespace ash { @@ -33,16 +32,16 @@ const data_decoder::mojom::ImageCodec& image_codec, OnWallpaperDecoded callback) { // The connector for the mojo service manager is null in unit tests. - if (!Shell::Get()->shell_delegate()->GetShellConnector()) { + if (!Shell::Get()->connector()) { std::move(callback).Run(gfx::ImageSkia()); return; } std::vector<uint8_t> image_bytes(image_data.begin(), image_data.end()); data_decoder::DecodeImage( - Shell::Get()->shell_delegate()->GetShellConnector(), - std::move(image_bytes), image_codec, /*shrink_to_fit=*/true, - kMaxImageSizeInBytes, /*desired_image_frame_size=*/gfx::Size(), + Shell::Get()->connector(), std::move(image_bytes), image_codec, + /*shrink_to_fit=*/true, kMaxImageSizeInBytes, + /*desired_image_frame_size=*/gfx::Size(), base::BindOnce(&ConvertToImageSkia, std::move(callback))); } -} // namespace ash \ No newline at end of file +} // namespace ash
diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py index 302f0a67..fe9b7a5 100755 --- a/build/android/gradle/generate_gradle.py +++ b/build/android/gradle/generate_gradle.py
@@ -334,7 +334,7 @@ return _DEFAULT_ANDROID_MANIFEST_PATH variables = {} - variables['compile_sdk_version'] = self.build_vars['android_sdk_version'] + variables['compile_sdk_version'] = self.build_vars['compile_sdk_version'] variables['package'] = resource_packages[0] output_file = os.path.join( @@ -550,7 +550,7 @@ variables = {} variables['build_tools_version'] = source_properties['Pkg.Revision'] variables['compile_sdk_version'] = ( - 'android-%s' % build_vars['android_sdk_version']) + 'android-%s' % build_vars['compile_sdk_version']) target_sdk_version = build_vars['android_sdk_version'] if target_sdk_version.isalpha(): target_sdk_version = '"{}"'.format(target_sdk_version) @@ -820,6 +820,12 @@ action='append', help='GN native targets to generate for. May be ' 'repeated.') + parser.add_argument('--compile-sdk-version', + type=int, + default=0, + help='Override compileSdkVersion for android sdk docs. ' + 'Useful when sources for android_sdk_version is ' + 'not available in Android Studio.') version_group = parser.add_mutually_exclusive_group() version_group.add_argument('--beta', action='store_true', @@ -895,6 +901,10 @@ channel = 'canary' else: channel = 'stable' + if args.compile_sdk_version: + build_vars['compile_sdk_version'] = args.compile_sdk_version + else: + build_vars['compile_sdk_version'] = build_vars['android_sdk_version'] generator = _ProjectContextGenerator(_gradle_output_dir, build_vars, args.use_gradle_process_resources, jinja_processor, args.split_projects, channel)
diff --git a/build/android/gradle/root.jinja b/build/android/gradle/root.jinja index 76ffa8f6..bf76bde 100644 --- a/build/android/gradle/root.jinja +++ b/build/android/gradle/root.jinja
@@ -10,7 +10,7 @@ } dependencies { {% if channel == 'canary' %} - classpath "com.android.tools.build:gradle:3.2.0-alpha16" + classpath "com.android.tools.build:gradle:3.3.0-alpha03" {% elif channel == 'beta' %} classpath "com.android.tools.build:gradle:3.1.0-beta4" {% else %}
diff --git a/build/android/gyp/generate_proguarded_module_jar.py b/build/android/gyp/generate_proguarded_module_jar.py new file mode 100755 index 0000000..97b3027a --- /dev/null +++ b/build/android/gyp/generate_proguarded_module_jar.py
@@ -0,0 +1,159 @@ +#!/usr/bin/env python +# +# Copyright (c) 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Extracts a bundle module's classes from jar created in the synchronized +proguarding step and packages them into a new jar. + +Synchronized proguarding means that, when several app modules are combined into +an app bundle, all un-optimized jars for all modules are grouped and sent to a +single proguard command, which generates a single, common, intermediate +optimized jar, and its mapping file. + +This script is used to extract, from this synchronized proguard jar, all the +optimized classes corresponding to a single module, into a new .jar file. The +latter will be compiled later into the module's dex file. + +For this, the script reads the module's un-obfuscated class names from the +module's unoptimized jars. Then, it maps those to obfuscated class names using +the proguard mapping file. Finally, it extracts the module's class files from +the proguarded jar and zips them into a new module jar. """ + +import argparse +import os +import sys +import zipfile + +from util import build_utils + +MANIFEST = """Manifest-Version: 1.0 +Created-By: generate_proguarded_module_jar.py +""" + + +# TODO(tiborg): Share with merge_jar_info_files.py. +def _FullJavaNameFromClassFilePath(path): + if not path.endswith('.class'): + return '' + path = os.path.splitext(path)[0] + parts = [] + while path: + # Use split to be platform independent. + head, tail = os.path.split(path) + path = head + parts.append(tail) + parts.reverse() # Package comes first + return '.'.join(parts) + + +def main(args): + args = build_utils.ExpandFileArgs(args) + parser = argparse.ArgumentParser() + build_utils.AddDepfileOption(parser) + parser.add_argument( + '--proguarded-jar', + required=True, + help='Path to input jar produced by synchronized proguarding') + parser.add_argument( + '--proguard-mapping', + required=True, + help='Path to input proguard mapping produced by synchronized ' + 'proguarding') + parser.add_argument( + '--module-input-jars', + required=True, + help='GN-list of input paths to un-optimized jar files for the current ' + 'module. The optimized versions of their .class files will go into ' + 'the output jar.') + parser.add_argument( + '--output-jar', + required=True, + help='Path to output jar file containing the module\'s optimized class ' + 'files') + parser.add_argument( + '--is-base-module', + action='store_true', + help='Inidcates to extract class files for a base module') + options = parser.parse_args(args) + options.module_input_jars = build_utils.ParseGnList(options.module_input_jars) + + # Read class names of the currently processed module. + classes = set() + for module_jar in options.module_input_jars: + with zipfile.ZipFile(module_jar) as zip_info: + for path in zip_info.namelist(): + fully_qualified_name = _FullJavaNameFromClassFilePath(path) + if fully_qualified_name: + classes.add(fully_qualified_name) + + # Parse the proguarding mapping to be able to map un-obfuscated to obfuscated + # names. + # Proguard mapping files have the following format: + # + # {un-obfuscated class name 1} -> {obfuscated class name 1}: + # {un-obfuscated member name 1} -> {obfuscated member name 1} + # ... + # {un-obfuscated class name 2} -> {obfuscated class name 2}: + # ... + # ... + obfuscation_map = {} + with open(options.proguard_mapping, 'r') as proguard_mapping_file: + for line in proguard_mapping_file: + # Skip indented lines since they map member names and not class names. + if line.startswith(' '): + continue + line = line.strip() + # Skip empty lines. + if not line: + continue + assert line.endswith(':') + full, obfuscated = line.strip(':').split(' -> ') + assert full + assert obfuscated + obfuscation_map[full] = obfuscated + + # Collect the obfuscated names of classes, which should go into the currently + # processed module. + obfuscated_module_classes = set( + obfuscation_map[c] for c in classes if c in obfuscation_map) + + # Collect horizontally merged classes to later make sure that those only go + # into the base module. Merging classes horizontally means that proguard took + # two classes that don't inherit from each other and merged them into one. + horiz_merged_classes = set() + obfuscated_classes = sorted(obfuscation_map.values()) + prev_obfuscated_class = None + for obfuscated_class in obfuscated_classes: + if prev_obfuscated_class and obfuscated_class == prev_obfuscated_class: + horiz_merged_classes.add(obfuscated_class) + prev_obfuscated_class = obfuscated_class + + # Move horizontally merged classes into the base module. + if options.is_base_module: + obfuscated_module_classes |= horiz_merged_classes + else: + obfuscated_module_classes -= horiz_merged_classes + + # Extract module class files from proguarded jar and store them in a module + # split jar. + with zipfile.ZipFile( + os.path.abspath(options.output_jar), 'w', + zipfile.ZIP_DEFLATED) as output_jar: + with zipfile.ZipFile(os.path.abspath(options.proguarded_jar), + 'r') as proguarded_jar: + for obfuscated_class in obfuscated_module_classes: + class_path = obfuscated_class.replace('.', '/') + '.class' + class_file_content = proguarded_jar.read(class_path) + output_jar.writestr(class_path, class_file_content) + output_jar.writestr('META-INF/MANIFEST.MF', MANIFEST) + + if options.depfile: + build_utils.WriteDepfile( + options.depfile, options.output_jar, options.module_input_jars + + [options.proguard_mapping, options.proguarded_jar], add_pydeps=False) + + +if __name__ == '__main__': + main(sys.argv[1:])
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py index 57edacc..a4519b2 100755 --- a/build/android/gyp/write_build_config.py +++ b/build/android/gyp/write_build_config.py
@@ -495,6 +495,16 @@ The list of annotation processor main classes. I.e. sent as `-processor' when invoking `javac`. +## <a name="android_app_bundle">Target type `android_app_bundle`</a>: + +This type corresponds to an Android app bundle (`.aab` file). + +* `deps_info['synchronized_proguard_enabled"]`: +True to indicate that the app modules of this bundle should be proguarded in a +single synchronized proguarding step. Synchronized proguarding means that all +un-optimized jars for all modules are sent to a single proguard command. The +resulting optimized jar is then split into optimized app module jars after. + --------------- END_MARKDOWN --------------------------------------------------- """ @@ -851,7 +861,9 @@ help='Path to the build config of the tested apk (for an instrumentation ' 'test apk).') parser.add_option('--proguard-enabled', action='store_true', - help='Whether proguard is enabled for this apk.') + help='Whether proguard is enabled for this apk or bundle module.') + parser.add_option('--synchronized-proguard-enabled', action='store_true', + help='Whether synchronized proguarding is enabled for this bundle.') parser.add_option('--proguard-configs', help='GN-list of proguard flag files to use in final apk.') parser.add_option('--proguard-output-jar-path', @@ -1187,6 +1199,11 @@ if is_java_target and options.jar_path: java_full_classpath.append(options.jar_path) java_full_classpath.extend(c['jar_path'] for c in all_library_deps) + if options.type == 'android_app_bundle': + for d in deps.Direct('android_app_bundle_module'): + java_full_classpath.extend( + c for c in d.get('java_runtime_classpath', []) + if c not in java_full_classpath) system_jars = [c['jar_path'] for c in system_library_deps] system_interface_jars = [c['interface_jar_path'] for c in system_library_deps] @@ -1209,7 +1226,16 @@ p for p in c.get('proguard_configs', []) if p not in all_configs) extra_jars.extend( p for p in c.get('extra_classpath_jars', []) if p not in extra_jars) + if options.type == 'android_app_bundle': + for c in deps.Direct('android_app_bundle_module'): + all_configs.extend( + p for p in c.get('proguard_configs', []) if p not in all_configs) deps_info['proguard_all_configs'] = all_configs + if options.type == 'android_app_bundle': + for d in deps.Direct('android_app_bundle_module'): + extra_jars.extend( + c for c in d.get('proguard_classpath_jars', []) + if c not in extra_jars) deps_info['proguard_classpath_jars'] = extra_jars if options.type == 'android_app_bundle': @@ -1227,7 +1253,16 @@ raise Exception('Deps %s have proguard enabled while deps %s have ' 'proguard disabled' % (deps_proguard_enabled, deps_proguard_disabled)) - deps_info['sync_proguard_enabled'] = bool(deps_proguard_enabled) + if (bool(deps_proguard_enabled) != + bool(options.synchronized_proguard_enabled) or + bool(deps_proguard_disabled) == + bool(options.synchronized_proguard_enabled)): + raise Exception('Modules %s of bundle %s have opposite proguard ' + 'enabling flags than bundle' % (deps_proguard_enabled + + deps_proguard_disabled, config['deps_info']['name']) + ) + deps_info['synchronized_proguard_enabled'] = bool( + options.synchronized_proguard_enabled) else: deps_info['proguard_enabled'] = bool(options.proguard_enabled) if options.proguard_output_jar_path:
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 345b77c9..379efef 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -376,6 +376,10 @@ if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) { args += [ "--proguard-enabled" ] } + if (defined(invoker.synchronized_proguard_enabled) && + invoker.synchronized_proguard_enabled) { + args += [ "--synchronized-proguard-enabled" ] + } if (defined(invoker.proguard_output_jar_path)) { _rebased_proguard_output_jar_path = rebase_path(invoker.proguard_output_jar_path, root_build_dir) @@ -3267,6 +3271,9 @@ # # build_config: Path to build_config of the android_apk_or_module() target. # +# dex_path_file_arg: Path to the module's dex file passed directly to the +# creation script. Must be a rebased path or @FileArg expression. +# template("create_android_app_bundle_module") { _build_config = invoker.build_config _rebased_build_config = rebase_path(_build_config, root_build_dir) @@ -3298,7 +3305,7 @@ "--format=bundle-module", "--output-apk", rebase_path(invoker.module_zip_path, root_build_dir), - "--dex-file=@FileArg($_rebased_build_config:final_dex:path)", + "--dex-file=${invoker.dex_path_file_arg}", "--resource-apk=@FileArg(" + "$_rebased_build_config:deps_info:proto_resources_path)", "--assets=@FileArg($_rebased_build_config:assets)", @@ -3319,3 +3326,42 @@ } } } + +# Extracts a bundle module's classes from jar created in the synchronized +# proguarding step and packages them into a new jar. +# +# Variables: +# proguarded_jar: Path to input jar produced by synchronized proguarding. +# proguard_mapping: Path to input proguard mapping produced by synchronized +# proguarding +# output_jar: Path to output jar file containing the module's optimized class +# files. +# build_config: Path to build config of module. +# is_base_module: True if this is processing a base module. +template("generate_proguarded_module_jar") { + _rebased_build_config = rebase_path(invoker.build_config, root_build_dir) + + action(target_name) { + forward_variables_from(invoker, [ "deps" ]) + script = "//build/android/gyp/generate_proguarded_module_jar.py" + inputs = build_utils_py + outputs = [ + invoker.output_jar, + ] + depfile = "${target_gen_dir}/${target_name}.d" + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--proguarded-jar", + rebase_path(invoker.proguarded_jar, root_build_dir), + "--proguard-mapping", + rebase_path(invoker.proguard_mapping, root_build_dir), + "--module-input-jars=@FileArg(${_rebased_build_config}:deps_info:java_runtime_classpath)", + "--output-jar", + rebase_path(invoker.output_jar, root_build_dir), + ] + if (defined(invoker.is_base_module) && invoker.is_base_module) { + args += [ "--is-base-module" ] + } + } +}
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 356544b..2bf284a 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1932,7 +1932,6 @@ } else { _final_dex_path = "$_gen_dir/classes.dex" } - _final_dex_target_name = "${_template_name}__final_dex" if (defined(invoker.final_apk_path)) { _final_apk_path = invoker.final_apk_path @@ -2388,85 +2387,102 @@ } } - if (_proguard_enabled) { - _proguard_target = "${_template_name}__proguard" - proguard(_proguard_target) { - forward_variables_from(invoker, [ "proguard_jar_path" ]) - build_config = _build_config - deps = _deps + [ - ":$_build_config_target", - ":$_compile_resources_target", - ":$_java_target", - ] - inputs = [ - _jar_path, - ] + # When using an app bundle that is made of several modules, it is crucial to + # ensure that the obfuscated class names used by each module are consistent. + # + # To achieve this, all modules belonging to the same app bundle must + # be grouped into a single .jar, that will be proguarded all at once. This + # is called "synchronized proguarding", and ensures that the obfuscated + # names of all classes remain consistent across modules. + # + # Later, this single optimized .jar is processed to generate module-specific + # .jar files that only contain the obfuscated classes needed by the module + # itself. + # + # This synchronized proguarding step is added by the bundle target. + if (!_is_bundle_module || !_proguard_enabled) { + if (_proguard_enabled) { + _proguard_target = "${_template_name}__proguard" + proguard(_proguard_target) { + forward_variables_from(invoker, [ "proguard_jar_path" ]) + build_config = _build_config + deps = _deps + [ + ":$_build_config_target", + ":$_compile_resources_target", + ":$_java_target", + ] + inputs = [ + _jar_path, + ] - output_jar_path = _proguard_output_jar_path - args = [ - "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)", - "--input-paths=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)", - ] - if (defined(invoker.proguard_config_exclusions)) { - _rebased_proguard_config_exclusions = - rebase_path(invoker.proguard_config_exclusions, root_build_dir) - args += [ - "--proguard-config-exclusions=$_rebased_proguard_config_exclusions", + output_jar_path = _proguard_output_jar_path + args = [ + "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)", + "--input-paths=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)", + ] + if (defined(invoker.proguard_config_exclusions)) { + _rebased_proguard_config_exclusions = + rebase_path(invoker.proguard_config_exclusions, root_build_dir) + args += [ "--proguard-config-exclusions=$_rebased_proguard_config_exclusions" ] + } + } + _dex_sources = [ _proguard_output_jar_path ] + _dex_deps = [ ":$_proguard_target" ] + + _copy_proguard_mapping_target = + "${_template_name}__copy_proguard_mapping" + copy(_copy_proguard_mapping_target) { + sources = [ + "$_proguard_output_jar_path.mapping", + ] + outputs = [ + "$_final_apk_path.mapping", + ] + deps = [ + ":$_proguard_target", ] } + } else { + if (_enable_multidex) { + # .jar already included in java_runtime_classpath. + _dex_sources = [] + } else { + _dex_sources = [ _lib_dex_path ] + } + _dex_deps = [ ":$_java_target" ] } - _dex_sources = [ _proguard_output_jar_path ] - _dex_deps = [ ":$_proguard_target" ] - _copy_proguard_mapping_target = "${_template_name}__copy_proguard_mapping" - copy(_copy_proguard_mapping_target) { - sources = [ - "$_proguard_output_jar_path.mapping", - ] - outputs = [ - "$_final_apk_path.mapping", - ] - deps = [ - ":$_proguard_target", - ] + _final_dex_target_name = "${_template_name}__final_dex" + dex("$_final_dex_target_name") { + deps = _dex_deps + [ ":$_build_config_target" ] + input_jars = _dex_sources + output = _final_dex_path + enable_multidex = _enable_multidex + + if (_enable_multidex) { + forward_variables_from(invoker, [ "negative_main_dex_globs" ]) + extra_main_dex_proguard_config = _generated_proguard_main_dex_config + deps += [ ":$_compile_resources_target" ] + } + + # All deps are already included in _dex_sources when proguard is used. + if (!_proguard_enabled) { + if (_enable_multidex) { + _dex_arg_key = + "${_rebased_build_config}:deps_info:java_runtime_classpath" + } else { + _dex_arg_key = + "${_rebased_build_config}:final_dex:dependency_dex_files" + } + build_config = _build_config + input_jars_file_arg = "@FileArg($_dex_arg_key)" + } + + # http://crbug.com/725224. Fix for bots running out of memory. + use_pool = true } } else { - if (_enable_multidex) { - # .jar already included in java_runtime_classpath. - _dex_sources = [] - } else { - _dex_sources = [ _lib_dex_path ] - } - _dex_deps = [ ":$_java_target" ] - } - - dex("$_final_dex_target_name") { - deps = _dex_deps + [ ":$_build_config_target" ] - input_jars = _dex_sources - output = _final_dex_path - enable_multidex = _enable_multidex - - if (_enable_multidex) { - forward_variables_from(invoker, [ "negative_main_dex_globs" ]) - extra_main_dex_proguard_config = _generated_proguard_main_dex_config - deps += [ ":$_compile_resources_target" ] - } - - # All deps are already included in _dex_sources when proguard is used. - if (!_proguard_enabled) { - if (_enable_multidex) { - _dex_arg_key = - "${_rebased_build_config}:deps_info:java_runtime_classpath" - } else { - _dex_arg_key = - "${_rebased_build_config}:final_dex:dependency_dex_files" - } - build_config = _build_config - input_jars_file_arg = "@FileArg($_dex_arg_key)" - } - - # http://crbug.com/725224. Fix for bots running out of memory. - use_pool = true + _final_deps += [ ":$_java_target" ] } _native_libs_file_arg_dep = ":$_build_config_target" @@ -2598,7 +2614,7 @@ _final_deps += [ ":$_merge_manifest_target", ":$_build_config_target", - ":$_final_dex_target_name", + ":$_compile_resources_target", ] + _all_native_libs_deps } @@ -2711,7 +2727,7 @@ public_deps += _apk_operations # Make the proguard .mapping file easy to find by putting it beside the .apk. - if (_proguard_enabled) { + if (_proguard_enabled && !_is_bundle_module) { deps = [ ":$_copy_proguard_mapping_target", ] @@ -3614,9 +3630,6 @@ # base module), and an 'apk_target' field that specified the # corresponding android_apk target name the module is modeled on. # - # extra_module_apk_targets: Optional list of android_apk target matching - # the names listed in extra_module_names. - # # enable_language_splits: Optional. If true, enable APK splits based # on languages. # @@ -3637,11 +3650,19 @@ # APKs use 'chrome-command-line', the WebView one uses # 'webview-command-line'). # + # synchronized_proguard_enabled: True if synchronized proguarding is + # enabled for this bundle. WARNING: All modules that contain Java must + # have proguarding enabled if this is true and disabled if this is false. + # + # proguard_jar_path: Path to custom proguard jar used for synchronized + # proguarding. WARNING: Can only be set if + # |synchronized_proguard_enabled| is set to true. + # # Example: # android_app_bundle("chrome_public_bundle") { # base_module_target = "//chrome/android:chrome_public_apk" # extra_modules = [ - # { # NOTE: Scopes require one field per line, and no comma separators. + # { # NOTE: Scopes require one field per line, and no comma separators. # name = "my_module" # module_target = ":my_module" # }, @@ -3671,44 +3692,118 @@ _all_modules += invoker.extra_modules } + _synchronized_proguard_enabled = + defined(invoker.synchronized_proguard_enabled) && + invoker.synchronized_proguard_enabled + # Make build config, which is required for synchronized proguarding. _module_targets = [] foreach(_module, _all_modules) { _module_targets += [ _module.module_target ] } _build_config = "$target_gen_dir/${target_name}.build_config" + _rebased_build_config = rebase_path(_build_config, root_build_dir) _build_config_target = "${target_name}__build_config" write_build_config(_build_config_target) { type = "android_app_bundle" possible_config_deps = _module_targets build_config = _build_config + synchronized_proguard_enabled = _synchronized_proguard_enabled } - # Generate one module .zip file per APK. + if (_synchronized_proguard_enabled) { + # Proguard all modules together to keep binary size small while still + # maintaining compatibility between modules. + _proguard_output_jar_path = + "${target_gen_dir}/${target_name}/${target_name}.proguard.jar" + _sync_proguard_target = "${target_name}__sync_proguard" + proguard(_sync_proguard_target) { + build_config = _build_config + deps = _module_targets + [ ":$_build_config_target" ] + + output_jar_path = _proguard_output_jar_path + args = [ + "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)", + "--input-paths=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)", + ] + + if (defined(invoker.proguard_jar_path)) { + proguard_jar_path = invoker.proguard_jar_path + } + } + } + _all_create_module_targets = [] _all_module_zip_paths = [] _all_module_build_configs = [] foreach(_module, _all_modules) { + _module_target = _module.module_target + _module_target_name = get_label_info(_module_target, "name") + _module_target_gen_dir = get_label_info(_module_target, "target_gen_dir") + _module_build_config_target = "${_module_target}__build_config" + _module_build_config = + "$_module_target_gen_dir/${_module_target_name}.build_config" + + if (_synchronized_proguard_enabled) { + # Extract optimized classes for each module and dex them. + + _module_final_dex_target = "${target_name}__${_module.name}__dex" + _module_final_dex_target_dep = ":$_module_final_dex_target" + _module_final_dex_path = + "$target_gen_dir/$target_name/${_module.name}/classes.dex" + _module_final_dex_path_file_arg = + rebase_path(_module_final_dex_path, root_build_dir) + + _module_jar_path = + "${target_gen_dir}/${target_name}/${_module.name}.optimized.jar" + _generate_proguarded_module_jar_target = + "${target_name}__${_module.name}__module_jar" + generate_proguarded_module_jar(_generate_proguarded_module_jar_target) { + proguarded_jar = _proguard_output_jar_path + build_config = _module_build_config + proguard_mapping = "${_proguard_output_jar_path}.mapping" + output_jar = _module_jar_path + is_base_module = _module.name == "base" + deps = [ + ":${_sync_proguard_target}", + "$_module_build_config_target", + "${_module.module_target}", + ] + } + + dex(_module_final_dex_target) { + deps = [ + ":${_generate_proguarded_module_jar_target}", + ] + input_jars = [ _module_jar_path ] + output = _module_final_dex_path + + # http://crbug.com/725224. Fix for bots running out of memory. + use_pool = true + } + } else { + _module_final_dex_target_dep = "${_module_target}__final_dex" + _rebased_module_build_config = + rebase_path(_module_build_config, root_build_dir) + _module_final_dex_path_file_arg = + "@FileArg($_rebased_module_build_config:final_dex:path)" + } + + # Generate one module .zip file per bundle module. + # # Important: the bundle tool uses the module's zip filename as # the internal module name inside the final bundle, in other words, # this file *must* be named ${_module.name}.zip _create_module_target = "${target_name}__${_module.name}__create" _module_zip_path = "$target_gen_dir/$target_name/${_module.name}.zip" - _module_target = _module.module_target - _module_build_config_target = "${_module_target}__build_config" - - # Determine the rebased path to the module's target .build_config - # In order to pass its list of uncompressed assets later. - _module_target_name = get_label_info(_module_target, "name") - _module_target_gen_dir = get_label_info(_module_target, "target_gen_dir") - _module_build_config = - "$_module_target_gen_dir/${_module_target_name}.build_config" create_android_app_bundle_module(_create_module_target) { build_config = _module_build_config module_zip_path = _module_zip_path + dex_path_file_arg = _module_final_dex_path_file_arg deps = [ "$_module_build_config_target", + "$_module_final_dex_target_dep", "$_module_target", ] }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 1f7de393..db2f45df 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -592,10 +592,7 @@ # example by disabling the optimize configuration. # TODO(pcc): Make this conditional on is_official_build rather than on gn # flags for specific features. - if (!is_debug && use_thin_lto && - (current_toolchain == default_toolchain || - (is_android && defined(android_secondary_abi_toolchain) && - current_toolchain == android_secondary_abi_toolchain))) { + if (!is_debug && use_thin_lto && current_toolchain == default_toolchain) { assert(use_lld || target_os == "chromeos", "gold plugin only supported with ChromeOS") @@ -1473,9 +1470,6 @@ # TODO(thakis): Only for no_chromium_code? http://crbug.com/505314 "-Wno-ignored-pragma-optimize", ] - if (llvm_force_head_revision) { - cflags += [ "-Wno-memset-transposed-args" ] - } } } }
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index cb8630d6..0b13302 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -43,7 +43,7 @@ # Enables support for ThinLTO, which links 3x-10x faster than full LTO. See # also http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html - use_thin_lto = is_cfi || (is_android && is_official_build) + use_thin_lto = is_cfi # Tell VS to create a PDB that references information in .obj files rather # than copying it all. This should improve linker performance. mspdbcmf.exe
diff --git a/build/config/coverage/BUILD.gn b/build/config/coverage/BUILD.gn index fb37787..6fd4fd5f 100644 --- a/build/config/coverage/BUILD.gn +++ b/build/config/coverage/BUILD.gn
@@ -17,10 +17,25 @@ "-mllvm", "-limited-coverage-experimental=true", ] - ldflags = [ "-fprofile-instr-generate" ] + ldflags = [] if (!is_win) { + ldflags += [ "-fprofile-instr-generate" ] cflags += [ "-fno-use-cxa-atexit" ] + } else { + # Windows directly calls link.exe instead of the compiler driver when + # linking. Hence, pass the runtime libraries instead of + # -fsanitize=address. + # TODO(rnk): Come up with a more uniform approach for linking against + # compiler-rt for sanitizers and coverage. + if (target_cpu == "x64") { + ldflags += [ "clang_rt.profile-x86_64.lib" ] + } else if (target_cpu == "x86") { + ldflags += [ "clang_rt.profile-i386.lib" ] + } else { + assert(false && + "use_clang_coverage=true not supported yet for this target_cpu") + } } } }
diff --git a/build/fuchsia/sdk.sha1 b/build/fuchsia/sdk.sha1 index e8b9ca0..b1cade3 100644 --- a/build/fuchsia/sdk.sha1 +++ b/build/fuchsia/sdk.sha1
@@ -1 +1 @@ -be1455d02b09799d1150be98feab598f91f00200 \ No newline at end of file +0e8488b5f1c0c1cdb03f50b262f3d61cbbe9c96a \ No newline at end of file
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 4909496..8b819ee 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1609,12 +1609,15 @@ sign_bundle = is_official_build enable_language_splits = true + synchronized_proguard_enabled = !is_java_debug } android_app_bundle("chrome_modern_public_bundle") { base_module_target = ":chrome_modern_public_base_module" + synchronized_proguard_enabled = !is_java_debug } android_app_bundle("monochrome_public_bundle") { base_module_target = ":monochrome_public_base_module" + synchronized_proguard_enabled = !is_java_debug }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java index 4431679..6591a5b8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java
@@ -158,6 +158,8 @@ // https://w3c.github.io/webpayments-methods-credit-transfer-direct-debit/ supportedNonUriPaymentMethods.add("payee-credit-transfer"); supportedNonUriPaymentMethods.add("payer-credit-transfer"); + // https://w3c.github.io/webpayments-methods-tokenization/ + supportedNonUriPaymentMethods.add("tokenized-card"); mNonUriPaymentMethods = new HashSet<>(); mUriPaymentMethods = new HashSet<>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java index f2e3a465..f3e4ba7e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
@@ -63,7 +63,8 @@ /** * Reasons that the user was rejected from being selected for a survey - * Note: these values must match the SurveyFilteringResult enum in enums.xml. + * Note: these values cannot change and must match the SurveyFilteringResult enum in enums.xml + * because they're written to logs. */ @IntDef({FilteringResult.SURVEY_INFOBAR_ALREADY_DISPLAYED, FilteringResult.FORCE_SURVEY_ON_COMMAND_PRESENT,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinderTest.java index 7ed11b3..f0c7e60 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinderTest.java
@@ -1062,24 +1062,27 @@ methods.add("interledger"); methods.add("payee-credit-transfer"); methods.add("payer-credit-transfer"); + methods.add("tokenized-card"); methods.add("not-supported"); mPackageManager.installPaymentApp("AlicePay", "com.alicepay", "" /* no default payment method name in metadata */, "AA"); mPackageManager.setStringArrayMetaData("com.alicepay", new String[] {"basic-card", "interledger", "payee-credit-transfer", - "payer-credit-transfer", "not-supported"}); + "payer-credit-transfer", "tokenized-card", "not-supported"}); findApps(methods); Assert.assertEquals("1 app should match the query", 1, mPaymentApps.size()); Assert.assertEquals("com.alicepay", mPaymentApps.get(0).getAppIdentifier()); - Assert.assertEquals(4, mPaymentApps.get(0).getAppMethodNames().size()); + Assert.assertEquals(5, mPaymentApps.get(0).getAppMethodNames().size()); Assert.assertTrue(mPaymentApps.get(0).getAppMethodNames().contains("basic-card")); Assert.assertTrue(mPaymentApps.get(0).getAppMethodNames().contains("interledger")); Assert.assertTrue( mPaymentApps.get(0).getAppMethodNames().contains("payee-credit-transfer")); Assert.assertTrue( mPaymentApps.get(0).getAppMethodNames().contains("payer-credit-transfer")); + Assert.assertTrue( + mPaymentApps.get(0).getAppMethodNames().contains("tokenized-card")); mPaymentApps.clear(); mAllPaymentAppsCreated = false; @@ -1088,13 +1091,15 @@ Assert.assertEquals("1 app should still match the query", 1, mPaymentApps.size()); Assert.assertEquals("com.alicepay", mPaymentApps.get(0).getAppIdentifier()); - Assert.assertEquals(4, mPaymentApps.get(0).getAppMethodNames().size()); + Assert.assertEquals(5, mPaymentApps.get(0).getAppMethodNames().size()); Assert.assertTrue(mPaymentApps.get(0).getAppMethodNames().contains("basic-card")); Assert.assertTrue(mPaymentApps.get(0).getAppMethodNames().contains("interledger")); Assert.assertTrue( mPaymentApps.get(0).getAppMethodNames().contains("payee-credit-transfer")); Assert.assertTrue( mPaymentApps.get(0).getAppMethodNames().contains("payer-credit-transfer")); + Assert.assertTrue( + mPaymentApps.get(0).getAppMethodNames().contains("tokenized-card")); } private void findApps(final Set<String> methodNames) throws Throwable {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java index 0d91baf..c538317 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java
@@ -327,13 +327,14 @@ }); } + @IntDef({MenuItemState.DISABLED, MenuItemState.ENABLED}) @Retention(RetentionPolicy.SOURCE) - @IntDef({MENU_ITEM_STATE_DISABLED, MENU_ITEM_STATE_ENABLED}) - private @interface MenuItemState {} - /** Represents the state of an enabled menu item. */ - private static final int MENU_ITEM_STATE_DISABLED = 0; - /** Represents the state of a disabled menu item. */ - private static final int MENU_ITEM_STATE_ENABLED = 1; + private @interface MenuItemState { + /** Represents the state of an enabled menu item. */ + int DISABLED = 0; + /** Represents the state of a disabled menu item. */ + int ENABLED = 1; + } /** * Checks that the menu item for exporting passwords is enabled or disabled as expected. @@ -343,7 +344,7 @@ openActionBarOverflowOrOptionsMenu( InstrumentationRegistry.getInstrumentation().getTargetContext()); final Matcher<View> stateMatcher = - expectedState == MENU_ITEM_STATE_ENABLED ? isEnabled() : not(isEnabled()); + expectedState == MenuItemState.ENABLED ? isEnabled() : not(isEnabled()); // The text matches a text view, but the disabled entity is some wrapper two levels up in // the view hierarchy, hence the two withParent matchers. Espresso.onView(allOf(withText(R.string.save_password_preferences_export_action_title), @@ -552,7 +553,7 @@ PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), SavePasswordsPreferences.class.getName()); - checkExportMenuItemState(MENU_ITEM_STATE_DISABLED); + checkExportMenuItemState(MenuItemState.DISABLED); } /** @@ -571,7 +572,7 @@ PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), SavePasswordsPreferences.class.getName()); - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); } /** @@ -717,7 +718,7 @@ .check(doesNotExist()); // Check that the export menu item is enabled, because the current export was cancelled. - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); } /** @@ -774,7 +775,7 @@ .perform(click()); // Check that for re-triggering, the export menu item is enabled. - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); } /** @@ -807,7 +808,7 @@ preferences.getFragmentForTest().onResume(); } }); - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); } /** @@ -994,7 +995,7 @@ // Check that the cancellation succeeded by checking that the export menu is available and // enabled. - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); } /** @@ -1034,7 +1035,7 @@ // Check that the cancellation succeeded by checking that the export menu is available and // enabled. - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); } /** @@ -1081,7 +1082,7 @@ // Check that the export flow was cancelled automatically by checking that the export menu // is available and enabled. - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); } /** @@ -1114,7 +1115,7 @@ // Check that the cancellation succeeded by checking that the export menu is available and // enabled. - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); } /** @@ -1279,7 +1280,7 @@ // Check that the cancellation succeeded by checking that the export menu is available and // enabled. - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); Assert.assertEquals(1, userAbortedDelta.getDelta()); } @@ -1322,7 +1323,7 @@ // Check that the cancellation succeeded by checking that the export menu is available and // enabled. - checkExportMenuItemState(MENU_ITEM_STATE_ENABLED); + checkExportMenuItemState(MenuItemState.ENABLED); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ssl/CaptivePortalTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ssl/CaptivePortalTest.java index ff2df33..ebb7065 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ssl/CaptivePortalTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ssl/CaptivePortalTest.java
@@ -49,29 +49,30 @@ private static final int INTERSTITIAL_TITLE_UPDATE_TIMEOUT_SECONDS = 5; // UMA events copied from ssl_error_handler.h. - @IntDef({ - HANDLE_ALL, SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE, - SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE, SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE, - SHOW_SSL_INTERSTITIAL_OVERRIDABLE, WWW_MISMATCH_FOUND, WWW_MISMATCH_URL_AVAILABLE, - WWW_MISMATCH_URL_NOT_AVAILABLE, SHOW_BAD_CLOCK, CAPTIVE_PORTAL_CERT_FOUND, - WWW_MISMATCH_FOUND_IN_SAN, SHOW_MITM_SOFTWARE_INTERSTITIAL, OS_REPORTS_CAPTIVE_PORTAL, - }) + @IntDef({UMAEvent.HANDLE_ALL, UMAEvent.SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE, + UMAEvent.SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE, + UMAEvent.SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE, + UMAEvent.SHOW_SSL_INTERSTITIAL_OVERRIDABLE, UMAEvent.WWW_MISMATCH_FOUND, + UMAEvent.WWW_MISMATCH_URL_AVAILABLE, UMAEvent.WWW_MISMATCH_URL_NOT_AVAILABLE, + UMAEvent.SHOW_BAD_CLOCK, UMAEvent.CAPTIVE_PORTAL_CERT_FOUND, + UMAEvent.WWW_MISMATCH_FOUND_IN_SAN, UMAEvent.SHOW_MITM_SOFTWARE_INTERSTITIAL, + UMAEvent.OS_REPORTS_CAPTIVE_PORTAL}) @Retention(RetentionPolicy.SOURCE) - private @interface UMAEvent {} - private static final int HANDLE_ALL = 0; - private static final int SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE = 1; - private static final int SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE = 2; - private static final int SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE = 3; - private static final int SHOW_SSL_INTERSTITIAL_OVERRIDABLE = 4; - private static final int WWW_MISMATCH_FOUND = - 5; // Deprecated in M59 by WWW_MISMATCH_FOUND_IN_SAN. - private static final int WWW_MISMATCH_URL_AVAILABLE = 6; - private static final int WWW_MISMATCH_URL_NOT_AVAILABLE = 7; - private static final int SHOW_BAD_CLOCK = 8; - private static final int CAPTIVE_PORTAL_CERT_FOUND = 9; - private static final int WWW_MISMATCH_FOUND_IN_SAN = 10; - private static final int SHOW_MITM_SOFTWARE_INTERSTITIAL = 11; - private static final int OS_REPORTS_CAPTIVE_PORTAL = 12; + private @interface UMAEvent { + int HANDLE_ALL = 0; + int SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE = 1; + int SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE = 2; + int SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE = 3; + int SHOW_SSL_INTERSTITIAL_OVERRIDABLE = 4; + int WWW_MISMATCH_FOUND = 5; // Deprecated in M59 by WWW_MISMATCH_FOUND_IN_SAN. + int WWW_MISMATCH_URL_AVAILABLE = 6; + int WWW_MISMATCH_URL_NOT_AVAILABLE = 7; + int SHOW_BAD_CLOCK = 8; + int CAPTIVE_PORTAL_CERT_FOUND = 9; + int WWW_MISMATCH_FOUND_IN_SAN = 10; + int SHOW_MITM_SOFTWARE_INTERSTITIAL = 11; + int OS_REPORTS_CAPTIVE_PORTAL = 12; + } @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); @@ -136,16 +137,16 @@ Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", HANDLE_ALL)); + "interstitial.ssl_error_handler", UMAEvent.HANDLE_ALL)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting("interstitial.ssl_error_handler", - SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE)); + UMAEvent.SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", CAPTIVE_PORTAL_CERT_FOUND)); + "interstitial.ssl_error_handler", UMAEvent.CAPTIVE_PORTAL_CERT_FOUND)); Assert.assertEquals(0, RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", OS_REPORTS_CAPTIVE_PORTAL)); + "interstitial.ssl_error_handler", UMAEvent.OS_REPORTS_CAPTIVE_PORTAL)); } @Test @@ -155,16 +156,16 @@ Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", HANDLE_ALL)); + "interstitial.ssl_error_handler", UMAEvent.HANDLE_ALL)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting("interstitial.ssl_error_handler", - SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE)); + UMAEvent.SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE)); Assert.assertEquals(0, RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", CAPTIVE_PORTAL_CERT_FOUND)); + "interstitial.ssl_error_handler", UMAEvent.CAPTIVE_PORTAL_CERT_FOUND)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", OS_REPORTS_CAPTIVE_PORTAL)); + "interstitial.ssl_error_handler", UMAEvent.OS_REPORTS_CAPTIVE_PORTAL)); } /** When CaptivePortalInterstitial feature is disabled, the result of OS captive portal @@ -186,15 +187,15 @@ Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", HANDLE_ALL)); + "interstitial.ssl_error_handler", UMAEvent.HANDLE_ALL)); Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", SHOW_SSL_INTERSTITIAL_OVERRIDABLE)); + RecordHistogram.getHistogramValueCountForTesting("interstitial.ssl_error_handler", + UMAEvent.SHOW_SSL_INTERSTITIAL_OVERRIDABLE)); Assert.assertEquals(0, RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", CAPTIVE_PORTAL_CERT_FOUND)); + "interstitial.ssl_error_handler", UMAEvent.CAPTIVE_PORTAL_CERT_FOUND)); Assert.assertEquals(0, RecordHistogram.getHistogramValueCountForTesting( - "interstitial.ssl_error_handler", OS_REPORTS_CAPTIVE_PORTAL)); + "interstitial.ssl_error_handler", UMAEvent.OS_REPORTS_CAPTIVE_PORTAL)); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/XrTestFramework.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/XrTestFramework.java index 3396f50..0e8d337d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/XrTestFramework.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/XrTestFramework.java
@@ -62,12 +62,13 @@ static final String TEST_DIR = "chrome/test/data/xr/e2e_test_files"; // Test status enum - private static final int STATUS_RUNNING = 0; - private static final int STATUS_PASSED = 1; - private static final int STATUS_FAILED = 2; + @IntDef({TestStatus.RUNNING, TestStatus.PASSED, TestStatus.FAILED}) @Retention(RetentionPolicy.SOURCE) - @IntDef({STATUS_RUNNING, STATUS_PASSED, STATUS_FAILED}) - private @interface TestStatus {} + private @interface TestStatus { + int RUNNING = 0; + int PASSED = 1; + int FAILED = 2; + } private ChromeActivityTestRule mRule; protected WebContents mFirstTabWebContents; @@ -188,8 +189,9 @@ // Check what state we're in to make sure javascriptDone wasn't called because the test // failed. + @TestStatus int testStatus = checkTestStatus(webContents); - if (!success || testStatus == STATUS_FAILED) { + if (!success || testStatus == TestStatus.FAILED) { // Failure states: Either polling failed or polling succeeded, but because the test // failed. String reason; @@ -225,12 +227,12 @@ boolean testPassed = Boolean.parseBoolean( runJavaScriptOrFail("testPassed", POLL_TIMEOUT_SHORT_MS, webContents)); if (testPassed) { - return STATUS_PASSED; + return TestStatus.PASSED; } else if (!testPassed && resultString.equals("\"\"")) { - return STATUS_RUNNING; + return TestStatus.RUNNING; } else { // !testPassed && !resultString.equals("\"\"") - return STATUS_FAILED; + return TestStatus.FAILED; } } @@ -242,14 +244,14 @@ */ public static void endTest(WebContents webContents) { switch (checkTestStatus(webContents)) { - case STATUS_PASSED: + case TestStatus.PASSED: break; - case STATUS_FAILED: + case TestStatus.FAILED: String resultString = runJavaScriptOrFail("resultString", POLL_TIMEOUT_SHORT_MS, webContents); Assert.fail("JavaScript testharness failed with result: " + resultString); break; - case STATUS_RUNNING: + case TestStatus.RUNNING: Assert.fail("Attempted to end test in Java without finishing in JavaScript."); break; default: @@ -267,7 +269,7 @@ * @param webContents The Webcontents for the tab to check for failures in. */ public static void assertNoJavaScriptErrors(WebContents webContents) { - Assert.assertNotEquals(checkTestStatus(webContents), STATUS_FAILED); + Assert.assertNotEquals(checkTestStatus(webContents), TestStatus.FAILED); } /**
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 759eb1e..1ceb8ced 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -183,8 +183,8 @@ <message name="IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_INSTALL_APPS_DESCRIPTION" desc="Tell the user that Better Together can install apps on their Chromebook"> Install apps on your Chromebook </message> - <message name="IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_ADD_FEATURES" desc="Tell the user that Better Together can add new features to that use their phone's connection to their Chromebook"> - Add new features that use your phone's connection to your Chromebook + <message name="IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_ADD_FEATURES" desc="Tell the user that Better Together can offer to add new features to that use their phone's connection to their Chromebook"> + Offer new features that use your phone's connection to your Chromebook </message> <!-- MultiDevice 'Forget device' dialog -->
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 2bc240e..e7efb90 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -3857,6 +3857,12 @@ <message name="IDS_SETTINGS_KEYBOARD_KEY_DISABLED" desc="In Device Settings, the dropdown list item for a disabled key."> Disabled </message> + <message name="IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_COMMAND" desc="In Device Settings, the dropdown list item for the external Command key on Apple keyboards."> + External Command + </message> + <message name="IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_META" desc="In Device Settings, the dropdown list item for the external Meta key (Search key on ChromeOS keyboards, and Windows key on Windows keyboards)."> + External Meta + </message> <message name="IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS" desc="In Device Settings, the checkbox label for interpreting the top-row keys as function keys instead."> Treat top-row keys as function keys </message>
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc index 68a34e79..5a39756 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
@@ -105,19 +105,6 @@ disks::DiskMountManager::GetInstance()->RemoveObserver(this); } -void KioskExternalUpdater::OnAutoMountableDiskEvent( - disks::DiskMountManager::DiskEvent event, - const disks::DiskMountManager::Disk& disk) {} - -void KioskExternalUpdater::OnBootDeviceDiskEvent( - disks::DiskMountManager::DiskEvent event, - const disks::DiskMountManager::Disk& disk) {} - -void KioskExternalUpdater::OnDeviceEvent( - disks::DiskMountManager::DeviceEvent event, - const std::string& device_path) { -} - void KioskExternalUpdater::OnMountEvent( disks::DiskMountManager::MountEvent event, MountError error_code,
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.h b/chrome/browser/chromeos/app_mode/kiosk_external_updater.h index 22c72649..2f7e732 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.h +++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.h
@@ -57,14 +57,6 @@ }; // disks::DiskMountManager::Observer overrides. - void OnAutoMountableDiskEvent( - disks::DiskMountManager::DiskEvent event, - const disks::DiskMountManager::Disk& disk) override; - void OnBootDeviceDiskEvent( - disks::DiskMountManager::DiskEvent event, - const disks::DiskMountManager::Disk& disk) override; - void OnDeviceEvent(disks::DiskMountManager::DeviceEvent event, - const std::string& device_path) override; void OnMountEvent( disks::DiskMountManager::MountEvent event, MountError error_code,
diff --git a/chrome/browser/chromeos/events/event_rewriter_unittest.cc b/chrome/browser/chromeos/events/event_rewriter_unittest.cc index 5288171..a37e246 100644 --- a/chrome/browser/chromeos/events/event_rewriter_unittest.cc +++ b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
@@ -66,10 +66,11 @@ ui::KeyboardCode ui_keycode, ui::DomCode code, int ui_flags, // ui::EventFlags - ui::DomKey key) { + ui::DomKey key, + int device_id = kKeyboardDeviceId) { ui::KeyEvent event(ui_type, ui_keycode, code, ui_flags, key, ui::EventTimeForNow()); - event.set_source_device_id(kKeyboardDeviceId); + event.set_source_device_id(device_id); std::unique_ptr<ui::Event> new_event; rewriter->RewriteEvent(event, &new_event); if (new_event) @@ -86,6 +87,7 @@ int flags; // ui::EventFlags ui::DomKey::Base key; } input, expected; + int device_id = kKeyboardDeviceId; }; std::string GetTestCaseAsString(ui::EventType ui_type, @@ -100,9 +102,10 @@ const KeyTestCase& test) { SCOPED_TRACE("\nSource: " + GetTestCaseAsString(test.type, test.input)); std::string expected = GetTestCaseAsString(test.type, test.expected); - EXPECT_EQ(expected, GetRewrittenEventAsString( - rewriter, test.type, test.input.key_code, - test.input.code, test.input.flags, test.input.key)); + EXPECT_EQ(expected, + GetRewrittenEventAsString(rewriter, test.type, test.input.key_code, + test.input.code, test.input.flags, + test.input.key, test.device_id)); } } // namespace @@ -212,6 +215,10 @@ rewriter_->KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "Apple Keyboard"); rewriter_->set_last_keyboard_device_id_for_testing(kKeyboardDeviceId); + // Simulate the default initialization of the Apple Command key remap pref to + // Ctrl. + chromeos::Preferences::RegisterProfilePrefs(prefs()->registry()); + KeyTestCase apple_keyboard_tests[] = { // VKEY_A, Alt modifier. {ui::ET_KEY_PRESSED, @@ -251,6 +258,226 @@ for (const auto& test : apple_keyboard_tests) CheckKeyTestCase(rewriter_, test); + + // Now simulate the user remapped the Command key back to Search. + IntegerPrefMember command; + InitModifierKeyPref(&command, prefs::kLanguageRemapExternalCommandKeyTo, + ui::chromeos::ModifierKey::kSearchKey); + + KeyTestCase command_remapped_to_search_tests[] = { + // VKEY_A, Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}}, + + // VKEY_A, Alt+Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}}, + + // VKEY_LWIN (left Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_LWIN, ui::DomCode::META_LEFT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_LWIN, ui::DomCode::META_LEFT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}}, + + // VKEY_RWIN (right Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_RWIN, ui::DomCode::META_RIGHT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_LWIN, ui::DomCode::META_RIGHT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}}, + }; + + for (const auto& test : command_remapped_to_search_tests) + CheckKeyTestCase(rewriter_, test); +} + +TEST_F(EventRewriterTest, TestRewriteExternalMetaKey) { + // Simulate the default initialization of the Meta key on external keyboards + // remap pref to Search. + chromeos::Preferences::RegisterProfilePrefs(prefs()->registry()); + + // Add an internal and external keyboards. + rewriter_->KeyboardDeviceAddedForTesting( + kKeyboardDeviceId, "Internal Keyboard", + ui::EventRewriterChromeOS::kKbdTopRowLayoutDefault, + ui::INPUT_DEVICE_INTERNAL); + rewriter_->KeyboardDeviceAddedForTesting( + kKeyboardDeviceId + 1, "External Keyboard", + ui::EventRewriterChromeOS::kKbdTopRowLayoutDefault, + ui::INPUT_DEVICE_EXTERNAL); + + // The Meta key on both external and internal keyboards should produce Search. + + // Test internal keyboard. + rewriter_->set_last_keyboard_device_id_for_testing(kKeyboardDeviceId); + KeyTestCase default_internal_search_tests[] = { + // VKEY_A, Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + kKeyboardDeviceId}, + + // VKEY_A, Alt+Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + kKeyboardDeviceId}, + + // VKEY_LWIN (left Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_LWIN, ui::DomCode::META_LEFT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_LWIN, ui::DomCode::META_LEFT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + kKeyboardDeviceId}, + + // VKEY_RWIN (right Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_RWIN, ui::DomCode::META_RIGHT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_LWIN, ui::DomCode::META_RIGHT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + kKeyboardDeviceId}, + }; + for (const auto& test : default_internal_search_tests) + CheckKeyTestCase(rewriter_, test); + + // Test external Keyboard. + KeyTestCase default_external_meta_tests[] = { + // VKEY_A, Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + kKeyboardDeviceId + 1}, + + // VKEY_A, Alt+Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + kKeyboardDeviceId + 1}, + + // VKEY_LWIN (left Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_LWIN, ui::DomCode::META_LEFT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_LWIN, ui::DomCode::META_LEFT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + kKeyboardDeviceId + 1}, + + // VKEY_RWIN (right Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_RWIN, ui::DomCode::META_RIGHT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_LWIN, ui::DomCode::META_RIGHT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + kKeyboardDeviceId + 1}, + }; + rewriter_->set_last_keyboard_device_id_for_testing(kKeyboardDeviceId + 1); + for (const auto& test : default_external_meta_tests) + CheckKeyTestCase(rewriter_, test); + + // Both preferences for internal Search and external Meta are independent, + // even if one or both are modified. + + // Remap internal Search to Ctrl. + IntegerPrefMember internal_search; + InitModifierKeyPref(&internal_search, prefs::kLanguageRemapSearchKeyTo, + ui::chromeos::ModifierKey::kControlKey); + + // Remap external Search to Alt. + IntegerPrefMember meta; + InitModifierKeyPref(&meta, prefs::kLanguageRemapExternalMetaKeyTo, + ui::chromeos::ModifierKey::kAltKey); + + // Test internal keyboard. + KeyTestCase remapped_internal_search_tests[] = { + // VKEY_A, Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_CONTROL_DOWN, + ui::DomKey::Constant<'a'>::Character}, + kKeyboardDeviceId}, + + // VKEY_A, Alt+Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, + ui::DomKey::Constant<'a'>::Character}, + kKeyboardDeviceId}, + + // VKEY_LWIN (left Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_LWIN, ui::DomCode::META_LEFT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_CONTROL, ui::DomCode::CONTROL_LEFT, + ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, ui::DomKey::CONTROL}, + kKeyboardDeviceId}, + + // VKEY_RWIN (right Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_RWIN, ui::DomCode::META_RIGHT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_CONTROL, ui::DomCode::CONTROL_RIGHT, + ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, ui::DomKey::CONTROL}, + kKeyboardDeviceId}, + }; + rewriter_->set_last_keyboard_device_id_for_testing(kKeyboardDeviceId); + for (const auto& test : remapped_internal_search_tests) + CheckKeyTestCase(rewriter_, test); + + // Test external keyboard. + KeyTestCase remapped_external_search_tests[] = { + // VKEY_A, Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN, + ui::DomKey::Constant<'a'>::Character}, + kKeyboardDeviceId + 1}, + + // VKEY_A, Alt+Win modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, + ui::DomKey::UNIDENTIFIED}, + {ui::VKEY_A, ui::DomCode::US_A, ui::EF_ALT_DOWN, + ui::DomKey::Constant<'a'>::Character}, + kKeyboardDeviceId + 1}, + + // VKEY_LWIN (left Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_LWIN, ui::DomCode::META_LEFT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_MENU, ui::DomCode::ALT_LEFT, ui::EF_ALT_DOWN, ui::DomKey::ALT}, + kKeyboardDeviceId + 1}, + + // VKEY_RWIN (right Windows key), Alt modifier. + {ui::ET_KEY_PRESSED, + {ui::VKEY_RWIN, ui::DomCode::META_RIGHT, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::DomKey::META}, + {ui::VKEY_MENU, ui::DomCode::ALT_RIGHT, ui::EF_ALT_DOWN, + ui::DomKey::ALT}, + kKeyboardDeviceId + 1}, + }; + rewriter_->set_last_keyboard_device_id_for_testing(kKeyboardDeviceId + 1); + for (const auto& test : remapped_external_search_tests) + CheckKeyTestCase(rewriter_, test); } // For crbug.com/133896. @@ -488,6 +715,10 @@ // Tests if the rewriter can handle a Command + Num Pad event. void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() { + // Simulate the default initialization of the Apple Command key remap pref to + // Ctrl. + chromeos::Preferences::RegisterProfilePrefs(prefs()->registry()); + rewriter_->KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "Apple Keyboard"); rewriter_->set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.cc b/chrome/browser/chromeos/file_manager/volume_manager.cc index 1ff1df2..57c3a4d 100644 --- a/chrome/browser/chromeos/file_manager/volume_manager.cc +++ b/chrome/browser/chromeos/file_manager/volume_manager.cc
@@ -688,10 +688,6 @@ NOTREACHED(); } -void VolumeManager::OnBootDeviceDiskEvent( - chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk& disk) {} - void VolumeManager::OnDeviceEvent( chromeos::disks::DiskMountManager::DeviceEvent event, const std::string& device_path) {
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.h b/chrome/browser/chromeos/file_manager/volume_manager.h index 1e126ff..1b1fa08 100644 --- a/chrome/browser/chromeos/file_manager/volume_manager.h +++ b/chrome/browser/chromeos/file_manager/volume_manager.h
@@ -317,9 +317,6 @@ void OnAutoMountableDiskEvent( chromeos::disks::DiskMountManager::DiskEvent event, const chromeos::disks::DiskMountManager::Disk& disk) override; - void OnBootDeviceDiskEvent( - chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk& disk) override; void OnDeviceEvent(chromeos::disks::DiskMountManager::DeviceEvent event, const std::string& device_path) override; void OnMountEvent(chromeos::disks::DiskMountManager::MountEvent event,
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.cc b/chrome/browser/chromeos/login/lock/views_screen_locker.cc index 29b027b..400c1dc 100644 --- a/chrome/browser/chromeos/login/lock/views_screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
@@ -81,10 +81,9 @@ void ViewsScreenLocker::Init() { lock_time_ = base::TimeTicks::Now(); user_selection_screen_->Init(screen_locker_->users()); - LoginScreenClient::Get()->login_screen()->SetUserList( - user_selection_screen_->UpdateAndReturnUserListForMojo()); - LoginScreenClient::Get()->login_screen()->SetAllowLoginAsGuest( - false /*show_guest*/); + LoginScreenClient::Get()->login_screen()->LoadUsers( + user_selection_screen_->UpdateAndReturnUserListForMojo(), + false /* show_guests */); if (!ime_state_.get()) ime_state_ = input_method::InputMethodManager::Get()->GetActiveIMEState();
diff --git a/chrome/browser/chromeos/login/ui/login_display_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_mojo.cc index 7d4249d1..e5097be 100644 --- a/chrome/browser/chromeos/login/ui/login_display_mojo.cc +++ b/chrome/browser/chromeos/login/ui/login_display_mojo.cc
@@ -74,9 +74,8 @@ UserSelectionScreen* user_selection_screen = host_->user_selection_screen(); user_selection_screen->Init(filtered_users); - client->login_screen()->SetUserList( - user_selection_screen->UpdateAndReturnUserListForMojo()); - client->login_screen()->SetAllowLoginAsGuest(show_guest); + client->login_screen()->LoadUsers( + user_selection_screen->UpdateAndReturnUserListForMojo(), show_guest); user_selection_screen->SetUsersLoaded(true /*loaded*/); // Enable pin for any users who can use it.
diff --git a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc index 1f842c4..bc94e4d 100644 --- a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc +++ b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h" #include "ash/public/cpp/shell_window_ids.h" -#include "ash/public/interfaces/login_screen.mojom.h" #include "chrome/browser/chromeos/login/screens/gaia_view.h" #include "chrome/browser/chromeos/login/ui/login_display_host_mojo.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -95,8 +94,7 @@ } void OobeUIDialogDelegate::Show() { - LoginScreenClient::Get()->login_screen()->NotifyOobeDialogState( - ash::mojom::OobeDialogState::GAIA_SIGNIN); + LoginScreenClient::Get()->login_screen()->NotifyOobeDialogVisibility(true); dialog_widget_->Show(); } @@ -113,16 +111,14 @@ void OobeUIDialogDelegate::Hide() { if (!dialog_widget_) return; - LoginScreenClient::Get()->login_screen()->NotifyOobeDialogState( - ash::mojom::OobeDialogState::HIDDEN); + LoginScreenClient::Get()->login_screen()->NotifyOobeDialogVisibility(false); dialog_widget_->Hide(); } void OobeUIDialogDelegate::Close() { if (!dialog_widget_) return; - LoginScreenClient::Get()->login_screen()->NotifyOobeDialogState( - ash::mojom::OobeDialogState::HIDDEN); + LoginScreenClient::Get()->login_screen()->NotifyOobeDialogVisibility(false); dialog_widget_->Close(); }
diff --git a/chrome/browser/chromeos/policy/app_install_event_log_collector.cc b/chrome/browser/chromeos/policy/app_install_event_log_collector.cc index a6fcbe2..7b00403 100644 --- a/chrome/browser/chromeos/policy/app_install_event_log_collector.cc +++ b/chrome/browser/chromeos/policy/app_install_event_log_collector.cc
@@ -65,7 +65,8 @@ pending_packages_(pending_packages) { chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( this); - net::NetworkChangeNotifier::AddNetworkChangeObserver(this); + g_browser_process->network_connection_tracker()->AddNetworkConnectionObserver( + this); // Might not be available in unit test. arc::ArcPolicyBridge* const policy_bridge = arc::ArcPolicyBridge::GetForBrowserContext(profile_); @@ -85,7 +86,8 @@ } chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( this); - net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); + g_browser_process->network_connection_tracker() + ->RemoveNetworkConnectionObserver(this); arc::ArcPolicyBridge* const policy_bridge = arc::ArcPolicyBridge::GetForBrowserContext(profile_); if (policy_bridge) { @@ -133,8 +135,8 @@ CreateSessionChangeEvent(em::AppInstallReportLogEvent::RESUME)); } -void AppInstallEventLogCollector::OnNetworkChanged( - net::NetworkChangeNotifier::ConnectionType type) { +void AppInstallEventLogCollector::OnConnectionChanged( + network::mojom::ConnectionType type) { const bool currently_online = GetOnlineState(); if (currently_online == online_) { return;
diff --git a/chrome/browser/chromeos/policy/app_install_event_log_collector.h b/chrome/browser/chromeos/policy/app_install_event_log_collector.h index 7394f7e..6f7ac761 100644 --- a/chrome/browser/chromeos/policy/app_install_event_log_collector.h +++ b/chrome/browser/chromeos/policy/app_install_event_log_collector.h
@@ -18,7 +18,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chromeos/dbus/power_manager_client.h" #include "components/arc/common/policy.mojom.h" -#include "net/base/network_change_notifier.h" +#include "content/public/browser/network_connection_tracker.h" class Profile; @@ -31,7 +31,7 @@ class AppInstallEventLogCollector : public chromeos::PowerManagerClient::Observer, public arc::ArcPolicyBridge::Observer, - public net::NetworkChangeNotifier::NetworkChangeObserver, + public content::NetworkConnectionTracker::NetworkConnectionObserver, public ArcAppListPrefs::Observer { public: // The delegate that events are forwarded to for inclusion in the log. @@ -76,9 +76,8 @@ void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; void SuspendDone(const base::TimeDelta& sleep_duration) override; - // net::NetworkChangeNotifier::NetworkChangeObserver: - void OnNetworkChanged( - net::NetworkChangeNotifier::ConnectionType type) override; + // content::NetworkConnectionTracker::NetworkConnectionObserver: + void OnConnectionChanged(network::mojom::ConnectionType type) override; // arc::ArcPolicyBridge::Observer: void OnCloudDpsRequested(base::Time time,
diff --git a/chrome/browser/chromeos/policy/app_install_event_log_collector_unittest.cc b/chrome/browser/chromeos/policy/app_install_event_log_collector_unittest.cc index b6b6ed0..21f291f 100644 --- a/chrome/browser/chromeos/policy/app_install_event_log_collector_unittest.cc +++ b/chrome/browser/chromeos/policy/app_install_event_log_collector_unittest.cc
@@ -120,8 +120,6 @@ chromeos::DBusThreadManager::Initialize(); chromeos::NetworkHandler::Initialize(); profile_ = std::make_unique<TestingProfile>(); - network_change_notifier_ = - base::WrapUnique(net::NetworkChangeNotifier::CreateMock()); service_test_ = chromeos::DBusThreadManager::Get() ->GetShillServiceClient() @@ -146,27 +144,29 @@ TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr); } - void SetNetworkState(const std::string& service_path, - const std::string& state) { + void SetNetworkState( + content::NetworkConnectionTracker::NetworkConnectionObserver* observer, + const std::string& service_path, + const std::string& state) { service_test_->SetServiceProperty(service_path, shill::kStateProperty, base::Value(state)); base::RunLoop().RunUntilIdle(); - net::NetworkChangeNotifier::ConnectionType connection_type = - net::NetworkChangeNotifier::CONNECTION_NONE; + network::mojom::ConnectionType connection_type = + network::mojom::ConnectionType::CONNECTION_NONE; std::string network_state; service_test_->GetServiceProperties(kWifiServicePath) ->GetString(shill::kStateProperty, &network_state); if (network_state == shill::kStateOnline) { - connection_type = net::NetworkChangeNotifier::CONNECTION_WIFI; + connection_type = network::mojom::ConnectionType::CONNECTION_WIFI; } service_test_->GetServiceProperties(kEthernetServicePath) ->GetString(shill::kStateProperty, &network_state); if (network_state == shill::kStateOnline) { - connection_type = net::NetworkChangeNotifier::CONNECTION_ETHERNET; + connection_type = network::mojom::ConnectionType::CONNECTION_ETHERNET; } - net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( - connection_type); + if (observer) + observer->OnConnectionChanged(connection_type); base::RunLoop().RunUntilIdle(); } @@ -179,7 +179,6 @@ const std::set<std::string> packages_ = {kPackageName}; - std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; chromeos::ShillServiceClient::TestInterface* service_test_ = nullptr; private: @@ -301,7 +300,7 @@ // to WiFi with a pending captive portal. Verify that no event is recorded. // Then, pass the captive portal. Verify that a connectivity change is recorded. TEST_F(AppInstallEventLogCollectorTest, ConnectivityChanges) { - SetNetworkState(kEthernetServicePath, shill::kStateOnline); + SetNetworkState(nullptr, kEthernetServicePath, shill::kStateOnline); std::unique_ptr<AppInstallEventLogCollector> collector = std::make_unique<AppInstallEventLogCollector>(delegate(), profile(), @@ -317,22 +316,22 @@ delegate()->last_event().session_state_change_type()); EXPECT_TRUE(delegate()->last_event().online()); - SetNetworkState(kWifiServicePath, shill::kStateOnline); + SetNetworkState(collector.get(), kWifiServicePath, shill::kStateOnline); EXPECT_EQ(1, delegate()->add_for_all_count()); - SetNetworkState(kEthernetServicePath, shill::kStateOffline); + SetNetworkState(collector.get(), kEthernetServicePath, shill::kStateOffline); EXPECT_EQ(1, delegate()->add_for_all_count()); - SetNetworkState(kWifiServicePath, shill::kStateOffline); + SetNetworkState(collector.get(), kWifiServicePath, shill::kStateOffline); EXPECT_EQ(2, delegate()->add_for_all_count()); EXPECT_EQ(em::AppInstallReportLogEvent::CONNECTIVITY_CHANGE, delegate()->last_event().event_type()); EXPECT_FALSE(delegate()->last_event().online()); - SetNetworkState(kWifiServicePath, shill::kStatePortal); + SetNetworkState(collector.get(), kWifiServicePath, shill::kStatePortal); EXPECT_EQ(2, delegate()->add_for_all_count()); - SetNetworkState(kWifiServicePath, shill::kStateOnline); + SetNetworkState(collector.get(), kWifiServicePath, shill::kStateOnline); EXPECT_EQ(3, delegate()->add_for_all_count()); EXPECT_EQ(em::AppInstallReportLogEvent::CONNECTIVITY_CHANGE, delegate()->last_event().event_type());
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client_impl.cc b/chrome/browser/chromeos/policy/auto_enrollment_client_impl.cc index 9121532b..3bd6673 100644 --- a/chrome/browser/chromeos/policy/auto_enrollment_client_impl.cc +++ b/chrome/browser/chromeos/policy/auto_enrollment_client_impl.cc
@@ -14,6 +14,7 @@ #include "base/metrics/histogram_macros.h" #include "base/optional.h" #include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/policy/server_backed_device_state.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/pref_names.h" @@ -375,7 +376,8 @@ } AutoEnrollmentClientImpl::~AutoEnrollmentClientImpl() { - net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); + g_browser_process->network_connection_tracker() + ->RemoveNetworkConnectionObserver(this); } // static @@ -386,8 +388,10 @@ void AutoEnrollmentClientImpl::Start() { // (Re-)register the network change observer. - net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); - net::NetworkChangeNotifier::AddNetworkChangeObserver(this); + g_browser_process->network_connection_tracker() + ->RemoveNetworkConnectionObserver(this); + g_browser_process->network_connection_tracker()->AddNetworkConnectionObserver( + this); // Drop the previous job and reset state. request_job_.reset(); @@ -425,9 +429,9 @@ return state_; } -void AutoEnrollmentClientImpl::OnNetworkChanged( - net::NetworkChangeNotifier::ConnectionType type) { - if (type != net::NetworkChangeNotifier::CONNECTION_NONE && +void AutoEnrollmentClientImpl::OnConnectionChanged( + network::mojom::ConnectionType type) { + if (type != network::mojom::ConnectionType::CONNECTION_NONE && !progress_callback_.is_null()) { RetryStep(); }
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client_impl.h b/chrome/browser/chromeos/policy/auto_enrollment_client_impl.h index 56595c0..15742b72 100644 --- a/chrome/browser/chromeos/policy/auto_enrollment_client_impl.h +++ b/chrome/browser/chromeos/policy/auto_enrollment_client_impl.h
@@ -15,7 +15,7 @@ #include "base/time/time.h" #include "chrome/browser/chromeos/policy/auto_enrollment_client.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" -#include "net/base/network_change_notifier.h" +#include "content/public/browser/network_connection_tracker.h" #include "third_party/protobuf/src/google/protobuf/repeated_field.h" class PrefRegistrySimple; @@ -35,7 +35,7 @@ // OOBE. class AutoEnrollmentClientImpl : public AutoEnrollmentClient, - public net::NetworkChangeNotifier::NetworkChangeObserver { + public content::NetworkConnectionTracker::NetworkConnectionObserver { public: // Subclasses of this class provide an identifier and specify the identifier // set for the DeviceAutoEnrollmentRequest, @@ -86,9 +86,8 @@ std::string device_id() const override; AutoEnrollmentState state() const override; - // Implementation of net::NetworkChangeNotifier::NetworkChangeObserver: - void OnNetworkChanged( - net::NetworkChangeNotifier::ConnectionType type) override; + // content::NetworkConnectionTracker::NetworkConnectionObserver: + void OnConnectionChanged(network::mojom::ConnectionType type) override; private: typedef bool (AutoEnrollmentClientImpl::*RequestCompletionHandler)(
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client_impl_unittest.cc b/chrome/browser/chromeos/policy/auto_enrollment_client_impl_unittest.cc index d07e02b..050a8cc 100644 --- a/chrome/browser/chromeos/policy/auto_enrollment_client_impl_unittest.cc +++ b/chrome/browser/chromeos/policy/auto_enrollment_client_impl_unittest.cc
@@ -460,7 +460,8 @@ // Network changes don't trigger retries after obtaining a response from // the server. - client()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET); + client()->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_ETHERNET); EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_); } @@ -479,7 +480,8 @@ // Network changes don't trigger retries after obtaining a response from // the server. - client()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET); + client()->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_ETHERNET); EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_); } @@ -502,7 +504,8 @@ // Network changes don't trigger retries after obtaining a response from // the server. - client()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET); + client()->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_ETHERNET); EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ZERO_TOUCH, state_); } @@ -648,7 +651,8 @@ EXPECT_FALSE(HasServerBackedState()); // The client doesn't retry if no new connection became available. - client()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE); + client()->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_NONE); EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_); EXPECT_FALSE(HasCachedDecision()); EXPECT_FALSE(HasServerBackedState()); @@ -659,7 +663,8 @@ "example.com", em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED, kDisabledMessage); - client()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET); + client()->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_ETHERNET); EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_); EXPECT_TRUE(HasCachedDecision()); VerifyServerBackedState("example.com", @@ -667,8 +672,10 @@ kDisabledMessage); // Subsequent network changes don't trigger retries. - client()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE); - client()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET); + client()->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_NONE); + client()->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_ETHERNET); EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_); EXPECT_TRUE(HasCachedDecision()); VerifyServerBackedState("example.com", @@ -712,7 +719,8 @@ EXPECT_TRUE(base::MessageLoopCurrent::Get()->IsIdleForTesting()); // Network change events are ignored while a request is pending. - client->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET); + client->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_ETHERNET); EXPECT_EQ(AUTO_ENROLLMENT_STATE_PENDING, state_); // The client cleans itself up once a reply is received. @@ -723,7 +731,8 @@ EXPECT_EQ(AUTO_ENROLLMENT_STATE_PENDING, state_); // Network changes that have been posted before are also ignored: - client->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET); + client->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_ETHERNET); EXPECT_EQ(AUTO_ENROLLMENT_STATE_PENDING, state_); } @@ -786,7 +795,8 @@ EXPECT_CALL(*service_, StartJob(_, _, _, _, _, _)); // Trigger a network change event. - client()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET); + client()->OnConnectionChanged( + network::mojom::ConnectionType::CONNECTION_ETHERNET); EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_); EXPECT_TRUE(HasCachedDecision()); VerifyServerBackedState("example.com",
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index a13c2ac..540f8f61 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc
@@ -75,10 +75,15 @@ // preferences will be saved in global user preferences dictionary so that they // can be used on signin screen. const char* const kLanguageRemapPrefs[] = { - prefs::kLanguageRemapSearchKeyTo, prefs::kLanguageRemapControlKeyTo, - prefs::kLanguageRemapAltKeyTo, prefs::kLanguageRemapCapsLockKeyTo, - prefs::kLanguageRemapEscapeKeyTo, prefs::kLanguageRemapBackspaceKeyTo, - prefs::kLanguageRemapDiamondKeyTo}; + prefs::kLanguageRemapSearchKeyTo, + prefs::kLanguageRemapControlKeyTo, + prefs::kLanguageRemapAltKeyTo, + prefs::kLanguageRemapCapsLockKeyTo, + prefs::kLanguageRemapEscapeKeyTo, + prefs::kLanguageRemapBackspaceKeyTo, + prefs::kLanguageRemapDiamondKeyTo, + prefs::kLanguageRemapExternalCommandKeyTo, + prefs::kLanguageRemapExternalMetaKeyTo}; // Migrates kResolveTimezoneByGeolocation value to // kResolveTimezoneByGeolocationMethod. @@ -352,6 +357,18 @@ prefs::kLanguageRemapDiamondKeyTo, static_cast<int>(ui::chromeos::ModifierKey::kControlKey), user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); + // The Command key on external Apple keyboards is remapped by default to Ctrl + // until the user changes it from the keyboard settings. + registry->RegisterIntegerPref( + prefs::kLanguageRemapExternalCommandKeyTo, + static_cast<int>(ui::chromeos::ModifierKey::kControlKey), + user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); + // The Meta key (Search or Windows keys) on external keyboards is remapped by + // default to Search until the user changes it from the keyboard settings. + registry->RegisterIntegerPref( + prefs::kLanguageRemapExternalMetaKeyTo, + static_cast<int>(ui::chromeos::ModifierKey::kSearchKey), + user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); // The following pref isn't synced since the user may desire a different value // depending on whether an external keyboard is attached to a particular // device.
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index a879491..509dce2 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -462,6 +462,10 @@ settings_api::PrefType::PREF_TYPE_NUMBER; (*s_whitelist)[::prefs::kLanguageRemapDiamondKeyTo] = settings_api::PrefType::PREF_TYPE_NUMBER; + (*s_whitelist)[::prefs::kLanguageRemapExternalCommandKeyTo] = + settings_api::PrefType::PREF_TYPE_NUMBER; + (*s_whitelist)[::prefs::kLanguageRemapExternalMetaKeyTo] = + settings_api::PrefType::PREF_TYPE_NUMBER; (*s_whitelist)[::prefs::kLanguageSendFunctionKeys] = settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[::prefs::kLanguageXkbAutoRepeatEnabled] = @@ -472,8 +476,10 @@ settings_api::PrefType::PREF_TYPE_NUMBER; // Multidevice settings. + (*s_whitelist)[chromeos::multidevice_setup::kSuiteEnabledPrefName] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist) - [chromeos::multidevice_setup::kMultiDeviceSuiteEnabledPrefName] = + [chromeos::multidevice_setup::kAndroidMessagesFeatureEnabledPrefName] = settings_api::PrefType::PREF_TYPE_BOOLEAN; // Native Printing settings.
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc index 38fcd9a..45bae3a8 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
@@ -306,7 +306,14 @@ ASSERT_TRUE(RunExtensionTest("webnavigation/simpleLoad")) << message_; } -IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Failures) { +// Flaky on Windows, Mac and Linux. See http://crbug.com/477480 (Windows) and +// https://crbug.com/746407 (Mac, Linux). +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) +#define MAYBE_Failures DISABLED_Failures +#else +#define MAYBE_Failures Failures +#endif +IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_Failures) { ASSERT_TRUE(RunExtensionTest("webnavigation/failures")) << message_; }
diff --git a/chrome/browser/media/DEPS b/chrome/browser/media/DEPS index 6c2e8e0..4ba0b3c8 100644 --- a/chrome/browser/media/DEPS +++ b/chrome/browser/media/DEPS
@@ -11,3 +11,9 @@ "+services/data_decoder/public", "+services/device/public/mojom", ] + +specific_include_rules = { + "cast_remoting_connector\.cc": [ + "+chrome/browser/ui/views/media_router/media_remoting_dialog_view.h", + ], +}
diff --git a/chrome/browser/media/cast_remoting_connector.cc b/chrome/browser/media/cast_remoting_connector.cc index 70b6cb7..3682fdf0 100644 --- a/chrome/browser/media/cast_remoting_connector.cc +++ b/chrome/browser/media/cast_remoting_connector.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/media/cast_remoting_connector.h" #include <memory> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h" @@ -24,6 +25,11 @@ #include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/strong_binding.h" +#if defined(TOOLKIT_VIEWS) && \ + (!defined(OS_MACOSX) || defined(MAC_VIEWS_BROWSER)) +#include "chrome/browser/ui/views/media_router/media_remoting_dialog_view.h" +#endif + using content::BrowserThread; using media::mojom::RemotingStartFailReason; using media::mojom::RemotingStopReason; @@ -92,7 +98,7 @@ } void Stop(RemotingStopReason reason) final { if (connector_) - connector_->StopRemoting(this, reason); + connector_->StopRemoting(this, reason, true); } void SendMessageToSink(const std::vector<uint8_t>& message) final { if (connector_) @@ -137,7 +143,30 @@ connector = new CastRemotingConnector( media_router::MediaRouterFactory::GetApiForBrowserContext( contents->GetBrowserContext()), - tab_id); + tab_id, +#if defined(TOOLKIT_VIEWS) && \ + (!defined(OS_MACOSX) || defined(MAC_VIEWS_BROWSER)) + base::BindRepeating( + [](content::WebContents* contents, + PermissionResultCallback result_callback) { + if (media_router::ShouldUseViewsDialog()) { + media_router::MediaRemotingDialogView::GetPermission( + contents, std::move(result_callback)); + return base::BindOnce( + &media_router::MediaRemotingDialogView::HideDialog); + } else { + std::move(result_callback).Run(true); + return CancelPermissionRequestCallback(); + } + }, + contents) +#else + base::BindRepeating([](PermissionResultCallback result_callback) { + std::move(result_callback).Run(true); + return CancelPermissionRequestCallback(); + }) +#endif + ); contents->SetUserData(kUserDataKey, base::WrapUnique(connector)); } return connector; @@ -158,14 +187,18 @@ connector->CreateBridge(std::move(source), std::move(request)); } -CastRemotingConnector::CastRemotingConnector(media_router::MediaRouter* router, - SessionID tab_id) +CastRemotingConnector::CastRemotingConnector( + media_router::MediaRouter* router, + SessionID tab_id, + PermissionRequestCallback permission_request_callback) : media_router_(router), tab_id_(tab_id), + permission_request_callback_(std::move(permission_request_callback)), active_bridge_(nullptr), binding_(this), weak_factory_(this) { VLOG(2) << "Register CastRemotingConnector for tab_id = " << tab_id_; + DCHECK(permission_request_callback_); media_router_->RegisterRemotingSource(tab_id_, this); } @@ -174,7 +207,7 @@ // it's possible the owning WebContents will be destroyed before the Mojo // message pipes to the RemotingBridges have been closed. if (active_bridge_) - StopRemoting(active_bridge_, RemotingStopReason::ROUTE_TERMINATED); + StopRemoting(active_bridge_, RemotingStopReason::ROUTE_TERMINATED, false); for (RemotingBridge* notifyee : bridges_) { notifyee->OnSinkGone(); notifyee->OnCastRemotingConnectorDestroyed(); @@ -213,7 +246,7 @@ sink_metadata_ = RemotingSinkMetadata(); if (active_bridge_) - StopRemoting(active_bridge_, RemotingStopReason::SERVICE_GONE); + StopRemoting(active_bridge_, RemotingStopReason::SERVICE_GONE, false); for (RemotingBridge* notifyee : bridges_) notifyee->OnSinkGone(); } @@ -239,9 +272,9 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(bridges_.find(bridge) != bridges_.end()); - if (bridge == active_bridge_) - StopRemoting(bridge, reason); bridges_.erase(bridge); + if (bridge == active_bridge_) + StopRemoting(bridge, reason, true); } void CastRemotingConnector::StartRemoting(RemotingBridge* bridge) { @@ -282,14 +315,15 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!connector) return; + connector->permission_request_cancel_callback_.Reset(); connector->remoting_allowed_ = is_allowed; connector->StartRemotingIfPermitted(); }, weak_factory_.GetWeakPtr())); - // TODO(http://crbug.com/849020): Show the remoting dialog to get user's - // permission. - std::move(dialog_result_callback).Run(true); + DCHECK(!permission_request_cancel_callback_); + permission_request_cancel_callback_ = + permission_request_callback_.Run(std::move(dialog_result_callback)); } } @@ -331,7 +365,7 @@ if ((!audio_pipe.is_valid() && !video_pipe.is_valid()) || (audio_pipe.is_valid() && !audio_sender_request.is_pending()) || (video_pipe.is_valid() && !video_sender_request.is_pending())) { - StopRemoting(active_bridge_, RemotingStopReason::DATA_SEND_FAILED); + StopRemoting(active_bridge_, RemotingStopReason::DATA_SEND_FAILED, false); return; } @@ -377,7 +411,8 @@ } void CastRemotingConnector::StopRemoting(RemotingBridge* bridge, - RemotingStopReason reason) { + RemotingStopReason reason, + bool is_initiated_by_source) { DCHECK_CURRENTLY_ON(BrowserThread::UI); VLOG(2) << __func__ << ": reason = " << reason; @@ -389,6 +424,19 @@ // Cancel all outstanding callbacks related to the remoting session. weak_factory_.InvalidateWeakPtrs(); + if (permission_request_cancel_callback_) { + std::move(permission_request_cancel_callback_).Run(); + if (is_initiated_by_source && remoter_) { + // The source requested remoting be stopped before the permission request + // was resolved. This means the |remoter_| was never started, and remains + // in the available state, still all ready to go. Thus, notify the sources + // that the sink is available once again. + for (RemotingBridge* notifyee : bridges_) + notifyee->OnSinkAvailable(sink_metadata_); + } + return; // Early returns since the |remoter_| was never started. + } + // Reset |sink_metadata_|. Remoting can only be started after // OnSinkAvailable() is called again. sink_metadata_ = RemotingSinkMetadata(); @@ -411,7 +459,7 @@ if (active_bridge_) { // This call will reset |sink_metadata_| and notify the source that sink is // gone. - StopRemoting(active_bridge_, reason); + StopRemoting(active_bridge_, reason, false); } else if (reason == RemotingStopReason::USER_DISABLED) { // Notify all the sources that the sink is gone. Remoting can only be // started after OnSinkAvailable() is called again. @@ -480,7 +528,7 @@ VLOG(2) << __func__; if (active_bridge_) - StopRemoting(active_bridge_, RemotingStopReason::UNEXPECTED_FAILURE); + StopRemoting(active_bridge_, RemotingStopReason::UNEXPECTED_FAILURE, false); } void CastRemotingConnector::OnDataSendFailed() { @@ -490,5 +538,5 @@ // A single data send failure is treated as fatal to an active remoting // session. if (active_bridge_) - StopRemoting(active_bridge_, RemotingStopReason::DATA_SEND_FAILED); + StopRemoting(active_bridge_, RemotingStopReason::DATA_SEND_FAILED, false); }
diff --git a/chrome/browser/media/cast_remoting_connector.h b/chrome/browser/media/cast_remoting_connector.h index 397c2be..1878779 100644 --- a/chrome/browser/media/cast_remoting_connector.h +++ b/chrome/browser/media/cast_remoting_connector.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_MEDIA_CAST_REMOTING_CONNECTOR_H_ #include <set> +#include <vector> #include "base/memory/weak_ptr.h" #include "base/optional.h" @@ -112,7 +113,15 @@ // Main constructor. |tab_id| refers to any remoted content managed // by this instance (i.e., any remoted content from one tab/WebContents). - CastRemotingConnector(media_router::MediaRouter* router, SessionID tab_id); + using CancelPermissionRequestCallback = base::OnceClosure; + // Called with true to mean "allowed", false to mean "not allowed". + using PermissionResultCallback = base::OnceCallback<void(bool)>; + using PermissionRequestCallback = + base::RepeatingCallback<CancelPermissionRequestCallback( + PermissionResultCallback)>; + CastRemotingConnector(media_router::MediaRouter* router, + SessionID tab_id, + PermissionRequestCallback request_callback); // Creates a RemotingBridge that implements the requested Remoter service, and // binds it to the interface |request|. @@ -144,7 +153,8 @@ media::mojom::RemotingDataStreamSenderRequest audio_sender_request, media::mojom::RemotingDataStreamSenderRequest video_sender_request); void StopRemoting(RemotingBridge* bridge, - media::mojom::RemotingStopReason reason); + media::mojom::RemotingStopReason reason, + bool is_initiated_by_source); void SendMessageToSink(RemotingBridge* bridge, const std::vector<uint8_t>& message); void EstimateTransmissionCapacity( @@ -174,6 +184,9 @@ const SessionID tab_id_; + // The callback to get permission. + const PermissionRequestCallback permission_request_callback_; + // Describes the remoting sink's metadata and its enabled features. The sink's // metadata is updated by the mirror service calling OnSinkAvailable() and // cleared when remoting stops. @@ -195,6 +208,10 @@ // casting session. base::Optional<bool> remoting_allowed_; + // This callback is non-null when a dialog is showing to get user's + // permission, and is reset when the dialog closes. + CancelPermissionRequestCallback permission_request_cancel_callback_; + // Produces weak pointers that are only valid for the current remoting // session. This is used to cancel any outstanding callbacks when a remoting // session is stopped.
diff --git a/chrome/browser/media/cast_remoting_connector_unittest.cc b/chrome/browser/media/cast_remoting_connector_unittest.cc index 2e15e81..b129cc2 100644 --- a/chrome/browser/media/cast_remoting_connector_unittest.cc +++ b/chrome/browser/media/cast_remoting_connector_unittest.cc
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/run_loop.h" +#include "build/build_config.h" #include "chrome/browser/media/router/test/mock_media_router.h" #include "chrome/common/media_router/media_route.h" #include "chrome/common/media_router/media_source.h" @@ -164,9 +165,7 @@ class CastRemotingConnectorTest : public ::testing::Test { public: - CastRemotingConnectorTest() : connector_(&media_router_, kRemotingTabId) { - EXPECT_EQ(kRemotingTabId, media_router_.tab_id()); - } + CastRemotingConnectorTest() { CreateConnector(true); } void TearDown() final { // Allow any pending Mojo operations to complete before destruction. For @@ -180,8 +179,8 @@ RemotingSourcePtr source_ptr; source->Bind(mojo::MakeRequest(&source_ptr)); RemoterPtr remoter_ptr; - connector_.CreateBridge(std::move(source_ptr), - mojo::MakeRequest(&remoter_ptr)); + connector_->CreateBridge(std::move(source_ptr), + mojo::MakeRequest(&remoter_ptr)); return remoter_ptr; } @@ -190,14 +189,29 @@ } void DisableRemoting() { - connector_.OnStopped(RemotingStopReason::USER_DISABLED); + connector_->OnStopped(RemotingStopReason::USER_DISABLED); + } + + void CreateConnector(bool remoting_allowed) { + connector_.reset(); // Call dtor first if there is one created. + connector_.reset(new CastRemotingConnector( + &media_router_, kRemotingTabId, + base::BindRepeating( + [](bool remoting_allowed, + CastRemotingConnector::PermissionResultCallback + result_callback) { + std::move(result_callback).Run(remoting_allowed); + return CastRemotingConnector::CancelPermissionRequestCallback(); + }, + remoting_allowed))); + EXPECT_EQ(kRemotingTabId, media_router_.tab_id()); } FakeMediaRouter media_router_; private: content::TestBrowserThreadBundle browser_thread_bundle_; - CastRemotingConnector connector_; + std::unique_ptr<CastRemotingConnector> connector_; }; TEST_F(CastRemotingConnectorTest, NeverNotifiesThatSinkIsAvailable) { @@ -309,6 +323,20 @@ RunUntilIdle(); } +TEST_F(CastRemotingConnectorTest, NoPermissionToStart) { + CreateConnector(false); + MockRemotingSource source; + RemoterPtr remoter = CreateRemoter(&source); + std::unique_ptr<MockMediaRemoter> media_remoter = + std::make_unique<MockMediaRemoter>(&media_router_); + + EXPECT_CALL(source, OnStartFailed(RemotingStartFailReason::ROUTE_TERMINATED)) + .Times(1); + EXPECT_CALL(source, OnSinkGone()).Times(AtLeast(1)); + remoter->Start(); + RunUntilIdle(); +} + namespace { // The possible ways a remoting session may be terminated in the "full
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc index a3fa181..54aeb86 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -185,6 +185,16 @@ return "cast:" + dial_sink_id.substr(5); } +// static +MediaSink::Id CastMediaSinkServiceImpl::GetDialSinkIdFromCast( + const MediaSink::Id& cast_sink_id) { + DCHECK_EQ("cast:", cast_sink_id.substr(0, 5)) + << "unexpected Cast sink id " << cast_sink_id; + + // Replace the "cast:" prefix with "dial:". + return "dial:" + cast_sink_id.substr(5); +} + CastMediaSinkServiceImpl::CastMediaSinkServiceImpl( const OnSinksDiscoveredCallback& callback, cast_channel::CastSocketService* cast_socket_service, @@ -632,6 +642,13 @@ if (old_sink_it != sinks.end()) RemoveSink(old_sink_it->second); + + // Certain classes of Cast sinks support advertising via SSDP but do not + // properly implement the rest of the DIAL protocol. If we successfully open + // a Cast channel to a device that came from DIAL, remove it from + // |dial_media_sink_service_|. This ensures the device shows up as a Cast sink + // only. + dial_media_sink_service_->RemoveSinkById(GetDialSinkIdFromCast(sink_id)); } void CastMediaSinkServiceImpl::OnChannelOpenFailed( @@ -674,6 +691,9 @@ DVLOG(2) << "Sink discovered by mDNS, skip adding [name]: " << sink.sink().name(); metrics_.RecordCastSinkDiscoverySource(SinkSource::kMdnsDial); + // Sink is a Cast device; remove from |dial_media_sink_service_| to prevent + // duplicates. + dial_media_sink_service_->RemoveSink(dial_sink); return; }
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h index 905161e..67c100d7 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
@@ -44,8 +44,9 @@ // before we can say confidently that it is unlikely to be a Cast device. static constexpr int kMaxDialSinkFailureCount = 10; - // Returns a Cast MediaSink ID from a DIAL MediaSink ID |dial_sink_id|. + // Returns a Cast MediaSink ID from a DIAL MediaSink ID, and vice versa. static MediaSink::Id GetCastSinkIdFromDial(const MediaSink::Id& dial_sink_id); + static MediaSink::Id GetDialSinkIdFromCast(const MediaSink::Id& cast_sink_id); // |callback|: Callback passed to MediaSinkServiceBase. // |observer|: Observer to invoke on sink updates. Can be nullptr.
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc index 3a9aa68..d0fecea 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -587,11 +587,6 @@ EXPECT_CALL(socket, ready_state()) .WillOnce(Return(cast_channel::ReadyState::CLOSED)); - // There is no existing cast sink. - /* XXX - media_sink_service_impl_.pending_for_open_ip_endpoints_.clear(); - media_sink_service_impl_.current_sinks_.clear(); - */ media_sink_service_impl_.OnError( socket, cast_channel::ChannelError::CHANNEL_NOT_OPEN); @@ -602,6 +597,10 @@ } TEST_F(CastMediaSinkServiceImplTest, TestOnSinkAddedOrUpdated) { + // Make sure |media_sink_service_impl_| adds itself as an observer to + // |dial_media_sink_service_|. + media_sink_service_impl_.Start(); + MediaSinkInternal dial_sink1 = CreateDialSink(1); MediaSinkInternal dial_sink2 = CreateDialSink(2); net::IPEndPoint ip_endpoint1(dial_sink1.dial_data().ip_address, @@ -618,22 +617,22 @@ // Channel 1, 2 opened. EXPECT_CALL(*mock_cast_socket_service_, OpenSocketInternal(ip_endpoint1, _, _)) - .WillOnce(WithArgs<2>(Invoke( - [&](const base::Callback<void(cast_channel::CastSocket * socket)>& - callback) { std::move(callback).Run(&socket1); }))); + .WillOnce(WithArgs<2>( + [&socket1]( + const base::Callback<void(cast_channel::CastSocket * socket)>& + callback) { callback.Run(&socket1); })); EXPECT_CALL(*mock_cast_socket_service_, OpenSocketInternal(ip_endpoint2, _, _)) - .WillOnce(WithArgs<2>(Invoke( - [&](const base::Callback<void(cast_channel::CastSocket * socket)>& - callback) { std::move(callback).Run(&socket2); }))); + .WillOnce(WithArgs<2>( + [&socket2]( + const base::Callback<void(cast_channel::CastSocket * socket)>& + callback) { callback.Run(&socket2); })); - // Invoke CastSocketService::OpenSocket on the IO thread. - media_sink_service_impl_.OnSinkAddedOrUpdated(dial_sink1); - base::RunLoop().RunUntilIdle(); - - // Invoke CastSocketService::OpenSocket on the IO thread. - media_sink_service_impl_.OnSinkAddedOrUpdated(dial_sink2); - base::RunLoop().RunUntilIdle(); + // Add DIAL sinks to |dial_media_sink_service_|, which in turn notifies + // |media_sink_service_impl_| via the Observer interface. + dial_media_sink_service_.AddOrUpdateSink(dial_sink1); + dial_media_sink_service_.AddOrUpdateSink(dial_sink2); + EXPECT_TRUE(dial_media_sink_service_.timer()->IsRunning()); // Verify sink content. const auto& sinks = media_sink_service_impl_.GetSinks(); @@ -648,6 +647,9 @@ CastMediaSinkServiceImpl::GetCastSinkIdFromDial(dial_sink2.sink().id())); ASSERT_TRUE(sink); EXPECT_EQ(SinkIconType::CAST_AUDIO, sink->sink().icon_type()); + + // The sinks are removed from |dial_media_sink_service_|. + EXPECT_TRUE(dial_media_sink_service_.GetSinks().empty()); } TEST_F(CastMediaSinkServiceImplTest,
diff --git a/chrome/browser/navigation_predictor/navigation_predictor.cc b/chrome/browser/navigation_predictor/navigation_predictor.cc index e654b62..28fc4a1 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor.cc
@@ -4,10 +4,9 @@ #include "chrome/browser/navigation_predictor/navigation_predictor.h" -#include <unordered_map> - #include "base/logging.h" #include "base/metrics/histogram_macros.h" +#include "base/optional.h" #include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/render_frame_host.h" @@ -16,24 +15,22 @@ #include "mojo/public/cpp/bindings/strong_binding.h" #include "url/gurl.h" -struct NavigationPredictor::MetricsFromBrowser { - MetricsFromBrowser(const GURL& source_url, - const GURL& target_url, - const SiteEngagementService* engagement_service) - : source_engagement_score(engagement_service->GetScore(source_url)), - target_engagement_score(engagement_service->GetScore(target_url)) { - DCHECK(source_engagement_score >= 0 && - source_engagement_score <= engagement_service->GetMaxPoints()); - DCHECK(target_engagement_score >= 0 && - target_engagement_score <= engagement_service->GetMaxPoints()); - } +struct NavigationPredictor::NavigationScore { + NavigationScore(const GURL& url, size_t area_rank, double score) + : url(url), area_rank(area_rank), score(score) {} + // URL of the target link. + const GURL url; - // The site engagement score of the url of the root document, and the target - // url (href) of the anchor element. The scores are retrieved from the site - // engagement service. The range of the scores are between 0 and - // SiteEngagementScore::kMaxPoints (both inclusive). - const double source_engagement_score; - const double target_engagement_score; + // Rank in terms of anchor element area. It starts at 0, a lower rank implies + // a larger area. + const size_t area_rank; + + // Calculated navigation score, based on |area_rank| and other metrics. + const double score; + + // Rank of the |score| in this document. It starts at 0, a lower rank implies + // a higher |score|. + base::Optional<size_t> score_rank; }; NavigationPredictor::NavigationPredictor( @@ -87,15 +84,14 @@ SiteEngagementService* NavigationPredictor::GetEngagementService() const { Profile* profile = Profile::FromBrowserContext(browser_context_); - return SiteEngagementService::Get(profile); + SiteEngagementService* service = SiteEngagementService::Get(profile); + DCHECK(service); + return service; } void NavigationPredictor::ReportAnchorElementMetricsOnClick( blink::mojom::AnchorElementMetricsPtr metrics) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // TODO(chelu): https://crbug.com/850624/. Use |metrics| to aggregate metrics - // extracted from the browser process. Analyze and use them to take some - // actions accordingly. if (!IsValidMetricFromRenderer(*metrics)) { mojo::ReportBadMessage("Bad anchor element metrics: onClick."); return; @@ -104,22 +100,81 @@ RecordTimingOnClick(); SiteEngagementService* engagement_service = GetEngagementService(); - DCHECK(engagement_service); + + UMA_HISTOGRAM_COUNTS_100( + "AnchorElementMetrics.Clicked.DocumentEngagementScore", + static_cast<int>(engagement_service->GetScore(metrics->source_url))); double target_score = engagement_service->GetScore(metrics->target_url); - UMA_HISTOGRAM_COUNTS_100("AnchorElementMetrics.Clicked.HrefEngagementScore2", static_cast<int>(target_score)); - if (target_score > 0) { UMA_HISTOGRAM_COUNTS_100( "AnchorElementMetrics.Clicked.HrefEngagementScorePositive", static_cast<int>(target_score)); } + + // Look up the clicked URL in |navigation_scores_map_|. Record if we find it. + auto iter = navigation_scores_map_.find(metrics->target_url.spec()); + if (iter == navigation_scores_map_.end()) + return; + + UMA_HISTOGRAM_COUNTS_100("AnchorElementMetrics.Clicked.AreaRank", + static_cast<int>(iter->second->area_rank)); + UMA_HISTOGRAM_COUNTS_100("AnchorElementMetrics.Clicked.NavigationScore", + static_cast<int>(iter->second->score)); + UMA_HISTOGRAM_COUNTS_100("AnchorElementMetrics.Clicked.NavigationScoreRank", + static_cast<int>(iter->second->score_rank.value())); + + // Guaranteed to be non-zero since we have found the clicked link in + // |navigation_scores_map_|. + int number_of_anchors = static_cast<int>(navigation_scores_map_.size()); + if (metrics->is_same_host) { + UMA_HISTOGRAM_PERCENTAGE( + "AnchorElementMetrics.Clicked.RatioSameHost_SameHost", + (number_of_anchors_same_host_ * 100) / number_of_anchors); + } else { + UMA_HISTOGRAM_PERCENTAGE( + "AnchorElementMetrics.Clicked.RatioSameHost_DiffHost", + (number_of_anchors_same_host_ * 100) / number_of_anchors); + } + + if (metrics->contains_image) { + UMA_HISTOGRAM_PERCENTAGE( + "AnchorElementMetrics.Clicked.RatioContainsImage_ContainsImage", + (number_of_anchors_contains_image_ * 100) / number_of_anchors); + } else { + UMA_HISTOGRAM_PERCENTAGE( + "AnchorElementMetrics.Clicked.RatioContainsImage_NoImage", + (number_of_anchors_contains_image_ * 100) / number_of_anchors); + } + + if (metrics->is_in_iframe) { + UMA_HISTOGRAM_PERCENTAGE( + "AnchorElementMetrics.Clicked.RatioInIframe_InIframe", + (number_of_anchors_in_iframe_ * 100) / number_of_anchors); + } else { + UMA_HISTOGRAM_PERCENTAGE( + "AnchorElementMetrics.Clicked.RatioInIframe_NotInIframe", + (number_of_anchors_in_iframe_ * 100) / number_of_anchors); + } + + if (metrics->is_url_incremented_by_one) { + UMA_HISTOGRAM_PERCENTAGE( + "AnchorElementMetrics.Clicked.RatioUrlIncremented_UrlIncremented", + (number_of_anchors_url_incremented_ * 100) / number_of_anchors); + } else { + UMA_HISTOGRAM_PERCENTAGE( + "AnchorElementMetrics.Clicked.RatioUrlIncremented_NotIncremented", + (number_of_anchors_url_incremented_ * 100) / number_of_anchors); + } } void NavigationPredictor::MergeMetricsSameTargetUrl( std::vector<blink::mojom::AnchorElementMetricsPtr>* metrics) const { + UMA_HISTOGRAM_COUNTS_100( + "AnchorElementMetrics.Visible.NumberOfAnchorElements", metrics->size()); + // Maps from target url (href) to anchor element metrics from renderer. std::unordered_map<std::string, blink::mojom::AnchorElementMetricsPtr> metrics_map; @@ -169,67 +224,124 @@ } DCHECK(!metrics->empty()); + UMA_HISTOGRAM_COUNTS_100( + "AnchorElementMetrics.Visible.NumberOfAnchorElementsAfterMerge", + metrics->size()); } void NavigationPredictor::ReportAnchorElementMetricsOnLoad( std::vector<blink::mojom::AnchorElementMetricsPtr> metrics) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Each document should only report metrics once when page is loaded. + DCHECK(navigation_scores_map_.empty()); + if (metrics.empty()) { mojo::ReportBadMessage("Bad anchor element metrics: empty."); return; } - document_loaded_timing_ = base::TimeTicks::Now(); - - UMA_HISTOGRAM_COUNTS_100( - "AnchorElementMetrics.Visible.NumberOfAnchorElements", metrics.size()); - - MergeMetricsSameTargetUrl(&metrics); - - SiteEngagementService* engagement_service = GetEngagementService(); - DCHECK(engagement_service); - - std::vector<double> scores; for (const auto& metric : metrics) { if (!IsValidMetricFromRenderer(*metric)) { mojo::ReportBadMessage("Bad anchor element metrics: onLoad."); return; } - - RecordMetricsOnLoad(*metric); - - MetricsFromBrowser metrics_browser(metric->source_url, metric->target_url, - engagement_service); - double score = GetAnchorElementScore(*metric, metrics_browser); - scores.push_back(score); } - MaybeTakeActionOnLoad(scores); + document_loaded_timing_ = base::TimeTicks::Now(); + + MergeMetricsSameTargetUrl(&metrics); + + // Count the number of anchors that have specific metrics. + for (const auto& metric : metrics) { + number_of_anchors_same_host_ += static_cast<int>(metric->is_same_host); + number_of_anchors_contains_image_ += + static_cast<int>(metric->contains_image); + number_of_anchors_in_iframe_ += static_cast<int>(metric->is_in_iframe); + number_of_anchors_url_incremented_ += + static_cast<int>(metric->is_url_incremented_by_one); + } + + // Retrive site engagement score of the docuemnt. |metrics| is guaranteed to + // be non-empty. All |metrics| have the same source_url. + SiteEngagementService* engagement_service = GetEngagementService(); + double document_engagement_score = + engagement_service->GetScore(metrics[0]->source_url); + DCHECK(document_engagement_score >= 0 && + document_engagement_score <= engagement_service->GetMaxPoints()); + UMA_HISTOGRAM_COUNTS_100( + "AnchorElementMetrics.Visible.DocumentEngagementScore", + static_cast<int>(document_engagement_score)); + + // Sort metric by area in descending order to get area rank, which is a + // derived feature to calculate navigation score. + std::sort(metrics.begin(), metrics.end(), [](const auto& a, const auto& b) { + return a->ratio_area > b->ratio_area; + }); + + // Loop |metrics| to compute navigation scores. + std::vector<std::unique_ptr<NavigationScore>> navigation_scores; + navigation_scores.reserve(metrics.size()); + for (size_t i = 0; i != metrics.size(); ++i) { + const auto& metric = metrics[i]; + RecordMetricsOnLoad(*metric); + + const double target_engagement_score = + engagement_service->GetScore(metric->target_url); + DCHECK(target_engagement_score >= 0 && + target_engagement_score <= engagement_service->GetMaxPoints()); + + // Anchor elements with the same area are assigned with the same rank. + size_t area_rank = i; + if (i > 0 && metric->ratio_area == metrics[i - 1]->ratio_area) + area_rank = navigation_scores[navigation_scores.size() - 1]->area_rank; + + double score = CalculateAnchorNavigationScore( + *metric, document_engagement_score, target_engagement_score, area_rank); + + navigation_scores.push_back(std::make_unique<NavigationScore>( + metric->target_url, area_rank, score)); + } + + // Sort scores by the calculated navigation score in descending order. This + // score rank is used by MaybeTakeActionOnLoad, and stored in + // |navigation_scores_map_|. + std::sort(navigation_scores.begin(), navigation_scores.end(), + [](const auto& a, const auto& b) { return a->score > b->score; }); + + MaybeTakeActionOnLoad(navigation_scores); + + // Store navigation scores in |navigation_scores_map_| for fast look up upon + // clicks. + navigation_scores_map_.reserve(navigation_scores.size()); + for (size_t i = 0; i != navigation_scores.size(); ++i) { + navigation_scores[i]->score_rank = base::make_optional(i); + navigation_scores_map_[navigation_scores[i]->url.spec()] = + std::move(navigation_scores[i]); + } } -double NavigationPredictor::GetAnchorElementScore( - const blink::mojom::AnchorElementMetrics& metrics_renderer, - const MetricsFromBrowser& metrics_browser) const { +double NavigationPredictor::CalculateAnchorNavigationScore( + const blink::mojom::AnchorElementMetrics& metrics, + double document_engagement_score, + double target_engagement_score, + int area_rank) const { // TODO(chelu): https://crbug.com/850624/. Experiment with other heuristic // algorithms for computing the anchor elements score. - return metrics_renderer.ratio_visible_area * - metrics_browser.target_engagement_score; + return metrics.ratio_visible_area; } void NavigationPredictor::MaybeTakeActionOnLoad( - const std::vector<double>& scores) const { + const std::vector<std::unique_ptr<NavigationScore>>& + sorted_navigation_scores) const { // TODO(chelu): https://crbug.com/850624/. Given the calculated navigation // scores, this function decides which action to take, or decides not to do // anything. Example actions including preresolve, preload, prerendering, etc. - // Other information (e.g., target urls) should also be passed in. - double highest_score = 0; - for (double score : scores) - highest_score = std::max(highest_score, score); - + // |sorted_navigation_scores| are sorted in descending order, the first one + // has the highest navigation score. UMA_HISTOGRAM_COUNTS_100( "AnchorElementMetrics.Visible.HighestNavigationScore", - static_cast<int>(highest_score)); + static_cast<int>(sorted_navigation_scores[0]->score)); } void NavigationPredictor::RecordMetricsOnLoad(
diff --git a/chrome/browser/navigation_predictor/navigation_predictor.h b/chrome/browser/navigation_predictor/navigation_predictor.h index 5d9ee992..da9555f7 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor.h +++ b/chrome/browser/navigation_predictor/navigation_predictor.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_NAVIGATION_PREDICTOR_NAVIGATION_PREDICTOR_H_ #define CHROME_BROWSER_NAVIGATION_PREDICTOR_NAVIGATION_PREDICTOR_H_ +#include <string> +#include <unordered_map> #include <vector> #include "base/macros.h" @@ -35,8 +37,9 @@ content::RenderFrameHost* render_frame_host); private: - // Struct holding features of an anchor element, extracted from the browser. - struct MetricsFromBrowser; + // Struct holding navigation score, rank and other info of the anchor element. + // Used for look up when an anchor element is clicked. + struct NavigationScore; // blink::mojom::AnchorElementMetricsHost: void ReportAnchorElementMetricsOnClick( @@ -57,16 +60,25 @@ void MergeMetricsSameTargetUrl( std::vector<blink::mojom::AnchorElementMetricsPtr>* metrics) const; - // Given metrics of an anchor element from both renderer and browser process, - // returns navigation score. - double GetAnchorElementScore( - const blink::mojom::AnchorElementMetrics& metrics_renderer, - const MetricsFromBrowser& metrics_browser) const; + // Computes and stores document level metrics, including |number_of_anchors_|, + // |document_engagement_score_|, etc. + void ComputeDocumentMetricsOnLoad( + const std::vector<blink::mojom::AnchorElementMetricsPtr>& metrics); - // Given a vector of navigation scores, decide what action to take, or decide - // not to do anything. Example actions including preresolve, preload, - // prerendering, etc. - void MaybeTakeActionOnLoad(const std::vector<double>& scores) const; + // Given metrics of an anchor element from both renderer and browser process, + // returns navigation score. Virtual for testing purposes. + virtual double CalculateAnchorNavigationScore( + const blink::mojom::AnchorElementMetrics& metrics, + double document_engagement_score, + double target_engagement_score, + int area_rank) const; + + // Given a vector of navigation scores sorted in descending order, decide what + // action to take, or decide not to do anything. Example actions including + // preresolve, preload, prerendering, etc. + void MaybeTakeActionOnLoad( + const std::vector<std::unique_ptr<NavigationScore>>& + sorted_navigation_scores) const; // Record anchor element metrics on page load. void RecordMetricsOnLoad( @@ -78,6 +90,17 @@ // Used to get keyed services. content::BrowserContext* const browser_context_; + // Maps from target url (href) to navigation score. + std::unordered_map<std::string, std::unique_ptr<NavigationScore>> + navigation_scores_map_; + + // Total number of anchors that: href has the same host as the document, + // contains image, inside an iframe, href incremented by 1 from document url. + int number_of_anchors_same_host_ = 0; + int number_of_anchors_contains_image_ = 0; + int number_of_anchors_in_iframe_ = 0; + int number_of_anchors_url_incremented_ = 0; + // Timing of document loaded and last click. base::TimeTicks document_loaded_timing_; base::TimeTicks last_click_timing_;
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc b/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc index 05c1244..89c29a3 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc
@@ -91,6 +91,7 @@ // Simulate a click at the anchor element. // Test that timing info (DurationLoadToFirstClick) can be recorded. +// And that the navigation score can be looked up. IN_PROC_BROWSER_TEST_P(NavigationPredictorBrowserTest, ClickAnchorElement) { base::HistogramTester histogram_tester; @@ -109,12 +110,39 @@ "AnchorElementMetrics.Clicked.HrefEngagementScore2", 1); histogram_tester.ExpectTotalCount( "AnchorElementMetrics.Clicked.DurationLoadToFirstClick", 1); + histogram_tester.ExpectTotalCount( + "AnchorElementMetrics.Clicked.NavigationScore", 1); + } else { histogram_tester.ExpectTotalCount( "AnchorElementMetrics.Clicked.HrefEngagementScore2", 0); } } +// Simulate click at the anchor element. +// Test that correct area ranks are recorded. +IN_PROC_BROWSER_TEST_P(NavigationPredictorBrowserTest, AreaRank) { + base::HistogramTester histogram_tester; + + // This test file contains 5 anchors with different size. + const GURL& url = GetTestURL("/anchors_different_area.html"); + ui_test_utils::NavigateToURL(browser(), url); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(content::ExecuteScript( + browser()->tab_strip_model()->GetActiveWebContents(), + "document.getElementById('medium').click();")); + base::RunLoop().RunUntilIdle(); + + if (base::FeatureList::IsEnabled( + blink::features::kRecordAnchorMetricsClicked)) { + histogram_tester.ExpectUniqueSample("AnchorElementMetrics.Clicked.AreaRank", + 2, 1); + histogram_tester.ExpectTotalCount("AnchorElementMetrics.Visible.RatioArea", + 5); + } +} + // Test that MergeMetricsSameTargetUrl merges anchor elements having the same // href. The html file contains two anchor elements having the same href. IN_PROC_BROWSER_TEST_P(NavigationPredictorBrowserTest,
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc b/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc index be6ceaf7..798ac79 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc
@@ -4,14 +4,49 @@ #include "chrome/browser/navigation_predictor/navigation_predictor.h" +#include <map> + #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/bindings/strong_binding.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/loader/navigation_predictor.mojom.h" #include "url/gurl.h" namespace { +class TestNavigationPredictor : public NavigationPredictor { + public: + explicit TestNavigationPredictor( + mojo::InterfaceRequest<AnchorElementMetricsHost> request, + content::RenderFrameHost* render_frame_host) + : NavigationPredictor(render_frame_host), binding_(this) { + binding_.Bind(std::move(request)); + } + + ~TestNavigationPredictor() override {} + + const std::map<GURL, int>& GetAreaRankMap() const { return area_rank_map_; } + + private: + double CalculateAnchorNavigationScore( + const blink::mojom::AnchorElementMetrics& metrics, + double document_engagement_score, + double target_engagement_score, + int area_rank) const override { + area_rank_map_.emplace(std::make_pair(metrics.target_url, area_rank)); + return 100 * metrics.ratio_area; + } + + // Maps from target URL to area rank of the anchor element. + mutable std::map<GURL, int> area_rank_map_; + + // Used to bind Mojo interface + mojo::Binding<AnchorElementMetricsHost> binding_; +}; + class NavigationPredictorTest : public ChromeRenderViewHostTestHarness { public: NavigationPredictorTest() = default; @@ -19,8 +54,8 @@ void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); - NavigationPredictor::Create(mojo::MakeRequest(&predictor_service_), - main_rfh()); + predictor_service_helper_ = std::make_unique<TestNavigationPredictor>( + mojo::MakeRequest(&predictor_service_), main_rfh()); } void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); } @@ -28,10 +63,12 @@ // Helper function to generate mojom metrics. blink::mojom::AnchorElementMetricsPtr CreateMetricsPtr( const std::string& source_url, - const std::string& target_url) const { + const std::string& target_url, + float ratio_area) const { auto metrics = blink::mojom::AnchorElementMetrics::New(); metrics->source_url = GURL(source_url); metrics->target_url = GURL(target_url); + metrics->ratio_area = ratio_area; return metrics; } @@ -39,8 +76,13 @@ return predictor_service_.get(); } + TestNavigationPredictor* predictor_service_helper() const { + return predictor_service_helper_.get(); + } + private: blink::mojom::AnchorElementMetricsHostPtr predictor_service_; + std::unique_ptr<TestNavigationPredictor> predictor_service_helper_; }; } // namespace @@ -50,7 +92,8 @@ TEST_F(NavigationPredictorTest, ReportAnchorElementMetricsOnClick) { base::HistogramTester histogram_tester; - auto metrics = CreateMetricsPtr("http://example.com", "https://google.com"); + auto metrics = + CreateMetricsPtr("http://example.com", "https://google.com", 0.1); predictor_service()->ReportAnchorElementMetricsOnClick(std::move(metrics)); base::RunLoop().RunUntilIdle(); @@ -62,7 +105,8 @@ TEST_F(NavigationPredictorTest, ReportAnchorElementMetricsOnLoad) { base::HistogramTester histogram_tester; - auto metrics = CreateMetricsPtr("https://example.com", "http://google.com"); + auto metrics = + CreateMetricsPtr("https://example.com", "http://google.com", 0.1); std::vector<blink::mojom::AnchorElementMetricsPtr> metrics_vector; metrics_vector.push_back(std::move(metrics)); predictor_service()->ReportAnchorElementMetricsOnLoad( @@ -78,7 +122,8 @@ TEST_F(NavigationPredictorTest, BadUrlReportAnchorElementMetricsOnClick) { base::HistogramTester histogram_tester; - auto metrics = CreateMetricsPtr("ftp://example.com", "https://google.com"); + auto metrics = + CreateMetricsPtr("ftp://example.com", "https://google.com", 0.1); predictor_service()->ReportAnchorElementMetricsOnClick(std::move(metrics)); base::RunLoop().RunUntilIdle(); @@ -91,7 +136,8 @@ TEST_F(NavigationPredictorTest, BadUrlReportAnchorElementMetricsOnLoad) { base::HistogramTester histogram_tester; - auto metrics = CreateMetricsPtr("https://example.com", "ftp://google.com"); + auto metrics = + CreateMetricsPtr("https://example.com", "ftp://google.com", 0.1); std::vector<blink::mojom::AnchorElementMetricsPtr> metrics_vector; metrics_vector.push_back(std::move(metrics)); predictor_service()->ReportAnchorElementMetricsOnLoad( @@ -101,3 +147,43 @@ histogram_tester.ExpectTotalCount( "AnchorElementMetrics.Visible.HighestNavigationScore", 0); } + +// In this test, multiple anchor element metrics are sent to +// ReportAnchorElementMetricsOnLoad. Test that CalculateAnchorNavigationScore +// works, and that highest navigation score can be recorded correctly. +TEST_F(NavigationPredictorTest, MultipleAnchorElementMetricsOnLoad) { + base::HistogramTester histogram_tester; + + const std::string source = "http://example.com"; + const std::string href_xlarge = "http://example.com/xlarge"; + const std::string href_large = "http://google.com/large"; + const std::string href_medium = "http://google.com/medium"; + const std::string href_small = "http://google.com/small"; + const std::string href_xsmall = "http://google.com/xsmall"; + + std::vector<blink::mojom::AnchorElementMetricsPtr> metrics; + metrics.push_back(CreateMetricsPtr(source, href_xsmall, 0.01)); + metrics.push_back(CreateMetricsPtr(source, href_large, 0.08)); + metrics.push_back(CreateMetricsPtr(source, href_xlarge, 0.1)); + metrics.push_back(CreateMetricsPtr(source, href_small, 0.02)); + metrics.push_back(CreateMetricsPtr(source, href_medium, 0.05)); + + int number_of_mertics_sent = metrics.size(); + predictor_service()->ReportAnchorElementMetricsOnLoad(std::move(metrics)); + base::RunLoop().RunUntilIdle(); + + const std::map<GURL, int>& area_rank_map = + predictor_service_helper()->GetAreaRankMap(); + EXPECT_EQ(number_of_mertics_sent, static_cast<int>(area_rank_map.size())); + EXPECT_EQ(0, area_rank_map.find(GURL(href_xlarge))->second); + EXPECT_EQ(1, area_rank_map.find(GURL(href_large))->second); + EXPECT_EQ(2, area_rank_map.find(GURL(href_medium))->second); + EXPECT_EQ(3, area_rank_map.find(GURL(href_small))->second); + EXPECT_EQ(4, area_rank_map.find(GURL(href_xsmall))->second); + + // The highest score is 100 (scale factor) * 0.1 (largest area) = 10. + histogram_tester.ExpectUniqueSample( + "AnchorElementMetrics.Visible.HighestNavigationScore", 10, 1); + histogram_tester.ExpectTotalCount("AnchorElementMetrics.Visible.RatioArea", + 5); +}
diff --git a/chrome/browser/chrome_network_service_browsertest.cc b/chrome/browser/net/chrome_network_service_browsertest.cc similarity index 100% rename from chrome/browser/chrome_network_service_browsertest.cc rename to chrome/browser/net/chrome_network_service_browsertest.cc
diff --git a/chrome/browser/chrome_network_service_restart_browsertest.cc b/chrome/browser/net/chrome_network_service_restart_browsertest.cc similarity index 100% rename from chrome/browser/chrome_network_service_restart_browsertest.cc rename to chrome/browser/net/chrome_network_service_restart_browsertest.cc
diff --git a/chrome/browser/payments/manifest_verifier_browsertest.cc b/chrome/browser/payments/manifest_verifier_browsertest.cc index 02d91e9..3f1d2cf 100644 --- a/chrome/browser/payments/manifest_verifier_browsertest.cc +++ b/chrome/browser/payments/manifest_verifier_browsertest.cc
@@ -532,6 +532,7 @@ apps[0]->enabled_methods.push_back("interledger"); apps[0]->enabled_methods.push_back("payee-credit-transfer"); apps[0]->enabled_methods.push_back("payer-credit-transfer"); + apps[0]->enabled_methods.push_back("tokenized-card"); apps[0]->enabled_methods.push_back("not-supported"); Verify(std::move(apps)); @@ -539,7 +540,7 @@ EXPECT_EQ(1U, verified_apps().size()); ExpectApp(0, "https://bobpay.com/webpay", {"basic-card", "interledger", "payee-credit-transfer", - "payer-credit-transfer"}, + "payer-credit-transfer", "tokenized-card"}, false); } @@ -552,6 +553,7 @@ apps[0]->enabled_methods.push_back("interledger"); apps[0]->enabled_methods.push_back("payee-credit-transfer"); apps[0]->enabled_methods.push_back("payer-credit-transfer"); + apps[0]->enabled_methods.push_back("tokenized-card"); apps[0]->enabled_methods.push_back("not-supported"); Verify(std::move(apps)); @@ -559,7 +561,7 @@ EXPECT_EQ(1U, verified_apps().size()); ExpectApp(0, "https://bobpay.com/webpay", {"basic-card", "interledger", "payee-credit-transfer", - "payer-credit-transfer"}, + "payer-credit-transfer", "tokenized-card"}, false); } }
diff --git a/chrome/browser/prefs/pref_service_incognito_whitelist.cc b/chrome/browser/prefs/pref_service_incognito_whitelist.cc index 7d8682c..370834b0 100644 --- a/chrome/browser/prefs/pref_service_incognito_whitelist.cc +++ b/chrome/browser/prefs/pref_service_incognito_whitelist.cc
@@ -759,7 +759,7 @@ arc::prefs::kArcSupervisionTransition, arc::prefs::kArcCompatibleFilesystemChosen, arc::prefs::kArcVoiceInteractionValuePropAccepted, - arc::prefs::kEcryptfsMigrationStrategy, arc::prefs::kSmsConnectEnabled, + arc::prefs::kEcryptfsMigrationStrategy, arc::prefs::kVoiceInteractionEnabled, arc::prefs::kVoiceInteractionContextEnabled, arc::prefs::kVoiceInteractionHotwordEnabled,
diff --git a/chrome/browser/profiling_host/background_profiling_triggers.cc b/chrome/browser/profiling_host/background_profiling_triggers.cc index de96545..7a515bd 100644 --- a/chrome/browser/profiling_host/background_profiling_triggers.cc +++ b/chrome/browser/profiling_host/background_profiling_triggers.cc
@@ -120,6 +120,12 @@ } } +bool BackgroundProfilingTriggers::ShouldTriggerControlReport( + int content_process_type) const { + return (content_process_type == content::ProcessType::PROCESS_TYPE_BROWSER) && + base::RandGenerator(kControlPopulationSamplingRate) == 0; +} + void BackgroundProfilingTriggers::PerformMemoryUsageChecks() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); @@ -150,37 +156,40 @@ return; } + // Sample a control population. + for (const auto& proc : dump->process_dumps()) { + if (base::ContainsValue(profiled_pids, proc.pid()) && + ShouldTriggerControlReport( + GetContentProcessType(proc.process_type()))) { + TriggerMemoryReport("MEMLOG_CONTROL_TRIGGER"); + return; + } + } + + // Detect whether memory footprint is too high and send a memlog report. bool should_send_report = false; std::string trigger_name; + for (const auto& proc : dump->process_dumps()) { + if (!base::ContainsValue(profiled_pids, proc.pid())) + continue; - if (base::RandGenerator(kControlPopulationSamplingRate) == 0) { - // Sample a control population. - trigger_name = "MEMLOG_CONTROL_TRIGGER"; - should_send_report = true; - } else { - // Detect whether memory footprint is too high and send a memlog report. - for (const auto& proc : dump->process_dumps()) { - if (!base::ContainsValue(profiled_pids, proc.pid())) - continue; - - uint32_t private_footprint_kb = proc.os_dump().private_footprint_kb; - auto it = pmf_at_last_upload_.find(proc.pid()); - if (it != pmf_at_last_upload_.end()) { - if (private_footprint_kb > it->second + kHighWaterMarkThresholdKb) { - trigger_name = "MEMLOG_BACKGROUND_TRIGGER"; - should_send_report = true; - it->second = private_footprint_kb; - } - continue; - } - - // No high water mark exists yet, check the trigger threshold. - if (IsOverTriggerThreshold(GetContentProcessType(proc.process_type()), - private_footprint_kb)) { + uint32_t private_footprint_kb = proc.os_dump().private_footprint_kb; + auto it = pmf_at_last_upload_.find(proc.pid()); + if (it != pmf_at_last_upload_.end()) { + if (private_footprint_kb > it->second + kHighWaterMarkThresholdKb) { trigger_name = "MEMLOG_BACKGROUND_TRIGGER"; should_send_report = true; - pmf_at_last_upload_[proc.pid()] = private_footprint_kb; + it->second = private_footprint_kb; } + continue; + } + + // No high water mark exists yet, check the trigger threshold. + if (IsOverTriggerThreshold(GetContentProcessType(proc.process_type()), + private_footprint_kb)) { + trigger_name = "MEMLOG_BACKGROUND_TRIGGER"; + should_send_report = true; + pmf_at_last_upload_[proc.pid()] = private_footprint_kb; } }
diff --git a/chrome/browser/profiling_host/background_profiling_triggers.h b/chrome/browser/profiling_host/background_profiling_triggers.h index 2484e27..4f54ea8 100644 --- a/chrome/browser/profiling_host/background_profiling_triggers.h +++ b/chrome/browser/profiling_host/background_profiling_triggers.h
@@ -47,6 +47,11 @@ // Returns true if trace uploads are allowed. bool IsAllowedToUpload() const; + // Returns true if a control report should be sent for the given + // |content_process_type|. + // Virtual for testing. + virtual bool ShouldTriggerControlReport(int content_process_type) const; + // Returns true if |private_footprint_kb| is large enough to trigger // a report for the given |content_process_type|. bool IsOverTriggerThreshold(int content_process_type,
diff --git a/chrome/browser/profiling_host/background_profiling_triggers_unittest.cc b/chrome/browser/profiling_host/background_profiling_triggers_unittest.cc index 199203c..9c7e4680 100644 --- a/chrome/browser/profiling_host/background_profiling_triggers_unittest.cc +++ b/chrome/browser/profiling_host/background_profiling_triggers_unittest.cc
@@ -66,22 +66,33 @@ class FakeBackgroundProfilingTriggers : public BackgroundProfilingTriggers { public: explicit FakeBackgroundProfilingTriggers(ProfilingProcessHost* host) - : BackgroundProfilingTriggers(host), was_report_triggered_(false) {} + : BackgroundProfilingTriggers(host), + was_report_triggered_(false), + should_trigger_control_report_(false) {} using BackgroundProfilingTriggers::OnReceivedMemoryDump; void Reset() { + should_trigger_control_report_ = false; was_report_triggered_ = false; pmf_at_last_upload_.clear(); } bool WasReportTriggered() const { return was_report_triggered_; } + bool ShouldTriggerControlReport(int content_process_type) const override { + return should_trigger_control_report_; + } + void SetControlTrigger(bool trigger_control_report) { + should_trigger_control_report_ = trigger_control_report; + } + private: void TriggerMemoryReport(std::string trigger_name) override { was_report_triggered_ = true; } bool was_report_triggered_; + bool should_trigger_control_report_; }; class BackgroundProfilingTriggersTest : public testing::Test { @@ -200,6 +211,15 @@ triggers_.OnReceivedMemoryDump(profiled_pids_, true, GlobalMemoryDump::MoveFrom(std::move(dump))); EXPECT_TRUE(triggers_.WasReportTriggered()); + + // Ensure control trigger work on browser process, no matter memory usage. + triggers_.Reset(); + triggers_.SetControlTrigger(true); + dump = memory_instrumentation::mojom::GlobalMemoryDump::New(); + PopulateMetrics(&dump, 1, ProcessType::BROWSER, 1, 1, 1); + triggers_.OnReceivedMemoryDump(profiled_pids_, true, + GlobalMemoryDump::MoveFrom(std::move(dump))); + EXPECT_TRUE(triggers_.WasReportTriggered()); } TEST_F(BackgroundProfilingTriggersTest, HighWaterMark) {
diff --git a/chrome/browser/resources/chromeos/login/md_header_bar.js b/chrome/browser/resources/chromeos/login/md_header_bar.js index f669c4bc..33f89d4d 100644 --- a/chrome/browser/resources/chromeos/login/md_header_bar.js +++ b/chrome/browser/resources/chromeos/login/md_header_bar.js
@@ -301,9 +301,6 @@ set signinUIState(state) { this.signinUIState_ = state; this.updateUI_(); - - if (Oobe.getInstance().showingViewsLogin) - chrome.send('updateSigninUIState', [state]); }, /**
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js index 97463c89..c81aa886 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -706,11 +706,6 @@ $('login-header-bar').showCreateSupervisedButton = data.supervisedUsersCanCreate; $('login-header-bar').showGuestButton = data.guestSignin; - if (Oobe.getInstance().showingViewsLogin) { - chrome.send( - 'showGuestButton', - [data.guestSignin && !this.closable && this.isAtTheBeginning()]); - } // Reset SAML this.classList.toggle('full-width', false);
diff --git a/chrome/browser/resources/local_ntp/custom_backgrounds.js b/chrome/browser/resources/local_ntp/custom_backgrounds.js index 0f8839f..51575cf 100644 --- a/chrome/browser/resources/local_ntp/custom_backgrounds.js +++ b/chrome/browser/resources/local_ntp/custom_backgrounds.js
@@ -110,7 +110,7 @@ }; customBackgrounds.CUSTOM_BACKGROUND_OVERLAY = - 'linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2))'; + 'linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.3))'; // These shound match the corresponding values in local_ntp.js, that control the // mv-notice element. @@ -501,21 +501,24 @@ 'url(' + imageData[i].thumbnailImageUrl + ')' ].join(',').trim(); tile.style.backgroundImage = imageWithOverlay; + tile.dataset.attributionLine1 = ''; + tile.dataset.attributionLine2 = ''; + tile.dataset.attributionActionUrl = ''; } else { tile.style.backgroundImage = 'url(' + imageData[i].thumbnailImageUrl + ')'; - } - tile.dataset.url = imageData[i].imageUrl; - tile.dataset.attributionLine1 = + tile.dataset.attributionLine1 = (imageData[i].attributions[0] != undefined ? imageData[i].attributions[0] : ''); - tile.dataset.attributionLine2 = + tile.dataset.attributionLine2 = (imageData[i].attributions[1] != undefined ? imageData[i].attributions[1] : ''); - tile.dataset.attributionActionUrl = imageData[i].attributionActionUrl; + tile.dataset.attributionActionUrl = imageData[i].attributionActionUrl; + } tile.setAttribute('aria-label', imageData[i].attributions[0]); + tile.dataset.url = imageData[i].imageUrl; } else { tile.style.backgroundImage = 'url(' + imageData[i].thumbnailPhotoUrl + ')'; @@ -957,7 +960,6 @@ .classList.contains(customBackgrounds.CLASSES.DONE_AVAILABLE)) { return; } - customBackgrounds.setBackground( customBackgrounds.selectedTile.dataset.url, customBackgrounds.selectedTile.dataset.attributionLine1,
diff --git a/chrome/browser/resources/local_ntp/most_visited_single.js b/chrome/browser/resources/local_ntp/most_visited_single.js index de79a61..a233668 100644 --- a/chrome/browser/resources/local_ntp/most_visited_single.js +++ b/chrome/browser/resources/local_ntp/most_visited_single.js
@@ -8,6 +8,16 @@ /** + * Enum for ids. + * @enum {string} + * @const + */ +const IDS = { + MV_TILES: 'mv-tiles', // Most Visited tiles container. +}; + + +/** * Enum for classnames. * @enum {string} * @const @@ -85,6 +95,13 @@ /** + * Number of tiles per row for Material Design. + * @const {number} + */ +const MD_MAX_TILES_PER_ROW = 5; + + +/** * Number of lines to display in titles. * @type {number} */ @@ -315,6 +332,16 @@ // Add new tileset. cur.id = 'mv-tiles'; parent.appendChild(cur); + + // If this is Material Design, re-balance the tiles if there are more than + // |MD_MAX_TILES_PER_ROW| in order to make even rows. + if (isMDEnabled) { + if (cur.childNodes.length > MD_MAX_TILES_PER_ROW) { + cur.style.maxWidth = + 'calc(var(--md-tile-width) * ' + Math.ceil(cur.childNodes.length / 2); + } + } + // getComputedStyle causes the initial style (opacity 0) to be applied, so // that when we then set it to 1, that triggers the CSS transition. if (fadeIn) {
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index a21d2781a..cd3da04a 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -124,7 +124,6 @@ js_library("find_shortcut_behavior") { deps = [ - "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:cr", ]
diff --git a/chrome/browser/resources/settings/device_page/keyboard.html b/chrome/browser/resources/settings/device_page/keyboard.html index 6f88254..415d4d6 100644 --- a/chrome/browser/resources/settings/device_page/keyboard.html +++ b/chrome/browser/resources/settings/device_page/keyboard.html
@@ -34,15 +34,6 @@ menu-options="[[keyMapTargets_]]"> </settings-dropdown-menu> </div> - <template is="dom-if" if="[[showCapsLock_]]"> - <div class="settings-box" id="capsLockKey"> - <div class="start">$i18n{keyboardKeyCapsLock}</div> - <settings-dropdown-menu label="$i18n{keyboardKeyCapsLock}" - pref="{{prefs.settings.language.remap_caps_lock_key_to}}" - menu-options="[[keyMapTargets_]]"> - </settings-dropdown-menu> - </div> - </template> <template is="dom-if" if="[[showDiamondKey_]]"> <div class="settings-box" id="diamondKey"> <div class="start">$i18n{keyboardKeyDiamond}</div> @@ -66,6 +57,34 @@ menu-options="[[keyMapTargets_]]"> </settings-dropdown-menu> </div> + <template is="dom-if" if="[[showCapsLock_]]"> + <div class="settings-box" id="capsLockKey"> + <div class="start">$i18n{keyboardKeyCapsLock}</div> + <settings-dropdown-menu label="$i18n{keyboardKeyCapsLock}" + pref="{{prefs.settings.language.remap_caps_lock_key_to}}" + menu-options="[[keyMapTargets_]]"> + </settings-dropdown-menu> + </div> + </template> + <template is="dom-if" if="[[showExternalMetaKey_]]"> + <div class="settings-box" id="externalMetaKey"> + <div class="start">$i18n{keyboardKeyExternalMeta}</div> + <settings-dropdown-menu label="$i18n{keyboardKeyExternalMeta}" + pref="{{prefs.settings.language.remap_external_meta_key_to}}" + menu-options="[[keyMapTargets_]]"> + </settings-dropdown-menu> + </div> + </template> + <template is="dom-if" if="[[showAppleCommandKey_]]"> + <div class="settings-box" id="externalCommandKey"> + <div class="start">$i18n{keyboardKeyExternalCommand}</div> + <settings-dropdown-menu + label="$i18n{keyboardKeyExternalCommand}" + pref="{{prefs.settings.language.remap_external_command_key_to}}" + menu-options="[[keyMapTargets_]]"> + </settings-dropdown-menu> + </div> + </template> <settings-toggle-button pref="{{prefs.settings.language.send_function_keys}}" label="$i18n{keyboardSendFunctionKeys}"
diff --git a/chrome/browser/resources/settings/device_page/keyboard.js b/chrome/browser/resources/settings/device_page/keyboard.js index e10766d..204013c2 100644 --- a/chrome/browser/resources/settings/device_page/keyboard.js +++ b/chrome/browser/resources/settings/device_page/keyboard.js
@@ -39,6 +39,21 @@ /** @private Whether to show diamond key options. */ showDiamondKey_: Boolean, + /** + * Whether to show a remapping option for external keyboard's Meta key + * (Search/Windows keys). This is true only when there's an external + * keyboard connected that is a non-Apple keyboard. + * @private + */ + showExternalMetaKey_: Boolean, + + /** + * Whether to show a remapping option for the Command key. This is true when + * one of the connected keyboards is an Apple keyboard. + * @private + */ + showAppleCommandKey_: Boolean, + /** @private {!DropdownMenuOptionList} Menu items for key mapping. */ keyMapTargets_: Object, @@ -114,13 +129,14 @@ /** * Handler for updating which keys to show. - * @param {boolean} showCapsLock - * @param {boolean} showDiamondKey + * @param {Object} keyboardParams * @private */ - onShowKeysChange_: function(showCapsLock, showDiamondKey) { - this.showCapsLock_ = showCapsLock; - this.showDiamondKey_ = showDiamondKey; + onShowKeysChange_: function(keyboardParams) { + this.showCapsLock_ = keyboardParams['showCapsLock']; + this.showDiamondKey_ = keyboardParams['showDiamondKey']; + this.showExternalMetaKey_ = keyboardParams['showExternalMetaKey']; + this.showAppleCommandKey_ = keyboardParams['showAppleCommandKey']; }, onShowKeyboardShortcutsOverlayTap_: function() {
diff --git a/chrome/browser/resources/settings/find_shortcut_behavior.html b/chrome/browser/resources/settings/find_shortcut_behavior.html index 4fedd0e..f6440393 100644 --- a/chrome/browser/resources/settings/find_shortcut_behavior.html +++ b/chrome/browser/resources/settings/find_shortcut_behavior.html
@@ -1,4 +1,3 @@ <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> <script src="find_shortcut_behavior.js"></script>
diff --git a/chrome/browser/resources/settings/find_shortcut_behavior.js b/chrome/browser/resources/settings/find_shortcut_behavior.js index 51103e5b..63d51aa 100644 --- a/chrome/browser/resources/settings/find_shortcut_behavior.js +++ b/chrome/browser/resources/settings/find_shortcut_behavior.js
@@ -3,49 +3,81 @@ // found in the LICENSE file. /** - * @fileoverview Listens for a find keyboard shortcut (i.e. Ctrl/Cmd+f) wherever - * this behavior is applied and invokes canHandleFindShortcut(). If - * canHandleFindShortcut() returns true, handleFindShortcut() will be called. - * Override these methods in your element in order to use this behavior. + * @fileoverview Listens for a find keyboard shortcut (i.e. Ctrl/Cmd+f) + * and keeps track of an stack of potential listeners. Only the listener at the + * top of the stack will be notified that a find shortcut has been invoked. */ -cr.exportPath('settings'); - -/** @polymerBehavior */ -settings.FindShortcutBehaviorImpl = { - keyBindings: { - // <if expr="is_macosx"> - 'meta+f': 'onFindShortcut_', - // </if> - // <if expr="not is_macosx"> - 'ctrl+f': 'onFindShortcut_', - // </if> - }, - - /** @private */ - onFindShortcut_: function(e) { - if (!e.defaultPrevented && this.canHandleFindShortcut()) { - this.handleFindShortcut(); - e.preventDefault(); - } - }, +cr.define('settings', function() { + /** + * Stack of listeners. Only the top listener will handle the shortcut. + * @type {!Array<!HTMLElement>} + */ + const listeners = []; /** - * @return {boolean} - * @protected + * Tracks if any modal context is open in settings. This assumes only one + * modal can be open at a time. The modals that are being tracked include + * cr-dialog and cr-drawer. + * @type {boolean} */ - canHandleFindShortcut: function() { - assertNotReached(); - }, + let modalContextOpen = false; - /** @protected */ - handleFindShortcut: function() { - assertNotReached(); - }, -}; + window.addEventListener('keydown', e => { + if (listeners.length == 0) + return; -/** @polymerBehavior */ -settings.FindShortcutBehavior = [ - Polymer.IronA11yKeysBehavior, - settings.FindShortcutBehaviorImpl, -]; + const modifierPressed = cr.isMac ? e.metaKey : e.ctrlKey; + if (modifierPressed && e.key == 'f') { + if (e.defaultPrevented) + return; + + const listener = /** @type {!{handleFindShortcut: function(boolean)}} */ ( + listeners[listeners.length - 1]); + if (listener.handleFindShortcut(modalContextOpen)) + e.preventDefault(); + } + }); + + window.addEventListener('cr-dialog-open', () => { + modalContextOpen = true; + }); + + window.addEventListener('cr-drawer-opened', () => { + modalContextOpen = true; + }); + + window.addEventListener('close', e => { + if (['CR-DIALOG', 'CR-DRAWER'].includes(e.composedPath()[0].nodeName)) + modalContextOpen = false; + }); + + /** + * Used to determine how to handle find shortcut invocations. + * @polymerBehavior + */ + const FindShortcutBehavior = { + /** + * If handled, return true. + * @param {boolean} modalContextOpen + * @return {boolean} + * @protected + */ + handleFindShortcut(modalContextOpen) { + assertNotReached(); + }, + + becomeActiveFindShortcutListener() { + assert(listeners.length == 0 || listeners[listeners.length - 1] != this); + listeners.push(this); + }, + + removeSelfAsFindShortcutListener() { + assert(listeners.pop() == this); + }, + }; + + return { + FindShortcutBehavior, + }; +});
diff --git a/chrome/browser/resources/settings/languages_page/add_languages_dialog.js b/chrome/browser/resources/settings/languages_page/add_languages_dialog.js index 4e38bc5f..77c6b94a 100644 --- a/chrome/browser/resources/settings/languages_page/add_languages_dialog.js +++ b/chrome/browser/resources/settings/languages_page/add_languages_dialog.js
@@ -48,18 +48,25 @@ /** @override */ attached: function() { this.$.dialog.showModal(); + this.becomeActiveFindShortcutListener(); + }, + + /** @override */ + detached: function() { + this.removeSelfAsFindShortcutListener(); }, // Override settings.FindShortcutBehavior methods. - canHandleFindShortcut: function() { + handleFindShortcut: function(modalContextOpen) { + // Assumes this is the only open modal. + const searchInput = this.$.search.getSearchInput(); + if (searchInput != this.$.search.shadowRoot.activeElement) { + searchInput.scrollIntoViewIfNeeded(); + searchInput.focus(); + } return true; }, - handleFindShortcut: function() { - this.$.search.getSearchInput().scrollIntoViewIfNeeded(); - this.$.search.getSearchInput().focus(); - }, - /** * @param {!CustomEvent} e * @private
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_page.html b/chrome/browser/resources/settings/multidevice_page/multidevice_page.html index 68bbcfe..53b49fa 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_page.html +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_page.html
@@ -32,7 +32,7 @@ <div id="multidevice-label">[[getLabelText_(pageContentData)]]</div> <div class="secondary" id="mutltideviceSubLabel" inner-h-t-m-l= "[[getSubLabelInnerHtml_(pageContentData, - prefs.multidevice_setup.enable_feature_suite.value)]]"> + prefs.multidevice_setup.suite_enabled.value)]]"> </div> </div> <template is="dom-if" @@ -51,7 +51,7 @@ </template> <template is="dom-if" if="[[showToggle_(pageContentData)]]" restamp> <settings-multidevice-feature-toggle - pref="{{prefs.multidevice_setup.enable_feature_suite}}"> + pref="{{prefs.multidevice_setup.suite_enabled}}"> </settings-multidevice-feature-toggle> </template> </div>
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_page.js b/chrome/browser/resources/settings/multidevice_page/multidevice_page.js index 500b562..9ccd097 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_page.js +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_page.js
@@ -73,7 +73,7 @@ case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION: return this.i18nAdvanced('multideviceVerificationText'); default: - return this.getPref('multidevice_setup.enable_feature_suite').value ? + return this.getPref('multidevice_setup.suite_enabled').value ? this.i18n('multideviceEnabled') : this.i18n('multideviceDisabled'); }
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html b/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html index 78d73c90..17b3615 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html
@@ -25,12 +25,11 @@ </style> <div class="settings-box first"> <div id="status-text-container" class="start" - enabled$= - "[[prefs.multidevice_setup.enable_feature_suite.value]]"> - [[getStatusText_(prefs.multidevice_setup.enable_feature_suite.value)]] + enabled$="[[prefs.multidevice_setup.suite_enabled.value]]"> + [[getStatusText_(prefs.multidevice_setup.suite_enabled.value)]] </div> <settings-multidevice-feature-toggle - pref="{{prefs.multidevice_setup.enable_feature_suite}}"> + pref="{{prefs.multidevice_setup.suite_enabled}}"> </settings-multidevice-feature-toggle> </div> <template is="dom-if" @@ -46,7 +45,7 @@ controlling Easy Unlock and make sure it's effectively password protected. --> <settings-multidevice-feature-toggle - pref="{{prefs.multidevice_setup.enable_feature_suite}}"> + pref="{{prefs.multidevice_setup.suite_enabled}}"> </settings-multidevice-feature-toggle> </div> </settings-multidevice-feature-item>
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.js b/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.js index d6f238b..5c2af21ff 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.js +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.js
@@ -45,7 +45,7 @@ * @private */ getStatusText_: function() { - return this.getPref('multidevice_setup.enable_feature_suite').value ? + return this.getPref('multidevice_setup.suite_enabled').value ? this.i18n('multideviceEnabled') : this.i18n('multideviceDisabled'); },
diff --git a/chrome/browser/resources/settings/search_page/search_page.html b/chrome/browser/resources/settings/search_page/search_page.html index 145c58d..0fa27b3f 100644 --- a/chrome/browser/resources/settings/search_page/search_page.html +++ b/chrome/browser/resources/settings/search_page/search_page.html
@@ -47,9 +47,9 @@ <!-- Omnibox search engine --> <div class="settings-box first block"> <div id="search-wrapper"> - <p id="searchExplanation" class="start"> + <div id="searchExplanation" class="start"> $i18nRaw{searchExplanation} - </p> + </div> <template is="dom-if" if="[[isDefaultSearchControlledByPolicy_( prefs.default_search_provider_data.template_url_data)]]"> <cr-policy-pref-indicator pref="[[
diff --git a/chrome/browser/resources/settings/settings_page/BUILD.gn b/chrome/browser/resources/settings/settings_page/BUILD.gn index d354bfa..9114c55 100644 --- a/chrome/browser/resources/settings/settings_page/BUILD.gn +++ b/chrome/browser/resources/settings/settings_page/BUILD.gn
@@ -46,6 +46,7 @@ js_library("settings_subpage") { deps = [ ":settings_subpage_search", + "..:find_shortcut_behavior", "..:route", "//third_party/polymer/v1_0/components-chromium/iron-resizable-behavior:iron-resizable-behavior-extracted", "//third_party/polymer/v1_0/components-chromium/neon-animation:neon-animatable-behavior-extracted",
diff --git a/chrome/browser/resources/settings/settings_page/settings_subpage.html b/chrome/browser/resources/settings/settings_page/settings_subpage.html index 23206c9..b940d7f 100644 --- a/chrome/browser/resources/settings/settings_page/settings_subpage.html +++ b/chrome/browser/resources/settings/settings_page/settings_subpage.html
@@ -7,6 +7,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-ripple/paper-ripple.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html"> +<link rel="import" href="../find_shortcut_behavior.html"> <link rel="import" href="../icons.html"> <link rel="import" href="../route.html"> <link rel="import" href="settings_subpage_search.html">
diff --git a/chrome/browser/resources/settings/settings_page/settings_subpage.js b/chrome/browser/resources/settings/settings_page/settings_subpage.js index 3288061..82fecc6 100644 --- a/chrome/browser/resources/settings/settings_page/settings_subpage.js +++ b/chrome/browser/resources/settings/settings_page/settings_subpage.js
@@ -15,6 +15,8 @@ // TODO(michaelpg): phase out NeonAnimatableBehavior. Polymer.NeonAnimatableBehavior, Polymer.IronResizableBehavior, + settings.FindShortcutBehavior, + settings.RouteObserverBehavior, ], properties: { @@ -47,6 +49,13 @@ type: Object, value: null, }, + + /** @private */ + active_: { + type: Boolean, + value: false, + observer: 'onActiveChanged_', + }, }, /** @override */ @@ -71,6 +80,22 @@ this, () => cr.ui.focusWithoutInk(this.$.closeButton)); }, + /** @protected */ + currentRouteChanged: function(route) { + this.active_ = this.getAttribute('route-path') == route.path; + }, + + /** @private */ + onActiveChanged_: function() { + if (!this.searchLabel) + return; + + if (this.active_) + this.becomeActiveFindShortcutListener(); + else + this.removeSelfAsFindShortcutListener(); + }, + /** * Clear the value of the search field. * @param {!Event} e @@ -89,4 +114,15 @@ onSearchChanged_: function(e) { this.searchTerm = e.detail; }, + + // Override settings.FindShortcutBehavior methods. + handleFindShortcut: function(modalContextOpen) { + if (modalContextOpen) + return false; + const subpageSearch = this.$$('settings-subpage-search'); + const searchInput = subpageSearch.getSearchInput(); + if (searchInput != subpageSearch.shadowRoot.activeElement) + searchInput.focus(); + return true; + }, });
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index d2c4fdc..28cf453 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -609,8 +609,7 @@ type="chrome_html" /> <structure name="IDR_SETTINGS_FIND_SHORTCUT_BEHAVIOR_JS" file ="find_shortcut_behavior.js" - type="chrome_html" - preprocess="true" /> + type="chrome_html" /> <structure name="IDR_SETTINGS_POWERWASH_DIALOG_HTML" file="reset_page/powerwash_dialog.html" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js index b3e2d45..fde4fd05 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -80,15 +80,6 @@ 'refresh-pref': 'onRefreshPref_', }, - /** - * Tracks if any cr-dialog is open anywhere in the UI. An assumption is being - * made that only one cr-dialog is open at a time. If this assumption changes - * |dialogOpen_| should be replaced with a count of the number of dialogs that - * are open. - * @private {boolean} - */ - dialogOpen_: false, - /** @override */ created: function() { settings.initializeRouteFromUrl(); @@ -173,15 +164,6 @@ this.addEventListener('hide-container', () => { this.$.container.style.visibility = 'hidden'; }); - - this.addEventListener('cr-dialog-open', () => { - this.dialogOpen_ = true; - }); - - this.addEventListener('close', e => { - if (e.composedPath()[0].nodeName == 'CR-DIALOG') - this.dialogOpen_ = false; - }); }, /** @override */ @@ -215,6 +197,8 @@ scrollToTop(e.detail.bottom - this.$.container.clientHeight) .then(e.detail.callback); }); + + this.becomeActiveFindShortcutListener(); }, /** @override */ @@ -246,12 +230,11 @@ }, // Override settings.FindShortcutBehavior methods. - canHandleFindShortcut: function() { - return !this.$.drawer.open && !this.dialogOpen_; - }, - - handleFindShortcut: function() { + handleFindShortcut: function(modalContextOpen) { + if (modalContextOpen) + return false; this.$$('cr-toolbar').getSearchField().showAndFocus(); + return true; }, /**
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc index 52f82e2..29044636 100644 --- a/chrome/browser/search/instant_service.cc +++ b/chrome/browser/search/instant_service.cc
@@ -402,9 +402,10 @@ // Get theme information from theme service. theme_info_.reset(new ThemeBackgroundInfo()); - // Get if the current theme is the default theme. + // Get if the current theme is the default theme (or GTK+ on linux). ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_); - theme_info_->using_default_theme = theme_service->UsingDefaultTheme(); + theme_info_->using_default_theme = + theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme(); // Get theme colors. const ui::ThemeProvider& theme_provider =
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index 46e5865..69ead942 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -51,7 +51,7 @@ // theme packs that aren't int-equal to this. Increment this number if you // change default theme assets or if you need themes to recreate their generated // images (which are cached). -const int kThemePackVersion = 51; +const int kThemePackVersion = 52; // IDs that are in the DataPack won't clash with the positive integer // uint16_t. kHeaderID should always have the maximum value because we want the
diff --git a/chrome/browser/ui/ash/ash_shell_init.cc b/chrome/browser/ui/ash/ash_shell_init.cc index 9ce7976f..d95547c 100644 --- a/chrome/browser/ui/ash/ash_shell_init.cc +++ b/chrome/browser/ui/ash/ash_shell_init.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/ui/ash/chrome_shell_delegate.h" #include "content/public/browser/context_factory.h" +#include "content/public/common/service_manager_connection.h" #include "ui/aura/window_tree_host.h" namespace { @@ -27,6 +28,9 @@ content::GetContextFactoryPrivate(); shell_init_params.gpu_interface_provider = std::make_unique<ash::ContentGpuInterfaceProvider>(); + shell_init_params.connector = + content::ServiceManagerConnection::GetForProcess()->GetConnector(); + DCHECK(shell_init_params.connector); // Pass the initial display prefs to ash::Shell as a Value dictionary. // This is done this way to avoid complexities with registering the display // prefs in multiple places (i.e. in g_browser_process->local_state() and
diff --git a/chrome/browser/ui/ash/chrome_keyboard_ui.cc b/chrome/browser/ui/ash/chrome_keyboard_ui.cc index b4ed238..37ee9b4 100644 --- a/chrome/browser/ui/ash/chrome_keyboard_ui.cc +++ b/chrome/browser/ui/ash/chrome_keyboard_ui.cc
@@ -479,8 +479,7 @@ return (contents_window->GetRootWindow() == window->GetRootWindow() && keyboard::IsKeyboardOverscrollEnabled() && contents_window->IsVisible() && - keyboard_controller()->IsKeyboardVisible() && - !keyboard::IsFullscreenHandwritingVirtualKeyboardEnabled()); + keyboard_controller()->IsKeyboardVisible()); } void ChromeKeyboardUI::AddBoundsChangedObserver(aura::Window* window) {
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 151c564..c5837ec 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -26,7 +26,6 @@ #include "chrome/browser/ui/ash/session_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/browser_tabstrip.h" @@ -89,10 +88,6 @@ ChromeShellDelegate::~ChromeShellDelegate() = default; -service_manager::Connector* ChromeShellDelegate::GetShellConnector() const { - return content::ServiceManagerConnection::GetForProcess()->GetConnector(); -} - bool ChromeShellDelegate::CanShowWindowForUser(aura::Window* window) const { return ::CanShowWindowForUser(window, base::BindRepeating(&GetActiveBrowserContext)); @@ -111,17 +106,10 @@ } void ChromeShellDelegate::OpenKeyboardShortcutHelpPage() const { - Profile* profile = ProfileManager::GetActiveUserProfile(); - Browser* browser = chrome::FindTabbedBrowser(profile, false); - - if (!browser) { - browser = new Browser(Browser::CreateParams(profile, true)); - browser->window()->Show(); - } - - browser->window()->Activate(); - - NavigateParams params(browser, GURL(kKeyboardShortcutHelpPageUrl), + chrome::ScopedTabbedBrowserDisplayer scoped_tabbed_browser_displayer( + ProfileManager::GetActiveUserProfile()); + NavigateParams params(scoped_tabbed_browser_displayer.browser(), + GURL(kKeyboardShortcutHelpPageUrl), ui::PAGE_TRANSITION_AUTO_BOOKMARK); params.disposition = WindowOpenDisposition::SINGLETON_TAB; Navigate(¶ms);
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index 51e7944..6532405 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -22,7 +22,6 @@ ~ChromeShellDelegate() override; // ash::ShellDelegate overrides; - service_manager::Connector* GetShellConnector() const override; bool CanShowWindowForUser(aura::Window* window) const override; void PreInit() override; std::unique_ptr<keyboard::KeyboardUI> CreateKeyboardUI() override;
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 2275f916..b15d21e 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -477,7 +477,9 @@ const int item_padding = GetLayoutConstant(LOCATION_BAR_ELEMENT_PADDING); - constexpr int kTextJogIndentDp = 12; + // We have an odd indent value because this is what matches the odd text + // indent value in OmniboxMatchCellView. + constexpr int kTextJogIndentDp = 11; int leading_edit_item_padding = OmniboxFieldTrial::IsJogTextfieldOnPopupEnabled() ? GetOmniboxPopupView()->IsOpen() ? kTextJogIndentDp : 0
diff --git a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc index 1fab783c..ed3c0ae 100644 --- a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc +++ b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc
@@ -66,8 +66,6 @@ IdentityManagerFactory::GetForProfile( Profile::FromBrowserContext(web_contents_->GetBrowserContext()) ->GetOriginalProfile()), - /*unmask_delegate=*/this, - /*save_delegate=*/nullptr, Profile::FromBrowserContext(web_contents_->GetBrowserContext()) ->IsOffTheRecord()), full_card_request_(this, @@ -82,12 +80,6 @@ CvcUnmaskViewController::~CvcUnmaskViewController() {} -void CvcUnmaskViewController::OnDidGetRealPan( - autofill::AutofillClient::PaymentsRpcResult result, - const std::string& real_pan) { - full_card_request_.OnDidGetRealPan(result, real_pan); -} - void CvcUnmaskViewController::LoadRiskData( const base::Callback<void(const std::string&)>& callback) { autofill::LoadRiskData(0, web_contents_, callback);
diff --git a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.h b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.h index 612715c..41e8c78f 100644 --- a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.h +++ b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.h
@@ -39,7 +39,6 @@ class CvcUnmaskViewController : public PaymentRequestSheetController, public autofill::RiskDataLoader, - public autofill::payments::PaymentsClientUnmaskDelegate, public autofill::payments::FullCardRequest::UIDelegate, public views::ComboboxListener, public views::TextfieldController { @@ -54,10 +53,6 @@ content::WebContents* web_contents); ~CvcUnmaskViewController() override; - // autofill::payments::PaymentsClientUnmaskDelegate: - void OnDidGetRealPan(autofill::AutofillClient::PaymentsRpcResult result, - const std::string& real_pan) override; - // autofill::RiskDataLoader: void LoadRiskData( const base::Callback<void(const std::string&)>& callback) override;
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 2d328a81..0d06906c 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -40,7 +40,6 @@ #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/ash/login_screen_client.h" #include "chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" @@ -580,9 +579,6 @@ AddCallback("updateOobeDialogSize", &GaiaScreenHandler::HandleUpdateOobeDialogSize); AddCallback("hideOobeDialog", &GaiaScreenHandler::HandleHideOobeDialog); - AddCallback("updateSigninUIState", - &GaiaScreenHandler::HandleUpdateSigninUIState); - AddCallback("showGuestButton", &GaiaScreenHandler::HandleShowGuestButton); // Allow UMA metrics collection from JS. web_ui()->AddMessageHandler(std::make_unique<MetricsHandler>()); @@ -856,26 +852,6 @@ base::Value(false) /* isSamlUserPasswordless */); } -void GaiaScreenHandler::HandleUpdateSigninUIState(int state) { - if (!ash::features::IsViewsLoginEnabled() || - !LoginScreenClient::HasInstance()) { - return; - } - - auto dialog_state = static_cast<ash::mojom::OobeDialogState>(state); - DCHECK(ash::mojom::IsKnownEnumValue(dialog_state)); - LoginScreenClient::Get()->login_screen()->NotifyOobeDialogState(dialog_state); -} - -void GaiaScreenHandler::HandleShowGuestButton(bool show) { - if (!ash::features::IsViewsLoginEnabled() || - !LoginScreenClient::HasInstance()) { - return; - } - - LoginScreenClient::Get()->login_screen()->SetAllowLoginAsGuest(show); -} - void GaiaScreenHandler::OnShowAddUser() { signin_screen_handler_->is_account_picker_showing_first_time_ = false; lock_screen_utils::EnforcePolicyInputMethods(std::string());
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h index 6178fa46..84306fd 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -137,9 +137,6 @@ void HandleGetIsSamlUserPasswordless(const std::string& callback_id, const std::string& typed_email, const std::string& gaia_id); - void HandleUpdateSigninUIState(int state); - void HandleShowGuestButton(bool show); - void OnShowAddUser(); // Really handles the complete login message.
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc index a54f351..9153024 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
@@ -14,18 +14,29 @@ #include "content/public/browser/web_ui.h" #include "content/public/common/service_manager_connection.h" #include "services/service_manager/public/cpp/connector.h" +#include "ui/chromeos/events/event_rewriter_chromeos.h" #include "ui/events/devices/input_device_manager.h" namespace { -bool HasExternalKeyboard() { +struct KeyboardsStateResult { + bool has_external_non_apple_keyboard = false; + bool has_apple_keyboard = false; +}; + +KeyboardsStateResult GetKeyboardsState() { + KeyboardsStateResult result; for (const ui::InputDevice& keyboard : ui::InputDeviceManager::GetInstance()->GetKeyboardDevices()) { - if (keyboard.type == ui::InputDeviceType::INPUT_DEVICE_EXTERNAL) - return true; + const ui::EventRewriterChromeOS::DeviceType type = + ui::EventRewriterChromeOS::GetDeviceType(keyboard); + if (type == ui::EventRewriterChromeOS::kDeviceAppleKeyboard) + result.has_apple_keyboard = true; + else if (type == ui::EventRewriterChromeOS::kDeviceExternalNonAppleKeyboard) + result.has_external_non_apple_keyboard = true; } - return false; + return result; } } // namespace @@ -115,14 +126,25 @@ void KeyboardHandler::UpdateShowKeys() { // kHasChromeOSKeyboard will be unset on Chromebooks that have standalone Caps // Lock keys. - const base::Value has_caps_lock( - HasExternalKeyboard() || - !base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kHasChromeOSKeyboard)); - const base::Value has_diamond_key( + const KeyboardsStateResult keyboards_state = GetKeyboardsState(); + const bool has_caps_lock = keyboards_state.has_apple_keyboard || + keyboards_state.has_external_non_apple_keyboard || + !base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kHasChromeOSKeyboard); + const bool has_diamond_key = base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kHasChromeOSDiamondKey)); - FireWebUIListener(kShowKeysChangedName, has_caps_lock, has_diamond_key); + chromeos::switches::kHasChromeOSDiamondKey); + + base::Value keyboard_params(base::Value::Type::DICTIONARY); + keyboard_params.SetKey("showCapsLock", base::Value(has_caps_lock)); + keyboard_params.SetKey("showDiamondKey", base::Value(has_diamond_key)); + keyboard_params.SetKey( + "showExternalMetaKey", + base::Value(keyboards_state.has_external_non_apple_keyboard)); + keyboard_params.SetKey("showAppleCommandKey", + base::Value(keyboards_state.has_apple_keyboard)); + + FireWebUIListener(kShowKeysChangedName, keyboard_params); } } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc index c875a448..a020a2e 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc
@@ -45,7 +45,9 @@ // which keys should be shown. False is returned if the message was invalid or // not found. bool GetLastShowKeysChangedMessage(bool* has_caps_lock_out, - bool* has_diamond_key_out) + bool* has_diamond_key_out, + bool* has_external_meta_key_out, + bool* has_apple_command_key_out) WARN_UNUSED_RESULT { for (auto it = web_ui_.call_data().rbegin(); it != web_ui_.call_data().rend(); ++it) { @@ -56,8 +58,29 @@ name != KeyboardHandler::kShowKeysChangedName) { continue; } - return data->arg2()->GetAsBoolean(has_caps_lock_out) && - data->arg3()->GetAsBoolean(has_diamond_key_out); + + if (!data->arg2() || + data->arg2()->type() != base::Value::Type::DICTIONARY) { + return false; + } + + const base::Value* keyboard_params = data->arg2(); + const std::vector<std::pair<std::string, bool*>> path_to_out_param = { + {"showCapsLock", has_caps_lock_out}, + {"showDiamondKey", has_diamond_key_out}, + {"showExternalMetaKey", has_external_meta_key_out}, + {"showAppleCommandKey", has_apple_command_key_out}, + }; + + for (const auto& pair : path_to_out_param) { + auto* found = keyboard_params->FindKey(pair.first); + if (!found) + return false; + + *(pair.second) = found->GetBool(); + } + + return true; } return false; } @@ -66,8 +89,10 @@ // is present and false otherwise. A failure is added if a message wasn't // found. bool HasCapsLock() { - bool has_caps_lock = false, has_diamond_key = false; - if (!GetLastShowKeysChangedMessage(&has_caps_lock, &has_diamond_key)) { + bool has_caps_lock = false; + bool ignored = false; + if (!GetLastShowKeysChangedMessage(&has_caps_lock, &ignored, &ignored, + &ignored)) { ADD_FAILURE() << "Didn't get " << KeyboardHandler::kShowKeysChangedName; return false; } @@ -78,14 +103,44 @@ // is present and false otherwise. A failure is added if a message wasn't // found. bool HasDiamondKey() { - bool has_caps_lock = false, has_diamond_key = false; - if (!GetLastShowKeysChangedMessage(&has_caps_lock, &has_diamond_key)) { + bool has_diamond_key = false; + bool ignored = false; + if (!GetLastShowKeysChangedMessage(&ignored, &has_diamond_key, &ignored, + &ignored)) { ADD_FAILURE() << "Didn't get " << KeyboardHandler::kShowKeysChangedName; return false; } return has_diamond_key; } + // Returns true if the last keys-changed message reported that a Meta key on + // an external keyboard is present and false otherwise. A failure is added if + // a message wasn't found. + bool HasExternalMetaKey() { + bool has_external_meta = false; + bool ignored = false; + if (!GetLastShowKeysChangedMessage(&ignored, &ignored, &has_external_meta, + &ignored)) { + ADD_FAILURE() << "Didn't get " << KeyboardHandler::kShowKeysChangedName; + return false; + } + return has_external_meta; + } + + // Returns true if the last keys-changed message reported that a Command key + // on an Apple keyboard is present and false otherwise. A failure is added if + // a message wasn't found. + bool HasAppleCommandKey() { + bool has_apple_command_key = false; + bool ignored = false; + if (!GetLastShowKeysChangedMessage(&ignored, &ignored, &ignored, + &has_apple_command_key)) { + ADD_FAILURE() << "Didn't get " << KeyboardHandler::kShowKeysChangedName; + return false; + } + return has_apple_command_key; + } + ui::InputDeviceClientTestApi input_device_client_test_api_; content::TestWebUI web_ui_; TestKeyboardHandler handler_; @@ -101,6 +156,8 @@ handler_test_api_.Initialize(); EXPECT_FALSE(HasCapsLock()); EXPECT_FALSE(HasDiamondKey()); + EXPECT_FALSE(HasExternalMetaKey()); + EXPECT_FALSE(HasAppleCommandKey()); } TEST_F(KeyboardHandlerTest, NonChromeOSKeyboard) { @@ -109,6 +166,8 @@ handler_test_api_.Initialize(); EXPECT_TRUE(HasCapsLock()); EXPECT_FALSE(HasDiamondKey()); + EXPECT_FALSE(HasExternalMetaKey()); + EXPECT_FALSE(HasAppleCommandKey()); } TEST_F(KeyboardHandlerTest, ExternalKeyboard) { @@ -120,18 +179,43 @@ handler_test_api_.Initialize(); EXPECT_FALSE(HasCapsLock()); EXPECT_FALSE(HasDiamondKey()); + EXPECT_FALSE(HasExternalMetaKey()); + EXPECT_FALSE(HasAppleCommandKey()); // Simulate an external keyboard being connected. We should assume there's a - // Caps Lock key now. + // Caps Lock and Meta keys now. input_device_client_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{ {2, ui::INPUT_DEVICE_EXTERNAL, "external keyboard"}}); EXPECT_TRUE(HasCapsLock()); EXPECT_FALSE(HasDiamondKey()); + EXPECT_TRUE(HasExternalMetaKey()); + EXPECT_FALSE(HasAppleCommandKey()); + + // Simulate an external Apple keyboard being connected. Now users can remap + // the command key. + input_device_client_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{ + {3, ui::INPUT_DEVICE_EXTERNAL, "Apple Inc. Apple Keyboard"}}); + EXPECT_TRUE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); + EXPECT_FALSE(HasExternalMetaKey()); + EXPECT_TRUE(HasAppleCommandKey()); + + // Simulate two external keyboards (Apple and non-Apple) are connected at the + // same time. + input_device_client_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{ + {2, ui::INPUT_DEVICE_EXTERNAL, "external keyboard"}, + {3, ui::INPUT_DEVICE_EXTERNAL, "Apple Inc. Apple Keyboard"}}); + EXPECT_TRUE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); + EXPECT_TRUE(HasExternalMetaKey()); + EXPECT_TRUE(HasAppleCommandKey()); // Disconnect the external keyboard and check that the key goes away. input_device_client_test_api_.SetKeyboardDevices({}); EXPECT_FALSE(HasCapsLock()); EXPECT_FALSE(HasDiamondKey()); + EXPECT_FALSE(HasExternalMetaKey()); + EXPECT_FALSE(HasAppleCommandKey()); } TEST_F(KeyboardHandlerTest, DiamondKey) { @@ -142,6 +226,8 @@ handler_test_api_.Initialize(); EXPECT_FALSE(HasCapsLock()); EXPECT_TRUE(HasDiamondKey()); + EXPECT_FALSE(HasExternalMetaKey()); + EXPECT_FALSE(HasAppleCommandKey()); } } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 8b6355b..0339dfc 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -613,6 +613,9 @@ {"keyboardKeyEscape", IDS_SETTINGS_KEYBOARD_KEY_ESCAPE}, {"keyboardKeyBackspace", IDS_SETTINGS_KEYBOARD_KEY_BACKSPACE}, {"keyboardKeyDisabled", IDS_SETTINGS_KEYBOARD_KEY_DISABLED}, + {"keyboardKeyExternalCommand", + IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_COMMAND}, + {"keyboardKeyExternalMeta", IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_META}, {"keyboardSendFunctionKeys", IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS}, {"keyboardSendFunctionKeysDescription", ui::DeviceUsesKeyboardLayout2()
diff --git a/chrome/browser/web_applications/bookmark_apps/BUILD.gn b/chrome/browser/web_applications/bookmark_apps/BUILD.gn index c79a8c9..12dc550 100644 --- a/chrome/browser/web_applications/bookmark_apps/BUILD.gn +++ b/chrome/browser/web_applications/bookmark_apps/BUILD.gn
@@ -8,8 +8,6 @@ source_set("bookmark_apps") { sources = [ - "external_web_apps.cc", - "external_web_apps.h", "policy/web_app_policy_constants.cc", "policy/web_app_policy_constants.h", "policy/web_app_policy_manager.cc", @@ -27,7 +25,6 @@ testonly = true sources = [ - "external_web_apps_unittest.cc", "policy/web_app_policy_manager_unittest.cc", ]
diff --git a/chrome/browser/web_applications/bookmark_apps/external_web_apps.cc b/chrome/browser/web_applications/bookmark_apps/external_web_apps.cc deleted file mode 100644 index f65bc5d..0000000 --- a/chrome/browser/web_applications/bookmark_apps/external_web_apps.cc +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/web_applications/bookmark_apps/external_web_apps.h" - -#include <memory> -#include <string> -#include <utility> - -#include "base/callback.h" -#include "base/files/file_enumerator.h" -#include "base/json/json_file_value_serializer.h" -#include "base/threading/thread_restrictions.h" -#include "url/gurl.h" - -namespace web_app { - -static constexpr char kWebAppManifestUrl[] = "web_app_manifest_url"; -static constexpr char kWebAppStartUrl[] = "web_app_start_url"; - -void ScanDirForExternalWebApps(base::FilePath dir, - ScanDirForExternalWebAppsCallback callback) { - base::AssertBlockingAllowed(); - base::FilePath::StringType extension(FILE_PATH_LITERAL(".json")); - base::FileEnumerator json_files(dir, - false, // Recursive. - base::FileEnumerator::FILES); - - std::vector<web_app::PendingAppManager::AppInfo> app_infos; - - for (base::FilePath file = json_files.Next(); !file.empty(); - file = json_files.Next()) { - if (!file.MatchesExtension(extension)) { - continue; - } - - JSONFileValueDeserializer deserializer(file); - std::string error_msg; - std::unique_ptr<base::Value> value = - deserializer.Deserialize(nullptr, &error_msg); - if (!value) { - VLOG(2) << file.value() << " was not valid JSON: " << error_msg; - continue; - } - if (value->type() != base::Value::Type::DICTIONARY) { - VLOG(2) << file.value() << " was not a dictionary as the top level"; - continue; - } - std::unique_ptr<base::DictionaryValue> dict_value = - base::DictionaryValue::From(std::move(value)); - - std::string manifest_url_str; - if (!dict_value->GetString(kWebAppStartUrl, &manifest_url_str) || - manifest_url_str.empty() || !GURL(manifest_url_str).is_valid()) { - VLOG(2) << file.value() << " had an invalid " << kWebAppManifestUrl; - continue; - } - - std::string start_url_str; - if (!dict_value->GetString(kWebAppStartUrl, &start_url_str) || - start_url_str.empty()) { - VLOG(2) << file.value() << " had an invalid " << kWebAppStartUrl; - continue; - } - GURL start_url(start_url_str); - if (!start_url.is_valid()) { - VLOG(2) << file.value() << " had an invalid " << kWebAppStartUrl; - continue; - } - - app_infos.emplace_back( - std::move(start_url), - web_app::PendingAppManager::LaunchContainer::kWindow); - } - - std::move(callback).Run(std::move(app_infos)); -} - -} // namespace web_app
diff --git a/chrome/browser/web_applications/bookmark_apps/external_web_apps.h b/chrome/browser/web_applications/bookmark_apps/external_web_apps.h deleted file mode 100644 index 5976242..0000000 --- a/chrome/browser/web_applications/bookmark_apps/external_web_apps.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_WEB_APPLICATIONS_BOOKMARK_APPS_EXTERNAL_WEB_APPS_H_ -#define CHROME_BROWSER_WEB_APPLICATIONS_BOOKMARK_APPS_EXTERNAL_WEB_APPS_H_ - -#include <vector> - -#include "base/callback_forward.h" -#include "base/files/file_path.h" -#include "chrome/browser/web_applications/components/pending_app_manager.h" - -namespace web_app { - -using ScanDirForExternalWebAppsCallback = - base::OnceCallback<void(std::vector<web_app::PendingAppManager::AppInfo>)>; - -// Scans the given directory (non-recursively) for *.json files that define -// "external web apps", the Web App analogs of "external extensions", described -// at https://developer.chrome.com/apps/external_extensions -// -// This function performs file I/O, and must not be scheduled on UI threads. -void ScanDirForExternalWebApps(base::FilePath dir, - ScanDirForExternalWebAppsCallback callback); - -} // namespace web_app - -#endif // CHROME_BROWSER_WEB_APPLICATIONS_BOOKMARK_APPS_EXTERNAL_WEB_APPS_H_
diff --git a/chrome/browser/web_applications/bookmark_apps/external_web_apps_unittest.cc b/chrome/browser/web_applications/bookmark_apps/external_web_apps_unittest.cc deleted file mode 100644 index 84c98b1..0000000 --- a/chrome/browser/web_applications/bookmark_apps/external_web_apps_unittest.cc +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright (c) 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/web_applications/bookmark_apps/external_web_apps.h" - -#include <algorithm> -#include <vector> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/path_service.h" -#include "chrome/common/chrome_paths.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace { - -static constexpr char kWebAppDefaultApps[] = "web_app_default_apps"; - -// Returns the chrome/test/data/web_app_default_apps/sub_dir directory that -// holds the *.json data files from which ScanDirForExternalWebApps should -// extract URLs from. -static base::FilePath test_dir(const char* sub_dir) { - base::FilePath dir; - if (!base::PathService::Get(chrome::DIR_TEST_DATA, &dir)) { - ADD_FAILURE() - << "base::PathService::Get could not resolve chrome::DIR_TEST_DATA"; - } - return dir.AppendASCII(kWebAppDefaultApps).AppendASCII(sub_dir); -} - -using AppInfos = std::vector<web_app::PendingAppManager::AppInfo>; - -} // namespace - -class ScanDirForExternalWebAppsTest : public testing::Test {}; - -TEST_F(ScanDirForExternalWebAppsTest, GoodJson) { - // The good_json directory contains two good JSON files: - // chrome_platform_status.json and google_io_2016.json. - web_app::ScanDirForExternalWebApps( - test_dir("good_json"), base::BindOnce([](AppInfos app_infos) { - static std::string urls[] = { - "https://www.chromestatus.com/features", - "https://events.google.com/io2016/?utm_source=web_app_manifest", - }; - - EXPECT_EQ(2u, app_infos.size()); - - for (const auto& url : urls) { - EXPECT_NE( - app_infos.end(), - std::find( - app_infos.begin(), app_infos.end(), - web_app::PendingAppManager::AppInfo( - GURL(url), - web_app::PendingAppManager::LaunchContainer::kWindow))); - } - })); -} - -TEST_F(ScanDirForExternalWebAppsTest, BadJson) { - // The bad_json directory contains one (malformed) JSON file. - web_app::ScanDirForExternalWebApps(test_dir("bad_json"), - base::BindOnce([](AppInfos app_infos) { - EXPECT_EQ(0u, app_infos.size()); - })); -} - -TEST_F(ScanDirForExternalWebAppsTest, TxtButNoJson) { - // The txt_but_no_json directory contains one file, and the contents of that - // file is valid JSON, but that file's name does not end with ".json". - web_app::ScanDirForExternalWebApps(test_dir("txt_but_no_json"), - base::BindOnce([](AppInfos app_infos) { - EXPECT_EQ(0u, app_infos.size()); - })); -} - -TEST_F(ScanDirForExternalWebAppsTest, MixedJson) { - // The mixed_json directory contains one empty JSON file, one malformed JSON - // file and one good JSON file. ScanDirForExternalWebApps should still pick - // up that one good JSON file: polytimer.json. - web_app::ScanDirForExternalWebApps( - test_dir("mixed_json"), base::BindOnce([](AppInfos app_infos) { - EXPECT_EQ(1u, app_infos.size()); - if (app_infos.size() == 1) { - EXPECT_EQ(app_infos[0].url.spec(), - std::string("https://polytimer.rocks/?homescreen=1")); - } - })); -}
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 5e4ef808..6ccec79 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -4,14 +4,8 @@ #include "chrome/browser/web_applications/web_app_provider.h" -#include "base/bind.h" -#include "base/path_service.h" -#include "base/task_scheduler/post_task.h" -#include "build/build_config.h" -#include "chrome/browser/web_applications/bookmark_apps/external_web_apps.h" #include "chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/web_app_provider_factory.h" -#include "chrome/common/chrome_paths.h" namespace web_app { @@ -23,70 +17,9 @@ WebAppProvider::WebAppProvider(PrefService* pref_service) : web_app_policy_manager_( std::make_unique<WebAppPolicyManager>(pref_service)) { -#if defined(OS_CHROMEOS) - // As of mid 2018, only Chrome OS has default web apps or external web apps. - // In the future, we might open external web apps to other flavors. - ScanForExternalWebApps(); -#endif // defined(OS_CHROMEOS) + // TODO(nigeltao): install default web apps as per http://crbug.com/855281 } WebAppProvider::~WebAppProvider() = default; -void WebAppProvider::ScanForExternalWebApps() { -#if !defined(OS_CHROMEOS) - // chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS is only defined for OS_LINUX. - // OS_CHROMEOS is a variant of OS_LINUX. -#else - // For manual testing, it can be useful to s/STANDALONE/USER/, as writing to - // "$HOME/.config/chromium/test-user/.config/chromium/External Extensions" - // does not require root ACLs, unlike "/usr/share/chromium/extensions". - // - // TODO(nigeltao): do we want to append a sub-directory name, analogous to - // the "arc" in "/usr/share/chromium/extensions/arc" as per - // chrome/browser/ui/app_list/arc/arc_default_app_list.cc? Or should we not - // sort "system apps" into directories based on their platform (e.g. ARC, - // PWA, etc.), and instead examine the JSON contents (e.g. an "activity" - // key means ARC, "web_app_start_url" key means PWA, etc.)? - base::FilePath dir; - if (!base::PathService::Get(chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS, - &dir)) { - LOG(ERROR) << "ScanForExternalWebApps: base::PathService::Get failed"; - return; - } - - auto callback = - base::BindOnce(&WebAppProvider::ScanForExternalWebAppsCallback, - weak_ptr_factory_.GetWeakPtr()); - - base::PostTaskWithTraits(FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce(&web_app::ScanDirForExternalWebApps, - dir, std::move(callback))); -#endif // !defined(OS_CHROMEOS) -} - -void WebAppProvider::ScanForExternalWebAppsCallback( - std::vector<web_app::PendingAppManager::AppInfo> app_infos) { - // TODO(nigeltao/ortuno): we shouldn't need a *policy* manager to get to a - // PendingAppManager. As ortuno@ says, "We should refactor PendingAppManager - // to no longer be owned by WebAppPolicyManager. I made it that way since at - // the time, WebAppPolicyManager was its only client." - // - // TODO(nigeltao/ortuno): drop the const_cast. Either - // WebAppPolicyManager::pending_app_manager should lose the const or we - // should acquire a (non-const) PendingAppManager by other means. - auto& pending_app_manager = const_cast<web_app::PendingAppManager&>( - web_app_policy_manager_->pending_app_manager()); - - // TODO(nigeltao/ortuno): confirm that the PendingAppManager callee is - // responsible for filtering out already-installed apps. - // - // TODO(nigeltao/ortuno): does the PendingAppManager care which thread we're - // on (e.g. "the UI thread", "the File thread") when we call into it? Do we - // need to bounce to another thread from here? Note that, in the long term, - // we might not be in the browser process, so there might not be the concept - // of "the UI thread". - pending_app_manager.ProcessAppOperations(std::move(app_infos)); -} - } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_provider.h b/chrome/browser/web_applications/web_app_provider.h index 9a7f35da..f2bec23 100644 --- a/chrome/browser/web_applications/web_app_provider.h +++ b/chrome/browser/web_applications/web_app_provider.h
@@ -6,11 +6,8 @@ #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_PROVIDER_H_ #include <memory> -#include <vector> #include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/web_applications/components/pending_app_manager.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_service.h" @@ -32,14 +29,8 @@ ~WebAppProvider() override; private: - void ScanForExternalWebApps(); - void ScanForExternalWebAppsCallback( - std::vector<web_app::PendingAppManager::AppInfo>); - std::unique_ptr<WebAppPolicyManager> web_app_policy_manager_; - base::WeakPtrFactory<WebAppProvider> weak_ptr_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(WebAppProvider); };
diff --git a/chrome/common/extensions/api/settings_private.idl b/chrome/common/extensions/api/settings_private.idl index f998ee3..1e2996c 100644 --- a/chrome/common/extensions/api/settings_private.idl +++ b/chrome/common/extensions/api/settings_private.idl
@@ -62,10 +62,10 @@ // Sets a pref value. // |name|: The name of the pref. // |value|: The new value of the pref. - // |pageId|: The user metrics identifier or null. + // |pageId|: An optional user metrics identifier. // |callback|: The callback for whether the pref was set or not. static void setPref(DOMString name, any value, - DOMString pageId, OnPrefSetCallback callback); + optional DOMString pageId, optional OnPrefSetCallback callback); // Gets an array of all the prefs. static void getAllPrefs(GetAllPrefsCallback callback);
diff --git a/chrome/common/media_router/discovery/media_sink_internal.cc b/chrome/common/media_router/discovery/media_sink_internal.cc index 30a7b726..17e42335 100644 --- a/chrome/common/media_router/discovery/media_sink_internal.cc +++ b/chrome/common/media_router/discovery/media_sink_internal.cc
@@ -25,6 +25,10 @@ InternalCopyConstructFrom(other); } +MediaSinkInternal::MediaSinkInternal(MediaSinkInternal&& other) noexcept { + InternalMoveConstructFrom(std::move(other)); +} + MediaSinkInternal::~MediaSinkInternal() { InternalCleanup(); } @@ -38,6 +42,15 @@ return *this; } +MediaSinkInternal& MediaSinkInternal::operator=( + MediaSinkInternal&& other) noexcept { + if (this != &other) { + InternalCleanup(); + InternalMoveConstructFrom(std::move(other)); + } + return *this; +} + bool MediaSinkInternal::operator==(const MediaSinkInternal& other) const { if (sink_type_ != other.sink_type_) return false; @@ -142,6 +155,23 @@ NOTREACHED(); } +void MediaSinkInternal::InternalMoveConstructFrom(MediaSinkInternal&& other) { + sink_ = std::move(other.sink_); + sink_type_ = other.sink_type_; + + switch (sink_type_) { + case SinkType::DIAL: + new (&dial_data_) DialSinkExtraData(std::move(other.dial_data_)); + return; + case SinkType::CAST: + new (&cast_data_) CastSinkExtraData(std::move(other.cast_data_)); + return; + case SinkType::GENERIC: + return; + } + NOTREACHED(); +} + void MediaSinkInternal::InternalCleanup() { switch (sink_type_) { case SinkType::DIAL: @@ -158,6 +188,8 @@ DialSinkExtraData::DialSinkExtraData() = default; DialSinkExtraData::DialSinkExtraData(const DialSinkExtraData& other) = default; +DialSinkExtraData::DialSinkExtraData(DialSinkExtraData&& other) noexcept = + default; DialSinkExtraData::~DialSinkExtraData() = default; bool DialSinkExtraData::operator==(const DialSinkExtraData& other) const { @@ -167,6 +199,8 @@ CastSinkExtraData::CastSinkExtraData() = default; CastSinkExtraData::CastSinkExtraData(const CastSinkExtraData& other) = default; +CastSinkExtraData::CastSinkExtraData(CastSinkExtraData&& other) noexcept = + default; CastSinkExtraData::~CastSinkExtraData() = default; bool CastSinkExtraData::operator==(const CastSinkExtraData& other) const {
diff --git a/chrome/common/media_router/discovery/media_sink_internal.h b/chrome/common/media_router/discovery/media_sink_internal.h index b1cbe15..c2e3691 100644 --- a/chrome/common/media_router/discovery/media_sink_internal.h +++ b/chrome/common/media_router/discovery/media_sink_internal.h
@@ -26,6 +26,7 @@ DialSinkExtraData(); DialSinkExtraData(const DialSinkExtraData& other); + DialSinkExtraData(DialSinkExtraData&& other) noexcept; ~DialSinkExtraData(); bool operator==(const DialSinkExtraData& other) const; @@ -54,6 +55,7 @@ CastSinkExtraData(); CastSinkExtraData(const CastSinkExtraData& other); + CastSinkExtraData(CastSinkExtraData&& other) noexcept; ~CastSinkExtraData(); bool operator==(const CastSinkExtraData& other) const; @@ -73,10 +75,12 @@ // Used to push instance of this class into vector. MediaSinkInternal(const MediaSinkInternal& other); + MediaSinkInternal(MediaSinkInternal&& other) noexcept; ~MediaSinkInternal(); MediaSinkInternal& operator=(const MediaSinkInternal& other); + MediaSinkInternal& operator=(MediaSinkInternal&& other) noexcept; bool operator==(const MediaSinkInternal& other) const; bool operator!=(const MediaSinkInternal& other) const; // Sorted by sink id. @@ -109,6 +113,7 @@ private: void InternalCopyConstructFrom(const MediaSinkInternal& other); + void InternalMoveConstructFrom(MediaSinkInternal&& other); void InternalCleanup(); enum class SinkType { GENERIC, DIAL, CAST };
diff --git a/chrome/common/media_router/discovery/media_sink_service_base.cc b/chrome/common/media_router/discovery/media_sink_service_base.cc index fc68861..a9536cd 100644 --- a/chrome/common/media_router/discovery/media_sink_service_base.cc +++ b/chrome/common/media_router/discovery/media_sink_service_base.cc
@@ -72,6 +72,21 @@ StartTimer(); } +void MediaSinkServiceBase::RemoveSinkById(const MediaSink::Id& sink_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto it = sinks_.find(sink_id); + if (it == sinks_.end()) + return; + + // Make a copy of the sink to avoid potential use-after-free. + MediaSinkInternal sink = it->second; + sinks_.erase(it); + for (auto& observer : observers_) + observer.OnSinkRemoved(sink); + + StartTimer(); +} + void MediaSinkServiceBase::SetTimerForTest( std::unique_ptr<base::OneShotTimer> timer) { discovery_timer_ = std::move(timer);
diff --git a/chrome/common/media_router/discovery/media_sink_service_base.h b/chrome/common/media_router/discovery/media_sink_service_base.h index fa7c038..71a4e84b 100644 --- a/chrome/common/media_router/discovery/media_sink_service_base.h +++ b/chrome/common/media_router/discovery/media_sink_service_base.h
@@ -63,6 +63,7 @@ // Also invokes |StartTimer()|. void AddOrUpdateSink(const MediaSinkInternal& sink); void RemoveSink(const MediaSinkInternal& sink); + void RemoveSinkById(const MediaSink::Id& sink_id); const base::flat_map<MediaSink::Id, MediaSinkInternal>& GetSinks() const; const MediaSinkInternal* GetSinkById(const MediaSink::Id& sink_id) const;
diff --git a/chrome/common/media_router/media_sink.cc b/chrome/common/media_router/media_sink.cc index fe05c1c..09b41997 100644 --- a/chrome/common/media_router/media_sink.cc +++ b/chrome/common/media_router/media_sink.cc
@@ -19,10 +19,12 @@ provider_id_(provider_id) {} MediaSink::MediaSink(const MediaSink& other) = default; +MediaSink::MediaSink(MediaSink&& other) noexcept = default; +MediaSink::MediaSink() = default; +MediaSink::~MediaSink() = default; -MediaSink::MediaSink() {} - -MediaSink::~MediaSink() {} +MediaSink& MediaSink::operator=(const MediaSink& other) = default; +MediaSink& MediaSink::operator=(MediaSink&& other) noexcept = default; bool MediaSink::Equals(const MediaSink& other) const { return sink_id_ == other.sink_id_;
diff --git a/chrome/common/media_router/media_sink.h b/chrome/common/media_router/media_sink.h index f47b68fc..f4b6f8c 100644 --- a/chrome/common/media_router/media_sink.h +++ b/chrome/common/media_router/media_sink.h
@@ -49,10 +49,13 @@ SinkIconType icon_type, MediaRouteProviderId provider_id = MediaRouteProviderId::UNKNOWN); MediaSink(const MediaSink& other); + MediaSink(MediaSink&& other) noexcept; MediaSink(); - ~MediaSink(); + MediaSink& operator=(const MediaSink& other); + MediaSink& operator=(MediaSink&& other) noexcept; + void set_sink_id(const MediaSink::Id& sink_id) { sink_id_ = sink_id; } const MediaSink::Id& id() const { return sink_id_; }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index b058385..e2bc910 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -504,8 +504,6 @@ "../browser/chrome_find_request_manager_browsertest.cc", "../browser/chrome_main_browsertest.cc", "../browser/chrome_navigation_browsertest.cc", - "../browser/chrome_network_service_browsertest.cc", - "../browser/chrome_network_service_restart_browsertest.cc", "../browser/chrome_origin_trials_browsertest.cc", "../browser/chrome_plugin_browsertest.cc", "../browser/chrome_security_exploit_browsertest.cc", @@ -621,6 +619,8 @@ "../browser/net/chrome_accept_header_browsertest.cc", "../browser/net/chrome_mojo_proxy_resolver_factory_browsertest.cc", "../browser/net/chrome_network_delegate_browsertest.cc", + "../browser/net/chrome_network_service_browsertest.cc", + "../browser/net/chrome_network_service_restart_browsertest.cc", "../browser/net/cookie_policy_browsertest.cc", "../browser/net/dns_probe_browsertest.cc", "../browser/net/errorpage_browsertest.cc",
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 1f5cc05..391d57b 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -113,6 +113,8 @@ 'ChromeDriverTest.testWindowMinimize', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2522 'ChromeDriverTest.testWindowMaximize', + # https://bugs.chromium.org/p/chromium/issues/detail?id=868376 + 'ChromeDriverTest.testHasFocusOnStartup', ] _DESKTOP_NEGATIVE_FILTER = [
diff --git a/chrome/test/data/navigation_predictor/anchors_different_area.html b/chrome/test/data/navigation_predictor/anchors_different_area.html new file mode 100644 index 0000000..c0daddb --- /dev/null +++ b/chrome/test/data/navigation_predictor/anchors_different_area.html
@@ -0,0 +1,11 @@ +<html> + <head> + </head> + <body> + <a id="small" href="https://example.com/2"><img height="2" width="2"></a> + <a id="xlarge" href="https://google.com"><img height="5" width="5"></a> + <a id="xmall" href="https://example.com/1"><img height="1" width="1"></a> + <a id="medium" href="https://example.com"><img height="3" width="3"></a> + <a id="large" href="https://dummy.com"><img height="4" width="4"></a> + </body> +</html> \ No newline at end of file
diff --git a/chrome/test/data/web_app_default_apps/bad_json/malformed0.json b/chrome/test/data/web_app_default_apps/bad_json/malformed0.json deleted file mode 100644 index 520f87f..0000000 --- a/chrome/test/data/web_app_default_apps/bad_json/malformed0.json +++ /dev/null
@@ -1 +0,0 @@ -This is not valid JSON.
diff --git a/chrome/test/data/web_app_default_apps/good_json/chrome_platform_status.json b/chrome/test/data/web_app_default_apps/good_json/chrome_platform_status.json deleted file mode 100644 index f5e81a7..0000000 --- a/chrome/test/data/web_app_default_apps/good_json/chrome_platform_status.json +++ /dev/null
@@ -1,4 +0,0 @@ -{ - "web_app_manifest_url": "https://www.chromestatus.com/static/manifest.json", - "web_app_start_url": "https://www.chromestatus.com/features" -}
diff --git a/chrome/test/data/web_app_default_apps/good_json/google_io_2016.json b/chrome/test/data/web_app_default_apps/good_json/google_io_2016.json deleted file mode 100644 index e7c5c10..0000000 --- a/chrome/test/data/web_app_default_apps/good_json/google_io_2016.json +++ /dev/null
@@ -1,4 +0,0 @@ -{ - "web_app_manifest_url": "https://events.google.com/io2016/manifest.json", - "web_app_start_url": "https://events.google.com/io2016/?utm_source=web_app_manifest" -}
diff --git a/chrome/test/data/web_app_default_apps/mixed_json/empty.json b/chrome/test/data/web_app_default_apps/mixed_json/empty.json deleted file mode 100644 index e69de29..0000000 --- a/chrome/test/data/web_app_default_apps/mixed_json/empty.json +++ /dev/null
diff --git a/chrome/test/data/web_app_default_apps/mixed_json/malformed1.json b/chrome/test/data/web_app_default_apps/mixed_json/malformed1.json deleted file mode 100644 index 10cce0e..0000000 --- a/chrome/test/data/web_app_default_apps/mixed_json/malformed1.json +++ /dev/null
@@ -1,5 +0,0 @@ -{ - "web_app_manifest_url": "https://www.chromestatus.com/static/manifest.json", - "web_app_start_url": "https://www.chromestatus.com/features", - "this is malformed JSON because there's no end quote -}
diff --git a/chrome/test/data/web_app_default_apps/mixed_json/polytimer.json b/chrome/test/data/web_app_default_apps/mixed_json/polytimer.json deleted file mode 100644 index 7858618..0000000 --- a/chrome/test/data/web_app_default_apps/mixed_json/polytimer.json +++ /dev/null
@@ -1,4 +0,0 @@ -{ - "web_app_manifest_url": "https://polytimer.rocks/manifest.json", - "web_app_start_url": "https://polytimer.rocks/?homescreen=1" -}
diff --git a/chrome/test/data/web_app_default_apps/txt_but_no_json/chrome_platform_status.txt b/chrome/test/data/web_app_default_apps/txt_but_no_json/chrome_platform_status.txt deleted file mode 100644 index f5e81a7..0000000 --- a/chrome/test/data/web_app_default_apps/txt_but_no_json/chrome_platform_status.txt +++ /dev/null
@@ -1,4 +0,0 @@ -{ - "web_app_manifest_url": "https://www.chromestatus.com/static/manifest.json", - "web_app_start_url": "https://www.chromestatus.com/features" -}
diff --git a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js index df9a05ba..486c5b0 100644 --- a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js +++ b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
@@ -884,3 +884,34 @@ function() { this.runMochaTest(destination_list_test.TestNames.FireDestinationSelected); }); + +PrintPreviewPrintButtonTest = class extends NewPrintPreviewTest { + /** @override */ + get browsePreload() { + return 'chrome://print/new/app.html'; + } + + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat([ + '../test_browser_proxy.js', + 'native_layer_stub.js', + 'plugin_stub.js', + 'print_preview_test_utils.js', + 'print_button_test.js', + ]); + } + + /** @override */ + get suiteName() { + return print_button_test.suiteName; + } +}; + +TEST_F('PrintPreviewPrintButtonTest', 'LocalPrintHidePreview', function() { + this.runMochaTest(print_button_test.TestNames.LocalPrintHidePreview); +}); + +TEST_F('PrintPreviewPrintButtonTest', 'PDFPrintVisiblePreview', function() { + this.runMochaTest(print_button_test.TestNames.PDFPrintVisiblePreview); +});
diff --git a/chrome/test/data/webui/print_preview/print_button_test.js b/chrome/test/data/webui/print_preview/print_button_test.js new file mode 100644 index 0000000..28a3d92 --- /dev/null +++ b/chrome/test/data/webui/print_preview/print_button_test.js
@@ -0,0 +1,140 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +cr.define('print_button_test', function() { + /** @enum {string} */ + const TestNames = { + LocalPrintHidePreview: 'local print hide preview', + PDFPrintVisiblePreview: 'pdf print visible preview', + }; + + const suiteName = 'PrintButtonTest'; + suite(suiteName, function() { + /** @type {?PrintPreviewAppElement} */ + let page = null; + + /** @type {?print_preview.NativeLayer} */ + let nativeLayer = null; + + /** @type {boolean} */ + let printBeforePreviewReady = false; + + /** @type {boolean} */ + let previewHidden = false; + + /** @type {!print_preview.NativeInitialSettings} */ + const initialSettings = + print_preview_test_utils.getDefaultInitialSettings(); + + /** @override */ + setup(function() { + nativeLayer = new print_preview.NativeLayerStub(); + print_preview.NativeLayer.setInstance(nativeLayer); + PolymerTest.clearBody(); + nativeLayer.setInitialSettings(initialSettings); + let localDestinationInfos = [ + {printerName: 'FooName', deviceName: 'FooDevice'}, + ]; + nativeLayer.setLocalDestinations(localDestinationInfos); + nativeLayer.setLocalDestinationCapabilities( + print_preview_test_utils.getCddTemplate( + initialSettings.printerName)); + nativeLayer.setLocalDestinationCapabilities( + print_preview_test_utils.getPdfPrinter()); + + const pluginProxy = new print_preview.PDFPluginStub(); + pluginProxy.setPluginCompatible(true); + print_preview_new.PluginProxy.setInstance(pluginProxy); + + page = document.createElement('print-preview-app'); + document.body.appendChild(page); + pluginProxy.setLoadCallback(() => { + // Print before calling previewArea.onPluginLoad_. This simulates the + // user clicking the print button while the preview is still loading, + // since previewArea.onPluginLoad_() indicates to the UI that the + // preview is ready. + if (printBeforePreviewReady) { + const header = page.$$('print-preview-header'); + const printButton = header.$$('.print'); + assertFalse(printButton.disabled); + printButton.click(); + } + + const previewArea = page.$.previewArea; + previewArea.onPluginLoad_(true); + }); + + previewHidden = false; + nativeLayer.whenCalled('hidePreview').then(() => { + previewHidden = true; + }); + }); + + function waitForInitialPreview() { + return nativeLayer.whenCalled('getInitialSettings') + .then(function() { + page.destinationStore_.startLoadDestinations( + print_preview.PrinterType.LOCAL_PRINTER); + // Wait for the preview request. + return Promise.all([ + nativeLayer.whenCalled('getPrinterCapabilities'), + nativeLayer.whenCalled('getPreview') + ]); + }); + } + + // Tests that hidePreview() is called before print() if a local printer is + // selected and the user clicks print while the preview is loading. + test(assert(TestNames.LocalPrintHidePreview), function() { + printBeforePreviewReady = true; + + return waitForInitialPreview().then(function() { + // Wait for the print request. + return nativeLayer.whenCalled('print'); + }).then(function(printTicket) { + assertTrue(previewHidden); + + // Verify that the printer name is correct. + assertEquals('FooDevice', JSON.parse(printTicket).deviceName); + return nativeLayer.whenCalled('dialogClose'); + }); + }); + + // Tests that hidePreview() is not called if Save as PDF is selected and + // the user clicks print while the preview is loading. + test(assert(TestNames.PDFPrintVisiblePreview), function() { + printBeforePreviewReady = false; + + return waitForInitialPreview().then(function() { + // Setup to print before the preview loads. + printBeforePreviewReady = true; + + // Select Save as PDF destination + const pdfDestination = page.destinationStore_.destinations().find( + d => d.id == 'Save as PDF'); + assertTrue(!!pdfDestination); + page.destinationStore_.selectDestination(pdfDestination); + + // Reload preview and wait for print. + return Promise.all([ + nativeLayer.whenCalled('getPrinterCapabilities'), + nativeLayer.whenCalled('getPreview'), + nativeLayer.whenCalled('print') + ]); + }).then(function(args) { + assertFalse(previewHidden); + + const printTicket = args[2]; + // Verify that the printer name is correct. + assertEquals('Save as PDF', JSON.parse(printTicket).deviceName); + return nativeLayer.whenCalled('dialogClose'); + }); + }); + }); + + return { + suiteName: suiteName, + TestNames: TestNames, + }; +});
diff --git a/chrome/test/data/webui/print_preview/print_preview_test_utils.js b/chrome/test/data/webui/print_preview/print_preview_test_utils.js index 8695eb0..34231067 100644 --- a/chrome/test/data/webui/print_preview/print_preview_test_utils.js +++ b/chrome/test/data/webui/print_preview/print_preview_test_utils.js
@@ -167,6 +167,38 @@ } /** + * @return {!print_preview.PrinterCapabilitiesResponse} The capabilities of + * the Save as PDF destination. + */ + function getPdfPrinter() { + return { + printer: { + deviceName: 'Save as PDF', + }, + capabilities: { + version: '1.0', + printer: { + page_orientation: { + option: [ + {type: 'AUTO', is_default: true}, {type: 'PORTRAIT'}, + {type: 'LANDSCAPE'} + ] + }, + color: {option: [{type: 'STANDARD_COLOR', is_default: true}]}, + media_size: { + option: [{ + name: 'NA_LETTER', + width_microns: 0, + height_microns: 0, + is_default: true + }] + } + } + } + }; + } + + /** * Get the default media size for |device|. * @param {!print_preview.PrinterCapabilitiesResponse} device * @return {{width_microns: number, @@ -259,5 +291,6 @@ getDestinations: getDestinations, getMediaSizeCapabilityWithCustomNames: getMediaSizeCapabilityWithCustomNames, + getPdfPrinter: getPdfPrinter, }; });
diff --git a/chrome/test/data/webui/print_preview/print_preview_tests.js b/chrome/test/data/webui/print_preview/print_preview_tests.js index cf7f030..e2352d0 100644 --- a/chrome/test/data/webui/print_preview/print_preview_tests.js +++ b/chrome/test/data/webui/print_preview/print_preview_tests.js
@@ -108,38 +108,6 @@ } /** - * @return {!print_preview.PrinterCapabilitiesResponse} The capabilities of - * the Save as PDF destination. - */ - function getPdfPrinter() { - return { - printer: { - deviceName: 'Save as PDF', - }, - capabilities: { - version: '1.0', - printer: { - page_orientation: { - option: [ - {type: 'AUTO', is_default: true}, {type: 'PORTRAIT'}, - {type: 'LANDSCAPE'} - ] - }, - color: {option: [{type: 'STANDARD_COLOR', is_default: true}]}, - media_size: { - option: [{ - name: 'NA_LETTER', - width_microns: 0, - height_microns: 0, - is_default: true - }] - } - } - } - }; - } - - /** * Gets a serialized app state string with some non-default values. * @return {string} */ @@ -618,7 +586,8 @@ initialSettings.printerName = 'Save as PDF'; // Set PDF printer - nativeLayer.setLocalDestinationCapabilities(getPdfPrinter()); + nativeLayer.setLocalDestinationCapabilities( + print_preview_test_utils.getPdfPrinter()); setInitialSettings(); return nativeLayer.whenCalled('getInitialSettings') @@ -1661,7 +1630,7 @@ // Test that Mac "Open PDF in Preview" link is treated correctly as a // local printer. See crbug.com/741341 and crbug.com/741528 test('MacOpenPDFInPreview', function() { - const device = getPdfPrinter(); + const device = print_preview_test_utils.getPdfPrinter(); initialSettings.printerName = device.printer.deviceName; return setupSettingsAndDestinationsWithCapabilities(device) .then(function() { @@ -1691,7 +1660,7 @@ // Test that the OpenPDFInPreview link is correctly disabled when the // print ticket is invalid. test('MacOpenPDFInPreviewBadPrintTicket', function() { - const device = getPdfPrinter(); + const device = print_preview_test_utils.getPdfPrinter(); initialSettings.printerName = device.printer.deviceName; const openPdfPreviewLink = $('open-pdf-in-preview-link'); return Promise
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index c6f4ab2..4e635502 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -2097,3 +2097,31 @@ mocha.run(); }); GEN('#endif // defined(OS_CHROMEOS)'); + +/** + * Test fixture for FindShortcutBehavior. + * @constructor + * @extends {CrSettingsBrowserTest} + */ +function CrSettingsFindShortcutBehavior() {} + +CrSettingsFindShortcutBehavior.prototype = { + __proto__: CrSettingsBrowserTest.prototype, + + /** + * Preload a module that depends on both cr-dialog and FindShortcutBehavior. + * cr-dialog is used in the tests. + * @override + */ + browsePreload: 'chrome://settings/languages_page/add_languages_dialog.html', + + /** @override */ + extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ + 'test_util.js', + 'find_shortcut_behavior_test.js', + ]), +}; + +TEST_F('CrSettingsFindShortcutBehavior', 'All', function() { + mocha.run(); +});
diff --git a/chrome/test/data/webui/settings/device_page_tests.js b/chrome/test/data/webui/settings/device_page_tests.js index 3ef75e1..3e2fd9f 100644 --- a/chrome/test/data/webui/settings/device_page_tests.js +++ b/chrome/test/data/webui/settings/device_page_tests.js
@@ -611,21 +611,45 @@ expectFalse(!!keyboardPage.$$('#diamondKey')); // Pretend the diamond key is available. - let showCapsLock = false; - const showDiamondKey = true; - cr.webUIListenerCallback( - 'show-keys-changed', showCapsLock, showDiamondKey); + let keyboardParams = { + 'showCapsLock': false, + 'showDiamondKey': true, + 'showExternalMetaKey': false, + 'showAppleCommandKey': false, + }; + cr.webUIListenerCallback('show-keys-changed', keyboardParams); Polymer.dom.flush(); expectFalse(!!keyboardPage.$$('#capsLockKey')); expectTrue(!!keyboardPage.$$('#diamondKey')); + expectFalse(!!keyboardPage.$$('#externalMetaKey')); + expectFalse(!!keyboardPage.$$('#externalCommandKey')); // Pretend a Caps Lock key is now available. - showCapsLock = true; - cr.webUIListenerCallback( - 'show-keys-changed', showCapsLock, showDiamondKey); + keyboardParams['showCapsLock'] = true; + cr.webUIListenerCallback('show-keys-changed', keyboardParams); Polymer.dom.flush(); expectTrue(!!keyboardPage.$$('#capsLockKey')); expectTrue(!!keyboardPage.$$('#diamondKey')); + expectFalse(!!keyboardPage.$$('#externalMetaKey')); + expectFalse(!!keyboardPage.$$('#externalCommandKey')); + + // Add a non-Apple external keyboard. + keyboardParams['showExternalMetaKey'] = true; + cr.webUIListenerCallback('show-keys-changed', keyboardParams); + Polymer.dom.flush(); + expectTrue(!!keyboardPage.$$('#capsLockKey')); + expectTrue(!!keyboardPage.$$('#diamondKey')); + expectTrue(!!keyboardPage.$$('#externalMetaKey')); + expectFalse(!!keyboardPage.$$('#externalCommandKey')); + + // Add an Apple keyboard. + keyboardParams['showAppleCommandKey'] = true; + cr.webUIListenerCallback('show-keys-changed', keyboardParams); + Polymer.dom.flush(); + expectTrue(!!keyboardPage.$$('#capsLockKey')); + expectTrue(!!keyboardPage.$$('#diamondKey')); + expectTrue(!!keyboardPage.$$('#externalMetaKey')); + expectTrue(!!keyboardPage.$$('#externalCommandKey')); const collapse = keyboardPage.$$('iron-collapse'); assertTrue(!!collapse);
diff --git a/chrome/test/data/webui/settings/find_shortcut_behavior_test.js b/chrome/test/data/webui/settings/find_shortcut_behavior_test.js new file mode 100644 index 0000000..bd2ba29 --- /dev/null +++ b/chrome/test/data/webui/settings/find_shortcut_behavior_test.js
@@ -0,0 +1,152 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +suite('find-shortcut', () => { + /** @typedef {{ + * becomeActiveFindShortcutListener: !Function, + * removeSelfAsFindShortcutListener: !Function, + * }} + */ + let Listener; + + /** + * @type {PromiseResolver<!{modalContextOpen: boolean, self: HTMLElement}>} + */ + let waits; + /** @type {number} */ + let nextWait; + + /** + * @param {!Array} fns + * @return {!Promise} + */ + const promiseSeries = fns => + fns.reduce((acc, fn) => acc.then(fn), Promise.resolve()); + + /** + * @param {!HTMLElement} testElement + * @return {!function(!Function)): !Promise} + */ + const listenScope = testElement => wrapped => promiseSeries([ + () => testElement.becomeActiveFindShortcutListener(), + wrapped, + () => testElement.removeSelfAsFindShortcutListener(), + ]); + + /** + * @param {!Array<!HTMLElement>} expectedSelves + * @param {?boolean} expectedModalContextOpen + * @return {!Promise} + */ + const checkMultiple = (expectedSelves, expectedModalContextOpen) => { + waits = expectedSelves.map(() => new PromiseResolver()); + nextWait = 0; + MockInteractions.pressAndReleaseKeyOn( + window, 70, cr.isMac ? 'meta' : 'ctrl', 'f'); + return Promise.all(waits.map(wait => wait.promise)).then(argss => { + argss.forEach((args, index) => { + assertEquals(expectedSelves[index], args.self); + assertEquals(!!expectedModalContextOpen, args.modalContextOpen); + }); + }); + }; + + /** + * @param {!HTMLElement} expectedSelf + * @param {?boolean} expectedModalContextOpen + * @return {!Promise} + */ + const check = (expectedSelf, expectedModalContextOpen) => + checkMultiple([expectedSelf], expectedModalContextOpen); + + /** + * @param {!HTMLElement} expectedSelf + * @param {?boolean} expectedModalContextOpen + * @return {!Promise} + */ + const wrappedCheck = (expectedSelf, expectedModalContextOpen) => listenScope( + expectedSelf)(() => check(expectedSelf, expectedModalContextOpen)); + + suiteSetup(() => { + document.body.innerHTML = ` + <dom-module id="find-shortcut-element"> + <template></template> + </dom-module> + `; + + Polymer({ + is: 'find-shortcut-element', + behaviors: [settings.FindShortcutBehavior], + + handledResponse: true, + + handleFindShortcut(modalContextOpen) { + assert(nextWait < waits.length); + waits[nextWait++].resolve({modalContextOpen, self: this}); + return this.handledResponse; + }, + }); + }); + + setup(() => { + PolymerTest.clearBody(); + }); + + test('no listeners are okay', () => checkMultiple([])); + + test('handled', () => { + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + const testElement = document.body.querySelector('find-shortcut-element'); + return wrappedCheck(testElement); + }); + + test('handled with modal context open', () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <cr-dialog></cr-dialog>`; + const testElement = document.body.querySelector('find-shortcut-element'); + const dialog = document.body.querySelector('cr-dialog'); + dialog.showModal(); + return wrappedCheck(testElement, true); + }); + + test('handled with modal context closed', () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <cr-dialog></cr-dialog>`; + const testElement = document.body.querySelector('find-shortcut-element'); + const dialog = document.body.querySelector('cr-dialog'); + dialog.showModal(); + assertTrue(dialog.open); + const whenCloseFired = test_util.eventToPromise('close', dialog); + dialog.close(); + return whenCloseFired.then(() => wrappedCheck(testElement)); + }); + + test('last listener is active', () => { + document.body.innerHTML = ` + <find-shortcut-element></find-shortcut-element> + <find-shortcut-element></find-shortcut-element>`; + const testElements = + document.body.querySelectorAll('find-shortcut-element'); + return promiseSeries([ + () => listenScope(testElements[0])(() => wrappedCheck(testElements[1])), + () => listenScope(testElements[1])(() => wrappedCheck(testElements[0])), + ]); + }); + + test('removing self when not active throws exception', () => { + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + const testElement = document.body.querySelector('find-shortcut-element'); + assertThrows(() => testElement.removeSelfAsFindShortcutListener()); + }); + + test('becoming active when already active throws exception', () => { + document.body.innerHTML = `<find-shortcut-element></find-shortcut-element>`; + const testElement = document.body.querySelector('find-shortcut-element'); + return listenScope(testElement)(() => { + assertThrows(() => testElement.becomeActiveFindShortcutListener()); + }); + }); +});
diff --git a/chrome/test/data/webui/settings/settings_ui_browsertest.js b/chrome/test/data/webui/settings/settings_ui_browsertest.js index 700bc99..a2d17cd 100644 --- a/chrome/test/data/webui/settings/settings_ui_browsertest.js +++ b/chrome/test/data/webui/settings/settings_ui_browsertest.js
@@ -166,21 +166,6 @@ urlParams = settings.getQueryParameters(); assertFalse(urlParams.has('search')); }); - - test('find shortcut', function() { - document.body.focus(); - assertTrue(ui.canHandleFindShortcut()); - - ui.handleFindShortcut(); - assertTrue(ui.$$('cr-toolbar').getSearchField().isSearchFocused()); - - const whenDialogOpen = test_util.eventToPromise('cr-dialog-open', ui); - settings.navigateTo(settings.routes.RESET_DIALOG); - - return whenDialogOpen.then(function() { - assertFalse(ui.canHandleFindShortcut()); - }); - }); }); mocha.run();
diff --git a/chromecast/system/reboot/reboot_util.h b/chromecast/system/reboot/reboot_util.h index 3f5179d..21dd79e5c 100644 --- a/chromecast/system/reboot/reboot_util.h +++ b/chromecast/system/reboot/reboot_util.h
@@ -45,12 +45,14 @@ static bool IsOtaForNextRebootSupported(); static void SetOtaForNextReboot(); - // These are used for logging/metrics purposes. In general, setting the last + // Returns last reboot source. This value persists throughout each boot. + static RebootShlib::RebootSource GetLastRebootSource(); + + // This is used for logging/metrics purposes. In general, setting the next // reboot type is handled automatically by RebootUtil, so it should not // be necessary to set explicitly. - static RebootShlib::RebootSource GetLastRebootSource(); // Returns true if successful. - static bool SetLastRebootSource(RebootShlib::RebootSource reboot_source); + static bool SetNextRebootSource(RebootShlib::RebootSource reboot_source); using RebootCallback = base::RepeatingCallback<bool(RebootShlib::RebootSource)>;
diff --git a/chromecast/system/reboot/reboot_util_core.cc b/chromecast/system/reboot/reboot_util_core.cc index c0aed49b..4d57445d 100644 --- a/chromecast/system/reboot/reboot_util_core.cc +++ b/chromecast/system/reboot/reboot_util_core.cc
@@ -55,7 +55,7 @@ // If we have a testing callback avoid calling RebootShlib::RebootNow // because it will crash our test RebootUtil::RebootCallback& callback = GetTestRebootCallback(); - SetLastRebootSource(reboot_source); + SetNextRebootSource(reboot_source); if (callback) { LOG(WARNING) << "Using reboot callback for test! Device will not reboot!"; return callback.Run(reboot_source);
diff --git a/chromecast/system/reboot/reboot_util_dummy.cc b/chromecast/system/reboot/reboot_util_dummy.cc index b216f861..5de5adf 100644 --- a/chromecast/system/reboot/reboot_util_dummy.cc +++ b/chromecast/system/reboot/reboot_util_dummy.cc
@@ -22,7 +22,7 @@ } // static -bool RebootUtil::SetLastRebootSource( +bool RebootUtil::SetNextRebootSource( RebootShlib::RebootSource /* reboot_source */) { return false; }
diff --git a/chromecast/system/reboot/reboot_util_test.cc b/chromecast/system/reboot/reboot_util_test.cc index 66045fe..7b02c79 100644 --- a/chromecast/system/reboot/reboot_util_test.cc +++ b/chromecast/system/reboot/reboot_util_test.cc
@@ -9,30 +9,6 @@ namespace chromecast { -TEST(RebootUtil, SingleSetGetLastRebootSource) { - if (RebootUtil::SetLastRebootSource(RebootShlib::RebootSource::FORCED)) { - EXPECT_EQ(RebootUtil::GetLastRebootSource(), - RebootShlib::RebootSource::FORCED); - } -} - -TEST(RebootUtil, MultipleSetGetLastRebootSource) { - if (RebootUtil::SetLastRebootSource(RebootShlib::RebootSource::FORCED)) { - EXPECT_EQ(RebootUtil::GetLastRebootSource(), - RebootShlib::RebootSource::FORCED); - } - - if (RebootUtil::SetLastRebootSource(RebootShlib::RebootSource::OTA)) { - EXPECT_EQ(RebootUtil::GetLastRebootSource(), - RebootShlib::RebootSource::OTA); - } - - if (RebootUtil::SetLastRebootSource(RebootShlib::RebootSource::FDR)) { - EXPECT_EQ(RebootUtil::GetLastRebootSource(), - RebootShlib::RebootSource::FDR); - } -} - // Ensure that we can call RebootNow during a test without crashing // and that it properly keeps track of the reboot source. TEST(RebootUtil, CaptureReboot) {
diff --git a/chromeos/components/nearby/BUILD.gn b/chromeos/components/nearby/BUILD.gn index 07b777a..779b8d43 100644 --- a/chromeos/components/nearby/BUILD.gn +++ b/chromeos/components/nearby/BUILD.gn
@@ -11,6 +11,8 @@ "hash_utils_impl.cc", "hash_utils_impl.h", "settable_future_impl.h", + "system_clock_impl.cc", + "system_clock_impl.h", "thread_utils_impl.cc", "thread_utils_impl.h", ]
diff --git a/chromeos/components/nearby/library/BUILD.gn b/chromeos/components/nearby/library/BUILD.gn index 367c8ed..3a96ebb1 100644 --- a/chromeos/components/nearby/library/BUILD.gn +++ b/chromeos/components/nearby/library/BUILD.gn
@@ -12,6 +12,7 @@ "future.h", "hash_utils.h", "settable_future.h", + "system_clock.h", "thread_utils.h", ]
diff --git a/chromeos/components/nearby/library/system_clock.h b/chromeos/components/nearby/library/system_clock.h new file mode 100644 index 0000000..dd48d1fe --- /dev/null +++ b/chromeos/components/nearby/library/system_clock.h
@@ -0,0 +1,26 @@ +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_NEARBY_LIBRARY_SYSTEM_CLOCK_H_ +#define CHROMEOS_COMPONENTS_NEARBY_LIBRARY_SYSTEM_CLOCK_H_ + +#include <cstdint> + +namespace location { +namespace nearby { + +class SystemClock { + public: + virtual ~SystemClock() {} + + // Returns the time since the system was booted, and includes deep sleep. This + // clock should be guaranteed to be monotonic, and should continue to tick + // even when the CPU is in power saving modes. + virtual std::int64_t elapsedRealtime() = 0; +}; + +} // namespace nearby +} // namespace location + +#endif // CHROMEOS_COMPONENTS_NEARBY_LIBRARY_SYSTEM_CLOCK_H_
diff --git a/chromeos/components/nearby/system_clock_impl.cc b/chromeos/components/nearby/system_clock_impl.cc new file mode 100644 index 0000000..db68c29 --- /dev/null +++ b/chromeos/components/nearby/system_clock_impl.cc
@@ -0,0 +1,26 @@ +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/nearby/system_clock_impl.h" + +#include "base/sys_info.h" + +namespace chromeos { + +namespace nearby { + +SystemClockImpl::SystemClockImpl() = default; + +SystemClockImpl::~SystemClockImpl() = default; + +int64_t SystemClockImpl::elapsedRealtime() { + // TODO(kyleqian): The POSIX implementation of base::SysInfo::Uptime() + // currently does not include time spent suspended. See + // https://crbug.com/166153. + return base::SysInfo::Uptime().InMilliseconds(); +} + +} // namespace nearby + +} // namespace chromeos
diff --git a/chromeos/components/nearby/system_clock_impl.h b/chromeos/components/nearby/system_clock_impl.h new file mode 100644 index 0000000..7f785c96e --- /dev/null +++ b/chromeos/components/nearby/system_clock_impl.h
@@ -0,0 +1,32 @@ +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_NEARBY_SYSTEM_CLOCK_IMPL_H_ +#define CHROMEOS_COMPONENTS_NEARBY_SYSTEM_CLOCK_IMPL_H_ + +#include "base/macros.h" +#include "chromeos/components/nearby/library/system_clock.h" + +namespace chromeos { + +namespace nearby { + +// Concrete location::nearby::SystemClock implementation. +class SystemClockImpl : public location::nearby::SystemClock { + public: + SystemClockImpl(); + ~SystemClockImpl() override; + + private: + // location::nearby::SystemClock: + int64_t elapsedRealtime() override; + + DISALLOW_COPY_AND_ASSIGN(SystemClockImpl); +}; + +} // namespace nearby + +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_NEARBY_SYSTEM_CLOCK_IMPL_H_
diff --git a/chromeos/dbus/fake_machine_learning_client.cc b/chromeos/dbus/fake_machine_learning_client.cc index b4392e2..2996828 100644 --- a/chromeos/dbus/fake_machine_learning_client.cc +++ b/chromeos/dbus/fake_machine_learning_client.cc
@@ -15,7 +15,7 @@ void FakeMachineLearningClient::BootstrapMojoConnection( base::ScopedFD fd, base::OnceCallback<void(bool success)> result_callback) { - const bool success = false; + const bool success = true; std::move(result_callback).Run(success); }
diff --git a/chromeos/dbus/services/proxy_resolution_service_provider.cc b/chromeos/dbus/services/proxy_resolution_service_provider.cc index c9bb074f..0b96b55 100644 --- a/chromeos/dbus/services/proxy_resolution_service_provider.cc +++ b/chromeos/dbus/services/proxy_resolution_service_provider.cc
@@ -50,6 +50,9 @@ // this request. const scoped_refptr<net::URLRequestContextGetter> context_getter; + // Handle to ProxyResolutionService's Request + std::unique_ptr<net::ProxyResolutionService::Request> request; + // ProxyInfo resolved for |source_url|. net::ProxyInfo proxy_info; @@ -160,7 +163,7 @@ << request_ptr->source_url; const int result = proxy_resolution_service->ResolveProxy( GURL(request_ptr->source_url), std::string(), &request_ptr->proxy_info, - callback, nullptr, nullptr, net::NetLogWithSource()); + callback, &request_ptr->request, nullptr, net::NetLogWithSource()); if (result != net::ERR_IO_PENDING) { VLOG(1) << "Network proxy resolution completed synchronously."; callback.Run(result);
diff --git a/chromeos/services/BUILD.gn b/chromeos/services/BUILD.gn index 047dc25..9e91de61 100644 --- a/chromeos/services/BUILD.gn +++ b/chromeos/services/BUILD.gn
@@ -22,6 +22,7 @@ testonly = true deps = [ "//chromeos/services/device_sync:unit_tests", + "//chromeos/services/machine_learning/public/cpp:unit_tests", "//chromeos/services/multidevice_setup:unit_tests", "//chromeos/services/secure_channel:unit_tests", ]
diff --git a/chromeos/services/machine_learning/DEPS b/chromeos/services/machine_learning/DEPS index b5a57d6..2e2e8d99 100644 --- a/chromeos/services/machine_learning/DEPS +++ b/chromeos/services/machine_learning/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+chromeos/dbus", + "+mojo/core/embedder", "+mojo/public", ]
diff --git a/chromeos/services/machine_learning/public/cpp/BUILD.gn b/chromeos/services/machine_learning/public/cpp/BUILD.gn index d714aa3..868c98e 100644 --- a/chromeos/services/machine_learning/public/cpp/BUILD.gn +++ b/chromeos/services/machine_learning/public/cpp/BUILD.gn
@@ -15,3 +15,19 @@ "//chromeos/services/machine_learning/public/mojom", ] } + +source_set("unit_tests") { + testonly = true + sources = [ + "service_connection_unittest.cc", + ] + deps = [ + ":cpp", + "//base/test:test_support", + "//chromeos", + "//chromeos/services/machine_learning/public/mojom", + "//mojo/core/embedder", + "//mojo/public/cpp/bindings", + "//testing/gtest", + ] +}
diff --git a/chromeos/services/machine_learning/public/cpp/service_connection.cc b/chromeos/services/machine_learning/public/cpp/service_connection.cc index ed89eed8..3a2e604 100644 --- a/chromeos/services/machine_learning/public/cpp/service_connection.cc +++ b/chromeos/services/machine_learning/public/cpp/service_connection.cc
@@ -7,7 +7,7 @@ #include "base/no_destructor.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/machine_learning_client.h" -#include "chromeos/services/machine_learning/public/mojom/interface.mojom.h" +#include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h" #include "mojo/public/cpp/platform/platform_channel.h" #include "mojo/public/cpp/system/invitation.h" #include "third_party/cros_system_api/dbus/service_constants.h"
diff --git a/chromeos/services/machine_learning/public/cpp/service_connection.h b/chromeos/services/machine_learning/public/cpp/service_connection.h index 6345ea9..da57df94 100644 --- a/chromeos/services/machine_learning/public/cpp/service_connection.h +++ b/chromeos/services/machine_learning/public/cpp/service_connection.h
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "base/no_destructor.h" #include "base/sequence_checker.h" -#include "chromeos/services/machine_learning/public/mojom/interface.mojom.h" +#include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h" namespace chromeos { namespace machine_learning {
diff --git a/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc b/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc new file mode 100644 index 0000000..7ed2d7d --- /dev/null +++ b/chromeos/services/machine_learning/public/cpp/service_connection_unittest.cc
@@ -0,0 +1,52 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/machine_learning/public/cpp/service_connection.h" + +#include "base/macros.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h" +#include "mojo/core/embedder/embedder.h" +#include "mojo/core/embedder/scoped_ipc_support.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { +namespace machine_learning { +namespace { + +class ServiceConnectionTest : public testing::Test { + public: + ServiceConnectionTest() = default; + + protected: + static void SetUpTestCase() { + DBusThreadManager::Initialize(); + + static base::Thread ipc_thread("ipc"); + ipc_thread.StartWithOptions( + base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + static mojo::core::ScopedIPCSupport ipc_support( + ipc_thread.task_runner(), + mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN); + } + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; + + DISALLOW_COPY_AND_ASSIGN(ServiceConnectionTest); +}; + +// Tests that BindModelProvider runs OK (no crash) in a basic Mojo environment. +TEST_F(ServiceConnectionTest, BindModelProvider) { + mojom::ModelProviderPtr model_provider; + ServiceConnection::GetInstance()->BindModelProvider( + mojo::MakeRequest(&model_provider)); +} + +} // namespace +} // namespace machine_learning +} // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/public/cpp/prefs.cc b/chromeos/services/multidevice_setup/public/cpp/prefs.cc index a616ff2..341943ff 100644 --- a/chromeos/services/multidevice_setup/public/cpp/prefs.cc +++ b/chromeos/services/multidevice_setup/public/cpp/prefs.cc
@@ -10,11 +10,27 @@ namespace multidevice_setup { -const char kMultiDeviceSuiteEnabledPrefName[] = - "multidevice_setup.enable_feature_suite"; +// Note that the pref names have slightly inconsistent naming conventions +// because some were named before the unified MultiDeviceSetup project and we +// wanted to avoid changing the internal names of existing prefs. The general +// naming pattern for each individual feature enabling pref moving forward +// should be of the form +// const char k[FeatureName]FeatureEnabledPrefName = +// "multidevice_setup.[feature_name]_enabled"; + +// This pref is a gatekeeper for all MultiDevice features (e.g. Easy Unlock, +// Instant Tethering). Setting the pref to 'true' is necessary but not +// sufficient to enable the individual features, which are each controlled by +// their own pref and may involve additional setup steps. +const char kSuiteEnabledPrefName[] = "multidevice_setup.suite_enabled"; + +// Individual feature prefs. +const char kAndroidMessagesFeatureEnabledPrefName[] = + "multidevice.sms_connect_enabled"; void RegisterFeaturePrefs(PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(kMultiDeviceSuiteEnabledPrefName, false); + registry->RegisterBooleanPref(kSuiteEnabledPrefName, false); + registry->RegisterBooleanPref(kAndroidMessagesFeatureEnabledPrefName, false); } } // namespace multidevice_setup
diff --git a/chromeos/services/multidevice_setup/public/cpp/prefs.h b/chromeos/services/multidevice_setup/public/cpp/prefs.h index 781e89cb..1d8ddfac 100644 --- a/chromeos/services/multidevice_setup/public/cpp/prefs.h +++ b/chromeos/services/multidevice_setup/public/cpp/prefs.h
@@ -11,11 +11,8 @@ namespace multidevice_setup { -// This pref is a gatekeeper for all MultiDevice features (e.g. Easy Unlock, -// Instant Tethering). Setting the pref to 'true' is necessary but not -// sufficient to enable the individual features, which are each controlled by -// their own pref and may involve additional setup steps. -extern const char kMultiDeviceSuiteEnabledPrefName[]; +extern const char kSuiteEnabledPrefName[]; +extern const char kAndroidMessagesFeatureEnabledPrefName[]; void RegisterFeaturePrefs(PrefRegistrySimple* registry);
diff --git a/components/arc/arc_prefs.cc b/components/arc/arc_prefs.cc index 9e44f23..c96e15a0 100644 --- a/components/arc/arc_prefs.cc +++ b/components/arc/arc_prefs.cc
@@ -89,9 +89,6 @@ // Integer pref indicating the ecryptfs to ext4 migration strategy. One of // options: forbidden = 0, migrate = 1, wipe = 2 or ask the user = 3. const char kEcryptfsMigrationStrategy[] = "ecryptfs_migration_strategy"; -// A preference that indicates whether the SMS Connect feature is enabled. -const char kSmsConnectEnabled[] = "multidevice.sms_connect_enabled"; - // A preference that indicates the user has accepted voice interaction activity // control settings. const char kVoiceInteractionActivityControlAccepted[] = @@ -147,7 +144,6 @@ registry->RegisterBooleanPref(kArcTermsAccepted, false); registry->RegisterBooleanPref(kArcTermsShownInOobe, false); registry->RegisterBooleanPref(kArcVoiceInteractionValuePropAccepted, false); - registry->RegisterBooleanPref(kSmsConnectEnabled, true); registry->RegisterBooleanPref(kVoiceInteractionContextEnabled, false); registry->RegisterBooleanPref(kVoiceInteractionEnabled, false); registry->RegisterBooleanPref(kVoiceInteractionHotwordEnabled, false);
diff --git a/components/arc/arc_prefs.h b/components/arc/arc_prefs.h index 9a43759c..d7accf8 100644 --- a/components/arc/arc_prefs.h +++ b/components/arc/arc_prefs.h
@@ -38,7 +38,6 @@ ARC_EXPORT extern const char kArcCompatibleFilesystemChosen[]; ARC_EXPORT extern const char kArcVoiceInteractionValuePropAccepted[]; ARC_EXPORT extern const char kEcryptfsMigrationStrategy[]; -ARC_EXPORT extern const char kSmsConnectEnabled[]; // TODO(b/110211045): Move Assistant related prefs to ash. ARC_EXPORT extern const char kVoiceInteractionActivityControlAccepted[];
diff --git a/components/arc/volume_mounter/arc_volume_mounter_bridge.cc b/components/arc/volume_mounter/arc_volume_mounter_bridge.cc index fbaebba..d8148cb 100644 --- a/components/arc/volume_mounter/arc_volume_mounter_bridge.cc +++ b/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
@@ -77,38 +77,6 @@ weak_ptr_factory_.GetWeakPtr())); } -void ArcVolumeMounterBridge::OnAutoMountableDiskEvent( - chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk& disk) { - // Ignored. DiskEvents will be maintained in Vold during MountEvents. -} - -void ArcVolumeMounterBridge::OnBootDeviceDiskEvent( - chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk& disk) { - // Ignored. ARC doesn't care about boot device disk events. -} - -void ArcVolumeMounterBridge::OnDeviceEvent( - chromeos::disks::DiskMountManager::DeviceEvent event, - const std::string& device_path) { - // Ignored. ARC doesn't care about events other than Disk and Mount events. -} - -void ArcVolumeMounterBridge::OnFormatEvent( - chromeos::disks::DiskMountManager::FormatEvent event, - chromeos::FormatError error_code, - const std::string& device_path) { - // Ignored. ARC doesn't care about events other than Disk and Mount events. -} - -void ArcVolumeMounterBridge::OnRenameEvent( - chromeos::disks::DiskMountManager::RenameEvent event, - chromeos::RenameError error_code, - const std::string& device_path) { - // Ignored. ARC doesn't care about events other than Disk and Mount events. -} - void ArcVolumeMounterBridge::OnMountEvent( DiskMountManager::MountEvent event, chromeos::MountError error_code,
diff --git a/components/arc/volume_mounter/arc_volume_mounter_bridge.h b/components/arc/volume_mounter/arc_volume_mounter_bridge.h index 654cefa..6da3adde 100644 --- a/components/arc/volume_mounter/arc_volume_mounter_bridge.h +++ b/components/arc/volume_mounter/arc_volume_mounter_bridge.h
@@ -44,24 +44,10 @@ void OnConnectionReady() override; // chromeos::disks::DiskMountManager::Observer overrides: - void OnAutoMountableDiskEvent( - chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk& disk) override; - void OnBootDeviceDiskEvent( - chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk& disk) override; - void OnDeviceEvent(chromeos::disks::DiskMountManager::DeviceEvent event, - const std::string& device_path) override; void OnMountEvent(chromeos::disks::DiskMountManager::MountEvent event, chromeos::MountError error_code, const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) override; - void OnFormatEvent(chromeos::disks::DiskMountManager::FormatEvent event, - chromeos::FormatError error_code, - const std::string& device_path) override; - void OnRenameEvent(chromeos::disks::DiskMountManager::RenameEvent event, - chromeos::RenameError error_code, - const std::string& device_path) override; // mojom::VolumeMounterHost overrides: void RequestAllMountPoints() override;
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 3d80a38..4237918 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -1151,10 +1151,6 @@ driver->GetURLLoaderFactory(), client->GetPrefs(), client->GetIdentityManager(), - /*unmask_delegate=*/this, - // save_delegate starts out as nullptr and is set up by the - // CreditCardSaveManager owned by form_data_importer_. - /*save_delegate=*/nullptr, driver->IsIncognito())), app_locale_(app_locale), personal_data_(personal_data),
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index eda55e31..7733d20 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -71,7 +71,6 @@ // forms. One per frame; owned by the AutofillDriver. class AutofillManager : public AutofillHandler, public AutofillDownloadManager::Observer, - public payments::PaymentsClientUnmaskDelegate, public payments::FullCardRequest::ResultDelegate, public payments::FullCardRequest::UIDelegate { public: @@ -344,10 +343,10 @@ void OnLoadedServerPredictions( std::string response, const std::vector<std::string>& form_signatures) override; - - // payments::PaymentsClientUnmaskDelegate: + // Returns the real PAN retrieved from Payments. |real_pan| will be empty on + // failure. void OnDidGetRealPan(AutofillClient::PaymentsRpcResult result, - const std::string& real_pan) override; + const std::string& real_pan); // payments::FullCardRequest::ResultDelegate: void OnFullCardRequestSucceeded(
diff --git a/components/autofill/core/browser/credit_card_save_manager.cc b/components/autofill/core/browser/credit_card_save_manager.cc index 6c0d86a..838d343e 100644 --- a/components/autofill/core/browser/credit_card_save_manager.cc +++ b/components/autofill/core/browser/credit_card_save_manager.cc
@@ -78,11 +78,7 @@ payments_client_(payments_client), app_locale_(app_locale), personal_data_manager_(personal_data_manager), - weak_ptr_factory_(this) { - if (payments_client_) { - payments_client_->SetSaveDelegate(this); - } -} + weak_ptr_factory_(this) {} CreditCardSaveManager::~CreditCardSaveManager() {} @@ -104,7 +100,6 @@ // Abort the uploading if |payments_client_| is nullptr. if (!payments_client_) return; - payments_client_->SetSaveDelegate(this); upload_request_ = payments::PaymentsClient::UploadRequestDetails(); upload_request_.card = card; uploading_local_card_ = uploading_local_card; @@ -183,7 +178,9 @@ upload_request_.profiles, detected_values, base::UTF16ToASCII(CreditCard::StripSeparators(card.number())) .substr(0, 6), - upload_request_.active_experiments, app_locale_); + upload_request_.active_experiments, app_locale_, + base::BindOnce(&CreditCardSaveManager::OnDidGetUploadDetails, + weak_ptr_factory_.GetWeakPtr())); } bool CreditCardSaveManager::IsCreditCardUploadEnabled() { @@ -514,7 +511,9 @@ uploading_local_card_ ? AutofillMetrics::USER_ACCEPTED_UPLOAD_OF_LOCAL_CARD : AutofillMetrics::USER_ACCEPTED_UPLOAD_OF_NEW_CARD); - payments_client_->UploadCard(upload_request_); + payments_client_->UploadCard( + upload_request_, base::BindOnce(&CreditCardSaveManager::OnDidUploadCard, + weak_ptr_factory_.GetWeakPtr())); } AutofillMetrics::CardUploadDecisionMetric
diff --git a/components/autofill/core/browser/credit_card_save_manager.h b/components/autofill/core/browser/credit_card_save_manager.h index d966e3f..93d721e 100644 --- a/components/autofill/core/browser/credit_card_save_manager.h +++ b/components/autofill/core/browser/credit_card_save_manager.h
@@ -24,7 +24,7 @@ // Manages logic for determining whether upload credit card save to Google // Payments is available as well as actioning both local and upload credit card // save logic. Owned by FormDataImporter. -class CreditCardSaveManager : public payments::PaymentsClientSaveDelegate { +class CreditCardSaveManager { public: // Possible fields and values detected during credit card form submission, to // be sent to Google Payments to better determine if upload credit card save @@ -100,19 +100,22 @@ void SetAppLocale(std::string app_locale) { app_locale_ = app_locale; } protected: - // payments::PaymentsClientSaveDelegate: - // Exposed for testing. - void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, - const std::string& server_id) override; + // Returns the result of an upload request. If |result| == + // |AutofillClient::SUCCESS|, |server_id| may, optionally, contain the opaque + // identifier for the card on the server. Exposed for testing. + virtual void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, + const std::string& server_id); private: friend class SaveCardBubbleViewsBrowserTestBase; - // payments::PaymentsClientSaveDelegate: + // Returns the legal message retrieved from Payments. On failure or not + // meeting Payments's conditions for upload, |legal_message| will contain + // nullptr. void OnDidGetUploadDetails( AutofillClient::PaymentsRpcResult result, const base::string16& context_token, - std::unique_ptr<base::DictionaryValue> legal_message) override; + std::unique_ptr<base::DictionaryValue> legal_message); // Examines |card| and the stored profiles and if a candidate set of profiles // is found that matches the client-side validation rules, assigns the values
diff --git a/components/autofill/core/browser/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/credit_card_save_manager_unittest.cc index 51bdb565..a22f131d 100644 --- a/components/autofill/core/browser/credit_card_save_manager_unittest.cc +++ b/components/autofill/core/browser/credit_card_save_manager_unittest.cc
@@ -109,10 +109,7 @@ autofill_driver_->SetURLRequestContext(request_context_.get()); payments_client_ = new payments::TestPaymentsClient( autofill_driver_->GetURLLoaderFactory(), autofill_client_.GetPrefs(), - autofill_client_.GetIdentityManager(), - /*unmask_delegate=*/nullptr, - // Will be set by CreditCardSaveManager's ctor - /*save_delegate=*/nullptr); + autofill_client_.GetIdentityManager()); credit_card_save_manager_ = new TestCreditCardSaveManager(autofill_driver_.get(), &autofill_client_, payments_client_, &personal_data_); @@ -121,7 +118,6 @@ std::unique_ptr<CreditCardSaveManager>(credit_card_save_manager_), payments_client_)); autofill_manager_->SetExpectedObservedSubmission(true); - payments_client_->SetSaveDelegate(credit_card_save_manager_); } void TearDown() override {
diff --git a/components/autofill/core/browser/local_card_migration_manager.cc b/components/autofill/core/browser/local_card_migration_manager.cc index eb0372e..c197aa5b 100644 --- a/components/autofill/core/browser/local_card_migration_manager.cc +++ b/components/autofill/core/browser/local_card_migration_manager.cc
@@ -35,10 +35,7 @@ payments_client_(payments_client), app_locale_(app_locale), personal_data_manager_(personal_data_manager), - weak_ptr_factory_(this) { - if (payments_client_) - payments_client_->SetSaveDelegate(this); -} + weak_ptr_factory_(this) {} LocalCardMigrationManager::~LocalCardMigrationManager() {} @@ -86,7 +83,6 @@ // Abort the migration if |payments_client_| is nullptr. if (!payments_client_) return; - payments_client_->SetSaveDelegate(this); upload_request_ = payments::PaymentsClient::UploadRequestDetails(); // Payments server determines which version of the legal message to show based @@ -101,7 +97,9 @@ payments_client_->GetUploadDetails( upload_request_.profiles, GetDetectedValues(), /*pan_first_six=*/std::string(), upload_request_.active_experiments, - app_locale_); + app_locale_, + base::BindOnce(&LocalCardMigrationManager::OnDidGetUploadDetails, + weak_ptr_factory_.GetWeakPtr())); } // TODO(crbug.com/852904): Pops up a larger, modal dialog showing the local @@ -148,10 +146,6 @@ user_accepted_main_migration_dialog_ = true; } -void LocalCardMigrationManager::OnDidUploadCard( - AutofillClient::PaymentsRpcResult result, - const std::string& server_id) {} - int LocalCardMigrationManager::GetDetectedValues() const { int detected_values = 0;
diff --git a/components/autofill/core/browser/local_card_migration_manager.h b/components/autofill/core/browser/local_card_migration_manager.h index 12c3a210..621e03e3 100644 --- a/components/autofill/core/browser/local_card_migration_manager.h +++ b/components/autofill/core/browser/local_card_migration_manager.h
@@ -46,7 +46,7 @@ // Manages logic for determining whether migration of locally saved credit cards // to Google Payments is available as well as multiple local card uploading. // Owned by FormDataImporter. -class LocalCardMigrationManager : public payments::PaymentsClientSaveDelegate { +class LocalCardMigrationManager { public: // The parameters should outlive the LocalCardMigrationManager. LocalCardMigrationManager(AutofillClient* client, @@ -76,20 +76,13 @@ int GetDetectedValues() const; protected: - // payments::PaymentsClientSaveDelegate: // Callback after successfully getting the legal documents. On success, // displays the offer-to-migrate dialog, which the user can accept or not. - void OnDidGetUploadDetails( + // Exposed for testing. + virtual void OnDidGetUploadDetails( AutofillClient::PaymentsRpcResult result, const base::string16& context_token, - std::unique_ptr<base::DictionaryValue> legal_message) override; - - // payments::PaymentsClientSaveDelegate: - // Callback after a local card was uploaded. Starts the upload of the next - // local card if one exists. - // Exposed for testing. - void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, - const std::string& server_id) override; + std::unique_ptr<base::DictionaryValue> legal_message); // Check whether a local card is already a server card. bool IsServerCard(CreditCard* local_card) const;
diff --git a/components/autofill/core/browser/local_card_migration_manager_unittest.cc b/components/autofill/core/browser/local_card_migration_manager_unittest.cc index cb6124b..08577ffc 100644 --- a/components/autofill/core/browser/local_card_migration_manager_unittest.cc +++ b/components/autofill/core/browser/local_card_migration_manager_unittest.cc
@@ -68,9 +68,7 @@ autofill_driver_->SetURLRequestContext(request_context_.get()); payments_client_ = new payments::TestPaymentsClient( autofill_driver_->GetURLLoaderFactory(), autofill_client_.GetPrefs(), - autofill_client_.GetIdentityManager(), - /*unmask_delegate=*/nullptr, - /*save_delegate=*/nullptr); + autofill_client_.GetIdentityManager()); credit_card_save_manager_ = new TestCreditCardSaveManager(autofill_driver_.get(), &autofill_client_, payments_client_, &personal_data_);
diff --git a/components/autofill/core/browser/payments/full_card_request.cc b/components/autofill/core/browser/payments/full_card_request.cc index 9fab4b42..ba71e3c3 100644 --- a/components/autofill/core/browser/payments/full_card_request.cc +++ b/components/autofill/core/browser/payments/full_card_request.cc
@@ -131,7 +131,9 @@ void FullCardRequest::SendUnmaskCardRequest() { real_pan_request_timestamp_ = AutofillClock::Now(); - payments_client_->UnmaskCard(*request_); + payments_client_->UnmaskCard(*request_, + base::BindOnce(&FullCardRequest::OnDidGetRealPan, + weak_ptr_factory_.GetWeakPtr())); } void FullCardRequest::OnDidGetRealPan(AutofillClient::PaymentsRpcResult result,
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 03d1b3e..284f113 100644 --- a/components/autofill/core/browser/payments/full_card_request_unittest.cc +++ b/components/autofill/core/browser/payments/full_card_request_unittest.cc
@@ -66,8 +66,7 @@ }; // The test fixture for full card request. -class FullCardRequestTest : public testing::Test, - public PaymentsClientUnmaskDelegate { +class FullCardRequestTest : public testing::Test { public: FullCardRequestTest() : request_context_(new net::TestURLRequestContextGetter( @@ -82,7 +81,7 @@ autofill_client_.SetPrefs(std::move(pref_service)); payments_client_ = std::make_unique<PaymentsClient>( test_shared_loader_factory_, autofill_client_.GetPrefs(), - autofill_client_.GetIdentityManager(), this, nullptr); + autofill_client_.GetIdentityManager()); request_ = std::make_unique<FullCardRequest>( &autofill_client_, payments_client_.get(), &personal_data_); // Silence the warning from PaymentsClient about matching sync and Payments @@ -105,9 +104,8 @@ MockUIDelegate* ui_delegate() { return &ui_delegate_; } - // PaymentsClientUnmaskDelegate: void OnDidGetRealPan(AutofillClient::PaymentsRpcResult result, - const std::string& real_pan) override { + const std::string& real_pan) { request_->OnDidGetRealPan(result, real_pan); }
diff --git a/components/autofill/core/browser/payments/payments_client.cc b/components/autofill/core/browser/payments/payments_client.cc index 6785c518..58cd6962 100644 --- a/components/autofill/core/browser/payments/payments_client.cc +++ b/components/autofill/core/browser/payments/payments_client.cc
@@ -198,8 +198,9 @@ class UnmaskCardRequest : public PaymentsRequest { public: UnmaskCardRequest(const PaymentsClient::UnmaskRequestDetails& request_details, - PaymentsClientUnmaskDelegate* delegate) - : request_details_(request_details), delegate_(delegate) { + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> callback) + : request_details_(request_details), callback_(std::move(callback)) { DCHECK( CreditCard::MASKED_SERVER_CARD == request_details.card.record_type() || CreditCard::FULL_SERVER_CARD == request_details.card.record_type()); @@ -252,29 +253,34 @@ bool IsResponseComplete() override { return !real_pan_.empty(); } void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override { - delegate_->OnDidGetRealPan(result, real_pan_); + std::move(callback_).Run(result, real_pan_); } private: PaymentsClient::UnmaskRequestDetails request_details_; - PaymentsClientUnmaskDelegate* delegate_; + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> + callback_; std::string real_pan_; }; class GetUploadDetailsRequest : public PaymentsRequest { public: - GetUploadDetailsRequest(const std::vector<AutofillProfile>& addresses, - const int detected_values, - const std::string& pan_first_six, - const std::vector<const char*>& active_experiments, - const std::string& app_locale, - PaymentsClientSaveDelegate* delegate) + GetUploadDetailsRequest( + const std::vector<AutofillProfile>& addresses, + const int detected_values, + const std::string& pan_first_six, + const std::vector<const char*>& active_experiments, + const std::string& app_locale, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const base::string16&, + std::unique_ptr<base::DictionaryValue>)> callback) : addresses_(addresses), detected_values_(detected_values), pan_first_six_(pan_first_six), active_experiments_(active_experiments), app_locale_(app_locale), - delegate_(delegate) {} + callback_(std::move(callback)) {} ~GetUploadDetailsRequest() override {} std::string GetRequestUrlPath() override { @@ -331,8 +337,7 @@ } void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override { - delegate_->OnDidGetUploadDetails(result, context_token_, - std::move(legal_message_)); + std::move(callback_).Run(result, context_token_, std::move(legal_message_)); } private: @@ -341,7 +346,10 @@ const std::string pan_first_six_; const std::vector<const char*> active_experiments_; std::string app_locale_; - PaymentsClientSaveDelegate* delegate_; + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const base::string16&, + std::unique_ptr<base::DictionaryValue>)> + callback_; base::string16 context_token_; std::unique_ptr<base::DictionaryValue> legal_message_; }; @@ -349,8 +357,9 @@ class UploadCardRequest : public PaymentsRequest { public: UploadCardRequest(const PaymentsClient::UploadRequestDetails& request_details, - PaymentsClientSaveDelegate* delegate) - : request_details_(request_details), delegate_(delegate) {} + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> callback) + : request_details_(request_details), callback_(std::move(callback)) {} ~UploadCardRequest() override {} std::string GetRequestUrlPath() override { return kUploadCardRequestPath; } @@ -431,12 +440,14 @@ bool IsResponseComplete() override { return true; } void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override { - delegate_->OnDidUploadCard(result, server_id_); + std::move(callback_).Run(result, server_id_); } private: const PaymentsClient::UploadRequestDetails request_details_; - PaymentsClientSaveDelegate* delegate_; + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> + callback_; std::string server_id_; }; @@ -459,14 +470,10 @@ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, PrefService* pref_service, identity::IdentityManager* identity_manager, - PaymentsClientUnmaskDelegate* unmask_delegate, - PaymentsClientSaveDelegate* save_delegate, bool is_off_the_record) : url_loader_factory_(url_loader_factory), pref_service_(pref_service), identity_manager_(identity_manager), - unmask_delegate_(unmask_delegate), - save_delegate_(save_delegate), is_off_the_record_(is_off_the_record), has_retried_authorization_(false), weak_ptr_factory_(this) {} @@ -478,20 +485,16 @@ StartTokenFetch(false); } -void PaymentsClient::SetSaveDelegate( - PaymentsClientSaveDelegate* save_delegate) { - save_delegate_ = save_delegate; -} - PrefService* PaymentsClient::GetPrefService() const { return pref_service_; } void PaymentsClient::UnmaskCard( - const PaymentsClient::UnmaskRequestDetails& request_details) { - DCHECK(unmask_delegate_); + const PaymentsClient::UnmaskRequestDetails& request_details, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> callback) { IssueRequest( - std::make_unique<UnmaskCardRequest>(request_details, unmask_delegate_), + std::make_unique<UnmaskCardRequest>(request_details, std::move(callback)), true); } @@ -500,19 +503,22 @@ const int detected_values, const std::string& pan_first_six, const std::vector<const char*>& active_experiments, - const std::string& app_locale) { - DCHECK(save_delegate_); + const std::string& app_locale, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const base::string16&, + std::unique_ptr<base::DictionaryValue>)> callback) { IssueRequest(std::make_unique<GetUploadDetailsRequest>( addresses, detected_values, pan_first_six, - active_experiments, app_locale, save_delegate_), + active_experiments, app_locale, std::move(callback)), false); } void PaymentsClient::UploadCard( - const PaymentsClient::UploadRequestDetails& request_details) { - DCHECK(save_delegate_); + const PaymentsClient::UploadRequestDetails& request_details, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> callback) { IssueRequest( - std::make_unique<UploadCardRequest>(request_details, save_delegate_), + std::make_unique<UploadCardRequest>(request_details, std::move(callback)), true); }
diff --git a/components/autofill/core/browser/payments/payments_client.h b/components/autofill/core/browser/payments/payments_client.h index e8eef9d9..ca740d4 100644 --- a/components/autofill/core/browser/payments/payments_client.h +++ b/components/autofill/core/browser/payments/payments_client.h
@@ -34,31 +34,6 @@ class PaymentsRequest; -class PaymentsClientUnmaskDelegate { - public: - // Returns the real PAN retrieved from Payments. |real_pan| will be empty - // on failure. - virtual void OnDidGetRealPan(AutofillClient::PaymentsRpcResult result, - const std::string& real_pan) = 0; -}; - -class PaymentsClientSaveDelegate { - public: - // Returns the legal message retrieved from Payments. On failure or not - // meeting Payments's conditions for upload, |legal_message| will contain - // nullptr. - virtual void OnDidGetUploadDetails( - AutofillClient::PaymentsRpcResult result, - const base::string16& context_token, - std::unique_ptr<base::DictionaryValue> legal_message) = 0; - - // Returns the result of an upload request. - // If |result| == |AutofillClient::SUCCESS|, |server_id| may, optionally, - // contain the opaque identifier for the card on the server. - virtual void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, - const std::string& server_id) = 0; -}; - // PaymentsClient issues Payments RPCs and manages responses and failure // conditions. Only one request may be active at a time. Initiating a new // request will cancel a pending request. @@ -111,8 +86,6 @@ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, PrefService* pref_service, identity::IdentityManager* identity_manager, - PaymentsClientUnmaskDelegate* unmask_delegate, - PaymentsClientSaveDelegate* save_delegate, bool is_off_the_record = false); virtual ~PaymentsClient(); @@ -124,15 +97,12 @@ // accepted an upload prompt. void Prepare(); - // Sets up the |save_delegate_|. Necessary because CreditCardSaveManager - // requires PaymentsClient during initialization, so PaymentsClient can't - // start with save_delegate_ initialized. - virtual void SetSaveDelegate(PaymentsClientSaveDelegate* save_delegate); - PrefService* GetPrefService() const; // The user has attempted to unmask a card with the given cvc. - void UnmaskCard(const UnmaskRequestDetails& request_details); + void UnmaskCard(const UnmaskRequestDetails& request_details, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> callback); // Determine if the user meets the Payments service's conditions for upload. // The service uses |addresses| (from which names and phone numbers are @@ -141,20 +111,28 @@ // being considered for upload. |detected_values| is a bitmask of // CreditCardSaveManager::DetectedValue values that relays what data is // actually available for upload in order to make more informed upload - // decisions. If the conditions are met, the legal message will be returned - // via OnDidGetUploadDetails. |active_experiments| is used by Payments server - // to track requests that were triggered by enabled features. + // decisions. |callback| is the callback function when get response from + // server. If the conditions are met, the legal message will be returned via + // |callback|. |active_experiments| is used by Payments server to track + // requests that were triggered by enabled features. virtual void GetUploadDetails( const std::vector<AutofillProfile>& addresses, const int detected_values, const std::string& pan_first_six, const std::vector<const char*>& active_experiments, - const std::string& app_locale); + const std::string& app_locale, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const base::string16&, + std::unique_ptr<base::DictionaryValue>)> + callback); // The user has indicated that they would like to upload a card with the given // cvc. This request will fail server-side if a successful call to // GetUploadDetails has not already been made. - virtual void UploadCard(const UploadRequestDetails& details); + virtual void UploadCard( + const UploadRequestDetails& details, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> callback); // Cancels and clears the current |request_|. void CancelRequest(); @@ -204,11 +182,6 @@ identity::IdentityManager* const identity_manager_; - // Delegates for the results of the various requests to Payments. Both must - // outlive |this|. - PaymentsClientUnmaskDelegate* const unmask_delegate_; - PaymentsClientSaveDelegate* save_delegate_; - // The current request. std::unique_ptr<PaymentsRequest> request_;
diff --git a/components/autofill/core/browser/payments/payments_client_unittest.cc b/components/autofill/core/browser/payments/payments_client_unittest.cc index 2d2027d..1250d7f 100644 --- a/components/autofill/core/browser/payments/payments_client_unittest.cc +++ b/components/autofill/core/browser/payments/payments_client_unittest.cc
@@ -48,11 +48,10 @@ } // namespace -class PaymentsClientTest : public testing::Test, - public PaymentsClientUnmaskDelegate, - public PaymentsClientSaveDelegate { +class PaymentsClientTest : public testing::Test { public: - PaymentsClientTest() : result_(AutofillClient::NONE) {} + PaymentsClientTest() + : result_(AutofillClient::NONE), weak_ptr_factory_(this) {} ~PaymentsClientTest() override {} void SetUp() override { @@ -74,9 +73,9 @@ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_); TestingPrefServiceSimple pref_service_; - client_.reset( - new PaymentsClient(test_shared_loader_factory_, &pref_service_, - identity_test_env_.identity_manager(), this, this)); + client_.reset(new PaymentsClient(test_shared_loader_factory_, + &pref_service_, + identity_test_env_.identity_manager())); } void TearDown() override { client_.reset(); } @@ -101,23 +100,22 @@ base::FieldTrialList::CreateFieldTrial(trial_name, group_name)->group(); } - // PaymentsClientUnmaskDelegate: void OnDidGetRealPan(AutofillClient::PaymentsRpcResult result, - const std::string& real_pan) override { + const std::string& real_pan) { result_ = result; real_pan_ = real_pan; } - // PaymentsClientSaveDelegate: void OnDidGetUploadDetails( AutofillClient::PaymentsRpcResult result, const base::string16& context_token, - std::unique_ptr<base::DictionaryValue> legal_message) override { + std::unique_ptr<base::DictionaryValue> legal_message) { result_ = result; legal_message_ = std::move(legal_message); } + void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, - const std::string& server_id) override { + const std::string& server_id) { result_ = result; server_id_ = server_id; } @@ -134,16 +132,21 @@ request_details.card = test::GetMaskedServerCard(); request_details.user_response.cvc = base::ASCIIToUTF16("123"); request_details.risk_data = "some risk data"; - client_->UnmaskCard(request_details); + client_->UnmaskCard(request_details, + base::BindOnce(&PaymentsClientTest::OnDidGetRealPan, + weak_ptr_factory_.GetWeakPtr())); } void StartGettingUploadDetails() { if (!identity_test_env_.identity_manager()->HasPrimaryAccount()) identity_test_env_.MakePrimaryAccountAvailable("example@gmail.com"); - client_->GetUploadDetails(BuildTestProfiles(), kAllDetectableValues, - /*pan_first_six=*/"411111", - std::vector<const char*>(), "language-LOCALE"); + client_->GetUploadDetails( + BuildTestProfiles(), kAllDetectableValues, + /*pan_first_six=*/"411111", std::vector<const char*>(), + "language-LOCALE", + base::BindOnce(&PaymentsClientTest::OnDidGetUploadDetails, + weak_ptr_factory_.GetWeakPtr())); } void StartUploading(bool include_cvc) { @@ -159,7 +162,9 @@ request_details.risk_data = "some risk data"; request_details.app_locale = "language-LOCALE"; request_details.profiles = BuildTestProfiles(); - client_->UploadCard(request_details); + client_->UploadCard(request_details, + base::BindOnce(&PaymentsClientTest::OnDidUploadCard, + weak_ptr_factory_.GetWeakPtr())); } network::TestURLLoaderFactory* factory() { return &test_url_loader_factory_; } @@ -199,6 +204,7 @@ net::HttpRequestHeaders intercepted_headers_; std::string intercepted_body_; + base::WeakPtrFactory<PaymentsClientTest> weak_ptr_factory_; private: DISALLOW_COPY_AND_ASSIGN(PaymentsClientTest);
diff --git a/components/autofill/core/browser/payments/test_payments_client.cc b/components/autofill/core/browser/payments/test_payments_client.cc index 1048649..c42daa5 100644 --- a/components/autofill/core/browser/payments/test_payments_client.cc +++ b/components/autofill/core/browser/payments/test_payments_client.cc
@@ -13,15 +13,8 @@ TestPaymentsClient::TestPaymentsClient( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_, PrefService* pref_service, - identity::IdentityManager* identity_manager, - payments::PaymentsClientUnmaskDelegate* unmask_delegate, - payments::PaymentsClientSaveDelegate* save_delegate) - : PaymentsClient(url_loader_factory_, - pref_service, - identity_manager, - unmask_delegate, - save_delegate), - save_delegate_(save_delegate) {} + identity::IdentityManager* identity_manager) + : PaymentsClient(url_loader_factory_, pref_service, identity_manager) {} TestPaymentsClient::~TestPaymentsClient() {} @@ -30,28 +23,27 @@ const int detected_values, const std::string& pan_first_six, const std::vector<const char*>& active_experiments, - const std::string& app_locale) { + const std::string& app_locale, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const base::string16&, + std::unique_ptr<base::DictionaryValue>)> callback) { upload_details_addresses_ = addresses; detected_values_ = detected_values; pan_first_six_ = pan_first_six; active_experiments_ = active_experiments; - save_delegate_->OnDidGetUploadDetails( - app_locale == "en-US" ? AutofillClient::SUCCESS - : AutofillClient::PERMANENT_FAILURE, - base::ASCIIToUTF16("this is a context token"), - std::unique_ptr<base::DictionaryValue>(nullptr)); + std::move(callback).Run(app_locale == "en-US" + ? AutofillClient::SUCCESS + : AutofillClient::PERMANENT_FAILURE, + base::ASCIIToUTF16("this is a context token"), + std::unique_ptr<base::DictionaryValue>(nullptr)); } void TestPaymentsClient::UploadCard( - const payments::PaymentsClient::UploadRequestDetails& request_details) { + const payments::PaymentsClient::UploadRequestDetails& request_details, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> callback) { active_experiments_ = request_details.active_experiments; - save_delegate_->OnDidUploadCard(AutofillClient::SUCCESS, server_id_); -} - -void TestPaymentsClient::SetSaveDelegate( - payments::PaymentsClientSaveDelegate* save_delegate) { - save_delegate_ = save_delegate; - payments::PaymentsClient::SetSaveDelegate(save_delegate); + std::move(callback).Run(AutofillClient::SUCCESS, server_id_); } void TestPaymentsClient::SetServerIdForCardUpload(std::string server_id) {
diff --git a/components/autofill/core/browser/payments/test_payments_client.h b/components/autofill/core/browser/payments/test_payments_client.h index 13d24e0..b4394e93 100644 --- a/components/autofill/core/browser/payments/test_payments_client.h +++ b/components/autofill/core/browser/payments/test_payments_client.h
@@ -22,23 +22,25 @@ TestPaymentsClient( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_, PrefService* pref_service, - identity::IdentityManager* identity_manager, - payments::PaymentsClientUnmaskDelegate* unmask_delegate, - payments::PaymentsClientSaveDelegate* save_delegate); + identity::IdentityManager* identity_manager); ~TestPaymentsClient() override; - void GetUploadDetails(const std::vector<AutofillProfile>& addresses, - const int detected_values, - const std::string& pan_first_six, - const std::vector<const char*>& active_experiments, - const std::string& app_locale) override; + void GetUploadDetails( + const std::vector<AutofillProfile>& addresses, + const int detected_values, + const std::string& pan_first_six, + const std::vector<const char*>& active_experiments, + const std::string& app_locale, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const base::string16&, + std::unique_ptr<base::DictionaryValue>)> callback) + override; - void UploadCard(const payments::PaymentsClient::UploadRequestDetails& - request_details) override; - - void SetSaveDelegate( - payments::PaymentsClientSaveDelegate* save_delegate) override; + void UploadCard( + const payments::PaymentsClient::UploadRequestDetails& request_details, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::string&)> callback) override; void SetServerIdForCardUpload(std::string); @@ -52,7 +54,6 @@ } private: - payments::PaymentsClientSaveDelegate* save_delegate_; std::string server_id_; std::vector<AutofillProfile> upload_details_addresses_; int detected_values_;
diff --git a/components/autofill/core/browser/test_autofill_manager.cc b/components/autofill/core/browser/test_autofill_manager.cc index dfbe4a7..51f1574b 100644 --- a/components/autofill/core/browser/test_autofill_manager.cc +++ b/components/autofill/core/browser/test_autofill_manager.cc
@@ -25,9 +25,7 @@ url_loader_factory_(driver->GetURLLoaderFactory()), client_(client) { set_payments_client(new payments::PaymentsClient( - url_loader_factory_, client->GetPrefs(), client->GetIdentityManager(), - /*unmask_delegate=*/this, - /*save_delegate=*/nullptr)); + url_loader_factory_, client->GetPrefs(), client->GetIdentityManager())); } TestAutofillManager::TestAutofillManager(
diff --git a/components/autofill/core/browser/test_credit_card_save_manager.cc b/components/autofill/core/browser/test_credit_card_save_manager.cc index c06d9507a..ab8a640 100644 --- a/components/autofill/core/browser/test_credit_card_save_manager.cc +++ b/components/autofill/core/browser/test_credit_card_save_manager.cc
@@ -16,12 +16,7 @@ : CreditCardSaveManager(client, payments_client, "en-US", - personal_data_manager), - test_payments_client_(payments_client) { - if (test_payments_client_) { - test_payments_client_->SetSaveDelegate(this); - } -} + personal_data_manager) {} TestCreditCardSaveManager::~TestCreditCardSaveManager() {}
diff --git a/components/autofill/core/browser/test_credit_card_save_manager.h b/components/autofill/core/browser/test_credit_card_save_manager.h index b00211b..cc157fc 100644 --- a/components/autofill/core/browser/test_credit_card_save_manager.h +++ b/components/autofill/core/browser/test_credit_card_save_manager.h
@@ -38,7 +38,6 @@ void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, const std::string& server_id) override; - payments::TestPaymentsClient* test_payments_client_; // Weak reference. bool credit_card_upload_enabled_ = false; bool credit_card_was_uploaded_ = false;
diff --git a/components/autofill/core/browser/test_local_card_migration_manager.cc b/components/autofill/core/browser/test_local_card_migration_manager.cc index 9ef4888..6a573a7 100644 --- a/components/autofill/core/browser/test_local_card_migration_manager.cc +++ b/components/autofill/core/browser/test_local_card_migration_manager.cc
@@ -19,11 +19,7 @@ : LocalCardMigrationManager(client, payments_client, "en-US", - personal_data_manager), - test_payments_client_(payments_client) { - if (test_payments_client_) - test_payments_client_->SetSaveDelegate(this); -} + personal_data_manager) {} TestLocalCardMigrationManager::~TestLocalCardMigrationManager() {}
diff --git a/components/autofill/core/browser/test_local_card_migration_manager.h b/components/autofill/core/browser/test_local_card_migration_manager.h index 07041a9d..6cb5cc6 100644 --- a/components/autofill/core/browser/test_local_card_migration_manager.h +++ b/components/autofill/core/browser/test_local_card_migration_manager.h
@@ -41,7 +41,6 @@ const base::string16& context_token, std::unique_ptr<base::DictionaryValue> legal_message) override; - payments::TestPaymentsClient* test_payments_client_; // Weak reference. bool local_card_migration_was_triggered_ = false; DISALLOW_COPY_AND_ASSIGN(TestLocalCardMigrationManager);
diff --git a/components/chrome_cleaner/public/constants/result_codes.h b/components/chrome_cleaner/public/constants/result_codes.h index 09e1f86..ff41456 100644 --- a/components/chrome_cleaner/public/constants/result_codes.h +++ b/components/chrome_cleaner/public/constants/result_codes.h
@@ -214,6 +214,10 @@ // Some of the scanning configuration switches have invalid values. RESULT_CODE_INVALID_SCANNING_SWITCHES = 53, + // The target process for the JSON parser sandbox disconnected from the IPC + // while the pipe was still needed by the broker process. + RESULT_CODE_JSON_PARSER_SANDBOX_DISCONNECTED_TOO_SOON = 54, + // WHEN YOU ADD NEW EXIT CODES, DON'T FORGET TO UPDATE THE MONITORING RULES. // See http://go/chrome-cleaner-exit-codes. (Google internal only - external // contributors please ask one of the OWNERS to do the update.)
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc index dd49dcc..cc04aa6 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -18,6 +18,7 @@ #include "base/strings/string_number_conversions.h" #include "base/trace_event/trace_event.h" #include "base/values.h" +#include "build/build_config.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h" #include "components/data_reduction_proxy/core/browser/data_usage_store.h" @@ -1398,6 +1399,12 @@ void DataReductionProxyCompressionStats::InitializeWeeklyAggregateDataUse( const base::Time& now) { +#if defined(OS_ANDROID) && defined(ARCH_CPU_X86) + // TODO(rajendrant): Enable aggregate metrics recording in x86 Android. + // http://crbug.com/865373 + return; +#endif + MaybeInitWeeklyAggregateDataUsePrefs(now, pref_service_); // Record the histograms that will show up in the user feedback. RecordDictionaryToHistogram( @@ -1434,6 +1441,11 @@ bool is_user_request, data_use_measurement::DataUseUserData::DataUseContentType content_type, int32_t service_hash_code) { +#if defined(OS_ANDROID) && defined(ARCH_CPU_X86) + // TODO(rajendrant): Enable aggregate metrics recording in x86 Android. + // http://crbug.com/865373 + return; +#endif // Update the prefs if this is a new week. This can happen when chrome is open // for weeks without being closed. MaybeInitWeeklyAggregateDataUsePrefs(now, pref_service_);
diff --git a/components/feed/core/feed_networking_host.cc b/components/feed/core/feed_networking_host.cc index cd94af0..e40bc2d 100644 --- a/components/feed/core/feed_networking_host.cc +++ b/components/feed/core/feed_networking_host.cc
@@ -8,6 +8,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/stringprintf.h" #include "base/values.h" #include "components/variations/net/variations_http_headers.h" #include "google_apis/gaia/google_service_auth_error.h" @@ -31,6 +32,8 @@ constexpr char kApiKeyQueryParam[] = "key"; constexpr char kAuthenticationScope[] = "https://www.googleapis.com/auth/googlenow"; +constexpr char kAuthorizationRequestHeaderFormat[] = "Bearer %s"; + constexpr char kContentEncoding[] = "Content-Encoding"; constexpr char kContentType[] = "application/octet-stream"; constexpr char kGzip[] = "gzip"; @@ -59,15 +62,15 @@ void StartAccessTokenFetch(); void AccessTokenFetchFinished(GoogleServiceAuthError error, identity::AccessTokenInfo access_token_info); - void StartLoader(const std::string& access_token); - std::unique_ptr<network::SimpleURLLoader> MakeLoader( - const std::string& access_token); + void StartLoader(); + std::unique_ptr<network::SimpleURLLoader> MakeLoader(); net::HttpRequestHeaders MakeHeaders(const std::string& auth_header) const; void PopulateRequestBody(network::SimpleURLLoader* loader); void OnSimpleLoaderComplete(std::unique_ptr<std::string> response); const GURL url_; const std::string request_type_; + std::string access_token_; const std::vector<uint8_t> request_body_; IdentityManager* const identity_manager_; std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> token_fetcher_; @@ -96,7 +99,7 @@ done_callback_ = std::move(done_callback); if (!identity_manager_->HasPrimaryAccount()) { - StartLoader(std::string()); + StartLoader(); return; } @@ -119,19 +122,24 @@ identity::AccessTokenInfo access_token_info) { UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.TokenFetchStatus", error.state(), GoogleServiceAuthError::NUM_STATES); - StartLoader(access_token_info.token); + access_token_ = access_token_info.token; + StartLoader(); } -void NetworkFetch::StartLoader(const std::string& access_token) { - simple_loader_ = MakeLoader(access_token); +void NetworkFetch::StartLoader() { + simple_loader_ = MakeLoader(); simple_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( loader_factory_, base::BindOnce(&NetworkFetch::OnSimpleLoaderComplete, base::Unretained(this))); } -std::unique_ptr<network::SimpleURLLoader> NetworkFetch::MakeLoader( - const std::string& access_token) { - net::HttpRequestHeaders headers = MakeHeaders(access_token); +std::unique_ptr<network::SimpleURLLoader> NetworkFetch::MakeLoader() { + std::string auth_header = + access_token_.empty() + ? std::string() + : base::StringPrintf(kAuthorizationRequestHeaderFormat, + access_token_.c_str()); + net::HttpRequestHeaders headers = MakeHeaders(auth_header); // TODO(pnoland): Add data use measurement once it's supported for simple // url loader. net::NetworkTrafficAnnotationTag traffic_annotation = @@ -160,7 +168,7 @@ } })"); GURL url(url_); - if (access_token.empty() && !api_key_.empty()) + if (access_token_.empty() && !api_key_.empty()) url = net::AppendQueryParameter(url_, kApiKeyQueryParam, api_key_); auto resource_request = std::make_unique<network::ResourceRequest>(); @@ -223,6 +231,14 @@ if (response) { status_code = simple_loader_->ResponseInfo()->headers->response_code(); + if (status_code == net::HTTP_UNAUTHORIZED) { + OAuth2TokenService::ScopeSet scopes{kAuthenticationScope}; + std::string account_id = + identity_manager_->GetPrimaryAccountInfo().account_id; + identity_manager_->RemoveAccessTokenFromCache(account_id, scopes, + access_token_); + } + const uint8_t* begin = reinterpret_cast<const uint8_t*>(response->data()); const uint8_t* end = begin + response->size(); response_body.assign(begin, end);
diff --git a/components/feed/core/feed_networking_host_unittest.cc b/components/feed/core/feed_networking_host_unittest.cc index 5c51361..27d7364 100644 --- a/components/feed/core/feed_networking_host_unittest.cc +++ b/components/feed/core/feed_networking_host_unittest.cc
@@ -8,6 +8,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" +#include "base/test/bind_test_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/test_mock_time_task_runner.h" #include "net/http/http_response_headers.h" @@ -127,6 +128,10 @@ response_string); } + network::TestURLLoaderFactory* test_factory() { + return &test_factory_; + } + private: scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_; identity::IdentityTestEnvironment identity_test_env_; @@ -222,8 +227,30 @@ } } -// TODO(pnoland): Add a test that verifies request headers -// specify gzip. +TEST_F(FeedNetworkingHostTest, ShouldSetHeadersCorrectly) { + MockResponseDoneCallback done_callback; + net::HttpRequestHeaders headers; + base::RunLoop interceptor_run_loop; + base::HistogramTester histogram_tester; + + test_factory()->SetInterceptor( + base::BindLambdaForTesting([&](const network::ResourceRequest& request) { + headers = request.headers; + interceptor_run_loop.Quit(); + })); + + SendRequestAndRespond("http://foobar.com/feed", "POST", "", "", + net::HTTP_OK, network::URLLoaderCompletionStatus(), + &done_callback); + + std::string content_encoding; + std::string authorization; + EXPECT_TRUE(headers.GetHeader("content-encoding", &content_encoding)); + EXPECT_TRUE(headers.GetHeader("Authorization", &authorization)); + + EXPECT_EQ(content_encoding, "gzip"); + EXPECT_EQ(authorization, "Bearer access_token"); +} TEST_F(FeedNetworkingHostTest, ShouldReportSizeHistograms) { std::string uncompressed_request_string(2048, 'a');
diff --git a/components/payments/content/manifest_verifier.cc b/components/payments/content/manifest_verifier.cc index 26047dd..8b6e910 100644 --- a/components/payments/content/manifest_verifier.cc +++ b/components/payments/content/manifest_verifier.cc
@@ -94,9 +94,11 @@ // https://w3c.github.io/payment-method-basic-card/ // https://w3c.github.io/webpayments/proposals/interledger-payment-method.html // https://w3c.github.io/webpayments-methods-credit-transfer-direct-debit/ + // https://w3c.github.io/webpayments-methods-tokenization/ if (method == "basic-card" || method == "interledger" || method == "payee-credit-transfer" || - method == "payer-credit-transfer") { + method == "payer-credit-transfer" || + method == "tokenized-card") { verified_method_names.emplace_back(method); continue; }
diff --git a/components/payments/core/autofill_payment_instrument_unittest.cc b/components/payments/core/autofill_payment_instrument_unittest.cc index 57b9f6a..9e170be 100644 --- a/components/payments/core/autofill_payment_instrument_unittest.cc +++ b/components/payments/core/autofill_payment_instrument_unittest.cc
@@ -59,9 +59,7 @@ bool on_instrument_details_error_called_ = false; }; -class FakePaymentRequestDelegate - : public PaymentRequestDelegate, - public autofill::payments::PaymentsClientUnmaskDelegate { +class FakePaymentRequestDelegate : public PaymentRequestDelegate { public: FakePaymentRequestDelegate() : locale_("en-US"), @@ -71,10 +69,8 @@ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)), payments_client_(test_shared_loader_factory_, - nullptr, - nullptr, - this, - nullptr), + /*pref_service=*/nullptr, + /*identity_manager=*/nullptr), full_card_request_(&autofill_client_, &payments_client_, &personal_data_) {}
diff --git a/components/payments/core/test_payment_request_delegate.cc b/components/payments/core/test_payment_request_delegate.cc index de207ed..ccd5d8d 100644 --- a/components/payments/core/test_payment_request_delegate.cc +++ b/components/payments/core/test_payment_request_delegate.cc
@@ -17,10 +17,8 @@ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)), payments_client_(test_shared_loader_factory_, - nullptr, - nullptr, - /*unmask_delegate=*/&payments_client_delegate_, - /*save_delegate=*/nullptr), + /*pref_service=*/nullptr, + /*identity_manager=*/nullptr), full_card_request_(&autofill_client_, &payments_client_, personal_data_manager) {} @@ -102,12 +100,4 @@ return true; } -TestPaymentsClientDelegate::TestPaymentsClientDelegate() {} - -TestPaymentsClientDelegate::~TestPaymentsClientDelegate() {} - -void TestPaymentsClientDelegate::OnDidGetRealPan( - autofill::AutofillClient::PaymentsRpcResult result, - const std::string& real_pan) {} - } // namespace payments
diff --git a/components/payments/core/test_payment_request_delegate.h b/components/payments/core/test_payment_request_delegate.h index 6c07f63d..5373fb1 100644 --- a/components/payments/core/test_payment_request_delegate.h +++ b/components/payments/core/test_payment_request_delegate.h
@@ -21,18 +21,6 @@ namespace payments { -class TestPaymentsClientDelegate - : public autofill::payments::PaymentsClientUnmaskDelegate { - public: - TestPaymentsClientDelegate(); - ~TestPaymentsClientDelegate(); - - private: - // autofill::payments::PaymentsClientUnmaskDelegate: - void OnDidGetRealPan(autofill::AutofillClient::PaymentsRpcResult result, - const std::string& real_pan) override; -}; - class TestPaymentRequestDelegate : public PaymentRequestDelegate { public: explicit TestPaymentRequestDelegate( @@ -66,7 +54,6 @@ private: base::MessageLoop loop_; - TestPaymentsClientDelegate payments_client_delegate_; autofill::PersonalDataManager* personal_data_manager_; std::string locale_; const GURL last_committed_url_;
diff --git a/components/storage_monitor/storage_monitor_chromeos.cc b/components/storage_monitor/storage_monitor_chromeos.cc index 0954f2c..2eaafc2 100644 --- a/components/storage_monitor/storage_monitor_chromeos.cc +++ b/components/storage_monitor/storage_monitor_chromeos.cc
@@ -162,10 +162,6 @@ weak_ptr_factory_.GetWeakPtr())); } -void StorageMonitorCros::OnAutoMountableDiskEvent( - DiskMountManager::DiskEvent event, - const DiskMountManager::Disk& disk) {} - void StorageMonitorCros::OnBootDeviceDiskEvent( DiskMountManager::DiskEvent event, const DiskMountManager::Disk& disk) { @@ -191,9 +187,6 @@ } } -void StorageMonitorCros::OnDeviceEvent(DiskMountManager::DeviceEvent event, - const std::string& device_path) {} - void StorageMonitorCros::OnMountEvent( DiskMountManager::MountEvent event, chromeos::MountError error_code, @@ -235,14 +228,6 @@ } } -void StorageMonitorCros::OnFormatEvent(DiskMountManager::FormatEvent event, - chromeos::FormatError error_code, - const std::string& device_path) {} - -void StorageMonitorCros::OnRenameEvent(DiskMountManager::RenameEvent event, - chromeos::RenameError error_code, - const std::string& device_path) {} - void StorageMonitorCros::SetMediaTransferProtocolManagerForTest( device::mojom::MtpManagerPtr test_manager) { DCHECK(!mtp_device_manager_);
diff --git a/components/storage_monitor/storage_monitor_chromeos.h b/components/storage_monitor/storage_monitor_chromeos.h index 7786be421..1eb3bb92 100644 --- a/components/storage_monitor/storage_monitor_chromeos.h +++ b/components/storage_monitor/storage_monitor_chromeos.h
@@ -46,24 +46,13 @@ device::mojom::MtpManagerPtr test_manager); // chromeos::disks::DiskMountManager::Observer implementation. - void OnAutoMountableDiskEvent( - chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk& disk) override; void OnBootDeviceDiskEvent( chromeos::disks::DiskMountManager::DiskEvent event, const chromeos::disks::DiskMountManager::Disk& disk) override; - void OnDeviceEvent(chromeos::disks::DiskMountManager::DeviceEvent event, - const std::string& device_path) override; void OnMountEvent(chromeos::disks::DiskMountManager::MountEvent event, chromeos::MountError error_code, const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) override; - void OnFormatEvent(chromeos::disks::DiskMountManager::FormatEvent event, - chromeos::FormatError error_code, - const std::string& device_path) override; - void OnRenameEvent(chromeos::disks::DiskMountManager::RenameEvent event, - chromeos::RenameError error_code, - const std::string& device_path) override; // StorageMonitor implementation. bool GetStorageInfoForPath(const base::FilePath& path,
diff --git a/components/viz/service/display_embedder/gl_output_surface_android.cc b/components/viz/service/display_embedder/gl_output_surface_android.cc index 882e5d8..c5bd5a8 100644 --- a/components/viz/service/display_embedder/gl_output_surface_android.cc +++ b/components/viz/service/display_embedder/gl_output_surface_android.cc
@@ -4,12 +4,16 @@ #include "components/viz/service/display_embedder/gl_output_surface_android.h" +#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.h" + namespace viz { GLOutputSurfaceAndroid::GLOutputSurfaceAndroid( scoped_refptr<VizProcessContextProvider> context_provider, SyntheticBeginFrameSource* synthetic_begin_frame_source) - : GLOutputSurface(context_provider, synthetic_begin_frame_source) {} + : GLOutputSurface(context_provider, synthetic_begin_frame_source), + overlay_candidate_validator_( + std::make_unique<CompositorOverlayCandidateValidatorAndroid>()) {} GLOutputSurfaceAndroid::~GLOutputSurfaceAndroid() = default; @@ -23,4 +27,9 @@ flags, std::move(swap_callback), std::move(presentation_callback)); } +OverlayCandidateValidator* +GLOutputSurfaceAndroid::GetOverlayCandidateValidator() const { + return overlay_candidate_validator_.get(); +} + } // namespace viz
diff --git a/components/viz/service/display_embedder/gl_output_surface_android.h b/components/viz/service/display_embedder/gl_output_surface_android.h index 75827f1..e10c463 100644 --- a/components/viz/service/display_embedder/gl_output_surface_android.h +++ b/components/viz/service/display_embedder/gl_output_surface_android.h
@@ -10,6 +10,7 @@ #include "components/viz/service/display_embedder/gl_output_surface.h" namespace viz { +class OverlayCandidateValidator; class GLOutputSurfaceAndroid : public GLOutputSurface { public: @@ -24,8 +25,11 @@ uint32_t flags, gpu::ContextSupport::SwapCompletedCallback swap_callback, gpu::ContextSupport::PresentationCallback presentation_callback) override; + OverlayCandidateValidator* GetOverlayCandidateValidator() const override; private: + std::unique_ptr<OverlayCandidateValidator> overlay_candidate_validator_; + DISALLOW_COPY_AND_ASSIGN(GLOutputSurfaceAndroid); };
diff --git a/components/viz/service/main/viz_main_impl.cc b/components/viz/service/main/viz_main_impl.cc index fdf998e..e547082 100644 --- a/components/viz/service/main/viz_main_impl.cc +++ b/components/viz/service/main/viz_main_impl.cc
@@ -298,12 +298,19 @@ DCHECK(gpu_service_); DCHECK(gpu_thread_task_runner_->BelongsToCurrentThread()); + gl::GLSurfaceFormat format; + // If we are running a SW Viz process, we may not have a default offscreen + // surface. + if (auto* offscreen_surface = + gpu_service_->gpu_channel_manager()->default_offscreen_surface()) { + format = offscreen_surface->GetFormat(); + } else { + DCHECK_EQ(gl::GetGLImplementation(), gl::kGLImplementationDisabled); + } + task_executor_ = base::MakeRefCounted<gpu::GpuInProcessThreadService>( gpu_thread_task_runner_, gpu_service_->sync_point_manager(), - gpu_service_->mailbox_manager(), gpu_service_->share_group(), - gpu_service_->gpu_channel_manager() - ->default_offscreen_surface() - ->GetFormat(), + gpu_service_->mailbox_manager(), gpu_service_->share_group(), format, gpu_service_->gpu_feature_info(), gpu_service_->gpu_channel_manager()->gpu_preferences());
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc index 99e8fd1..fa63a56 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.cc +++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -944,7 +944,6 @@ create_loader_params_->request.url, "", net::ForceSniffFileUrlsForHtml::kDisabled, &head->mime_type); - head->did_mime_sniff = true; } head->content_length = body_size; head->encoded_data_length = header_size;
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc index 1d467539..46cd268c 100644 --- a/content/browser/devtools/protocol/target_handler.cc +++ b/content/browser/devtools/protocol/target_handler.cc
@@ -27,8 +27,6 @@ namespace { -static const char kMethod[] = "method"; -static const char kResumeMethod[] = "Runtime.runIfWaitingForDebugger"; static const char kInitializerScript[] = R"( (function() { const bindingName = "%s"; @@ -241,8 +239,10 @@ DevToolsAgentHostImpl* agent_host_impl = static_cast<DevToolsAgentHostImpl*>(agent_host); if (flatten_protocol) { - handler->target_registry_->AttachSubtargetSession(id, agent_host_impl, - session); + handler->target_registry_->AttachSubtargetSession( + id, agent_host_impl, session, + base::BindOnce(&Session::ResumeIfThrottled, + base::Unretained(session))); } else { agent_host_impl->AttachClient(session); } @@ -275,17 +275,16 @@ void SetThrottle(Throttle* throttle) { throttle_ = throttle; } + void ResumeIfThrottled() { + if (throttle_) + throttle_->Clear(); + } + void SendMessageToAgentHost(const std::string& message) { if (throttle_) { - bool resuming = false; std::unique_ptr<base::Value> value = base::JSONReader::Read(message); - if (value && value->is_dict()) { - base::Value* method = value->FindKey(kMethod); - resuming = method && method->is_string() && - method->GetString() == kResumeMethod; - } - if (resuming) - throttle_->Clear(); + if (TargetRegistry::IsRuntimeResumeCommand(value.get())) + ResumeIfThrottled(); } agent_host_->DispatchProtocolMessage(this, message); @@ -426,7 +425,7 @@ } Response TargetHandler::Disable() { - SetAutoAttach(false, false); + SetAutoAttach(false, false, false); SetDiscoverTargets(false); auto_attached_sessions_.clear(); attached_sessions_.clear(); @@ -455,7 +454,7 @@ void TargetHandler::AutoAttach(DevToolsAgentHost* host, bool waiting_for_debugger) { std::string session_id = - Session::Attach(this, host, waiting_for_debugger, false); + Session::Attach(this, host, waiting_for_debugger, flatten_auto_attach_); auto_attached_sessions_[host] = attached_sessions_[session_id].get(); } @@ -517,8 +516,10 @@ return Response::OK(); } -Response TargetHandler::SetAutoAttach( - bool auto_attach, bool wait_for_debugger_on_start) { +Response TargetHandler::SetAutoAttach(bool auto_attach, + bool wait_for_debugger_on_start, + Maybe<bool> flatten) { + flatten_auto_attach_ = flatten.fromMaybe(false); auto_attacher_.SetAutoAttach(auto_attach, wait_for_debugger_on_start); if (!auto_attacher_.ShouldThrottleFramesNavigation()) ClearThrottles();
diff --git a/content/browser/devtools/protocol/target_handler.h b/content/browser/devtools/protocol/target_handler.h index ba5702a..69b17b4 100644 --- a/content/browser/devtools/protocol/target_handler.h +++ b/content/browser/devtools/protocol/target_handler.h
@@ -49,7 +49,8 @@ // Domain implementation. Response SetDiscoverTargets(bool discover) override; Response SetAutoAttach(bool auto_attach, - bool wait_for_debugger_on_start) override; + bool wait_for_debugger_on_start, + Maybe<bool> flatten) override; Response SetRemoteLocations( std::unique_ptr<protocol::Array<Target::RemoteLocation>>) override; Response AttachToTarget(const std::string& target_id, @@ -107,6 +108,7 @@ std::unique_ptr<Target::Frontend> frontend_; TargetAutoAttacher auto_attacher_; + bool flatten_auto_attach_ = false; bool discover_; std::map<std::string, std::unique_ptr<Session>> attached_sessions_; std::map<DevToolsAgentHost*, Session*> auto_attached_sessions_;
diff --git a/content/browser/devtools/target_registry.cc b/content/browser/devtools/target_registry.cc index aa783b0..6250b22 100644 --- a/content/browser/devtools/target_registry.cc +++ b/content/browser/devtools/target_registry.cc
@@ -9,15 +9,45 @@ namespace content { +namespace { +static const char kMethod[] = "method"; +static const char kResumeMethod[] = "Runtime.runIfWaitingForDebugger"; +} // namespace + +// static +bool TargetRegistry::IsRuntimeResumeCommand(base::Value* value) { + if (value && value->is_dict()) { + base::Value* method = value->FindKey(kMethod); + return method && method->is_string() && + method->GetString() == kResumeMethod; + } + return false; +} + +struct TargetRegistry::SessionInfo { + SessionInfo(scoped_refptr<DevToolsAgentHostImpl> agent_host, + DevToolsAgentHostClient* client, + base::OnceClosure resume_if_throttled) + : agent_host(agent_host), + client(client), + resume_if_throttled(std::move(resume_if_throttled)) {} + scoped_refptr<DevToolsAgentHostImpl> agent_host; + DevToolsAgentHostClient* client; + base::OnceClosure resume_if_throttled; +}; + TargetRegistry::TargetRegistry(DevToolsSession* root_session) : root_session_(root_session) {} TargetRegistry::~TargetRegistry() {} -void TargetRegistry::AttachSubtargetSession(const std::string& session_id, - DevToolsAgentHostImpl* agent_host, - DevToolsAgentHostClient* client) { - sessions_[session_id] = std::make_pair(agent_host, client); +void TargetRegistry::AttachSubtargetSession( + const std::string& session_id, + DevToolsAgentHostImpl* agent_host, + DevToolsAgentHostClient* client, + base::OnceClosure resume_if_throttled) { + sessions_[session_id] = std::make_unique<SessionInfo>( + agent_host, client, std::move(resume_if_throttled)); agent_host->AttachSubtargetClient(client, this); } void TargetRegistry::DetachSubtargetSession(const std::string& session_id) { @@ -36,14 +66,17 @@ std::string session_id; bool result = parsed_message->GetString("sessionId", &session_id); DCHECK(result); - auto it = sessions_.find(session_id); if (it == sessions_.end()) { LOG(ERROR) << "Unknown session " << session_id; return; } - scoped_refptr<DevToolsAgentHostImpl> agent_host = it->second.first; - DevToolsAgentHostClient* client = it->second.second; + scoped_refptr<DevToolsAgentHostImpl> agent_host = it->second->agent_host; + DevToolsAgentHostClient* client = it->second->client; + if (!it->second->resume_if_throttled.is_null() && + IsRuntimeResumeCommand(parsed_message.get())) { + std::move(it->second->resume_if_throttled).Run(); + } agent_host->DispatchProtocolMessage(client, message, std::move(parsed_message)); }
diff --git a/content/browser/devtools/target_registry.h b/content/browser/devtools/target_registry.h index 5b12d858..9892da5 100644 --- a/content/browser/devtools/target_registry.h +++ b/content/browser/devtools/target_registry.h
@@ -7,6 +7,7 @@ #include <string> +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/containers/flat_map.h" #include "base/values.h" @@ -18,12 +19,15 @@ class TargetRegistry { public: + static bool IsRuntimeResumeCommand(base::Value* value); + explicit TargetRegistry(DevToolsSession* root_session); ~TargetRegistry(); void AttachSubtargetSession(const std::string& session_id, DevToolsAgentHostImpl* agent_host, - DevToolsAgentHostClient* client); + DevToolsAgentHostClient* client, + base::OnceClosure resume_if_throttled); void DetachSubtargetSession(const std::string& session_id); bool CanDispatchMessageOnAgentHost(base::DictionaryValue* parsed_message); void DispatchMessageOnAgentHost( @@ -34,10 +38,8 @@ private: DevToolsSession* root_session_; - base::flat_map< - std::string, - std::pair<scoped_refptr<DevToolsAgentHostImpl>, DevToolsAgentHostClient*>> - sessions_; + struct SessionInfo; + base::flat_map<std::string, std::unique_ptr<SessionInfo>> sessions_; DISALLOW_COPY_AND_ASSIGN(TargetRegistry); };
diff --git a/content/browser/file_url_loader_factory.cc b/content/browser/file_url_loader_factory.cc index cfed5f6..822e0a0 100644 --- a/content/browser/file_url_loader_factory.cc +++ b/content/browser/file_url_loader_factory.cc
@@ -557,7 +557,6 @@ ? net::ForceSniffFileUrlsForHtml::kEnabled : net::ForceSniffFileUrlsForHtml::kDisabled, &head.mime_type); - head.did_mime_sniff = true; } if (head.headers) { head.headers->AddHeader(
diff --git a/content/browser/fileapi/file_system_url_loader_factory.cc b/content/browser/fileapi/file_system_url_loader_factory.cc index 183e2a9..7ef37b18 100644 --- a/content/browser/fileapi/file_system_url_loader_factory.cc +++ b/content/browser/fileapi/file_system_url_loader_factory.cc
@@ -522,7 +522,6 @@ SniffMimeType(file_data_->data(), result, url_.ToGURL(), type_hint, net::ForceSniffFileUrlsForHtml::kDisabled, &head_.mime_type); - head_.did_mime_sniff = true; } client_->OnReceiveResponse(head_);
diff --git a/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc b/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc index 980fddb..82cfc276 100644 --- a/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc +++ b/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
@@ -739,7 +739,6 @@ EXPECT_TRUE(client->has_received_completion()); EXPECT_EQ(mime_type_direct, client->response_head().mime_type); - EXPECT_TRUE(client->response_head().did_mime_sniff); } IN_PROC_BROWSER_TEST_F(FileSystemURLLoaderFactoryTest, FileIncognito) {
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index e9d435c..9e0eae5d 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -42,6 +42,7 @@ #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/resource_dispatcher_host_delegate.h" #include "content/public/browser/resource_throttle.h" +#include "content/public/browser/site_isolation_policy.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" @@ -5391,6 +5392,11 @@ // not modify the underlying last committed entry.) Not crashing means that // the test is successful. IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, ReloadOriginalRequest) { + // TODO(lukasza): https://crbug.com/417518: Get tests working with + // --site-per-process. + if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites()) + return; + GURL original_url(embedded_test_server()->GetURL( "/navigation_controller/simple_page_1.html")); EXPECT_TRUE(NavigateToURL(shell(), original_url));
diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc index 31f2ab76..d69de17 100644 --- a/content/browser/gpu/gpu_ipc_browsertests.cc +++ b/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -367,4 +367,24 @@ } #endif +class GpuProcessHostDisableGLBrowserTest : public GpuProcessHostBrowserTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + GpuProcessHostBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII(switches::kUseGL, + gl::kGLImplementationDisabledName); + } +}; + +// Android and CrOS don't support disabling GL. +#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) +IN_PROC_BROWSER_TEST_F(GpuProcessHostDisableGLBrowserTest, CreateAndDestroy) { + DCHECK(!IsChannelEstablished()); + EstablishAndWait(); + base::RunLoop run_loop; + StopGpuProcess(run_loop.QuitClosure()); + run_loop.Run(); +} +#endif + } // namespace content
diff --git a/content/browser/loader/loader_browsertest.cc b/content/browser/loader/loader_browsertest.cc index 024fade..2a7dd5c 100644 --- a/content/browser/loader/loader_browsertest.cc +++ b/content/browser/loader/loader_browsertest.cc
@@ -25,6 +25,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/resource_dispatcher_host_delegate.h" #include "content/public/browser/resource_request_info.h" +#include "content/public/browser/site_isolation_policy.h" #include "content/public/browser/web_contents.h" #include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/previews_state.h" @@ -1172,6 +1173,11 @@ // bypass cookies SameSite=Strict protections by navigating a new window twice. IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CookieSameSiteStrictOpenNewNamedWindowTwice) { + // TODO(lukasza): https://crbug.com/417518: Get tests working with + // --site-per-process. + if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites()) + return; + ASSERT_TRUE(embedded_test_server()->Start()); // 1) Add cookies for 'a.com', one of them with the "SameSite=Strict" option.
diff --git a/content/browser/loader/mime_sniffing_resource_handler.cc b/content/browser/loader/mime_sniffing_resource_handler.cc index 74707ef3..89e2c53 100644 --- a/content/browser/loader/mime_sniffing_resource_handler.cc +++ b/content/browser/loader/mime_sniffing_resource_handler.cc
@@ -250,7 +250,6 @@ // the mime type. However, even if it returns false, it returns a new type // that is probably better than the current one. response_->head.mime_type.assign(new_type); - response_->head.did_mime_sniff = true; if (!made_final_decision && (bytes_read > 0)) { controller->Resume();
diff --git a/content/browser/loader/mime_sniffing_resource_handler_unittest.cc b/content/browser/loader/mime_sniffing_resource_handler_unittest.cc index 6d23266..6ac3538 100644 --- a/content/browser/loader/mime_sniffing_resource_handler_unittest.cc +++ b/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
@@ -473,8 +473,6 @@ EXPECT_EQ(1, test_handler->on_will_read_called()); EXPECT_EQ(1, test_handler->on_read_completed_called()); - EXPECT_TRUE(test_handler->resource_response()->head.did_mime_sniff); - // Process all messages to ensure proper test teardown. content::RunAllPendingInMessageLoop(); } @@ -603,8 +601,6 @@ EXPECT_EQ(1, test_handler->on_will_read_called()); EXPECT_EQ(1, test_handler->on_read_completed_called()); - EXPECT_FALSE(test_handler->resource_response()->head.did_mime_sniff); - if (!read_completed) { EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader.status()); EXPECT_EQ(net::ERR_ABORTED, mock_loader.error_code());
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 6f423f6..7b97b04 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -40,7 +40,6 @@ #include "content/browser/web_package/signed_exchange_utils.h" #include "content/browser/webui/url_data_manager_backend.h" #include "content/browser/webui/web_ui_url_loader_factory_internal.h" -#include "content/common/mime_sniffing_throttle.h" #include "content/common/navigation_subresource_loader_params.h" #include "content/common/net/record_load_histograms.h" #include "content/common/throttling_url_loader.h" @@ -696,14 +695,11 @@ // |interceptor| wants to handle the request with // |single_request_handler|. DCHECK(interceptor); - std::vector<std::unique_ptr<content::URLLoaderThrottle>> throttles = - CreateURLLoaderThrottles(); - throttles.push_back(std::make_unique<MimeSniffingThrottle>()); default_loader_used_ = false; url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( base::MakeRefCounted<SingleRequestURLLoaderFactory>( std::move(single_request_handler)), - std::move(throttles), frame_tree_node_id_, + CreateURLLoaderThrottles(), frame_tree_node_id_, global_request_id_.request_id, network::mojom::kURLLoadOptionNone, resource_request_.get(), this, kNavigationUrlLoaderTrafficAnnotation, base::ThreadTaskRunnerHandle::Get());
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc index d11f55bf0f..a6d33ec2 100644 --- a/content/browser/loader/resource_dispatcher_host_unittest.cc +++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -2011,7 +2011,6 @@ client.RunUntilResponseReceived(); EXPECT_EQ("text/html", client.response_head().mime_type); - EXPECT_TRUE(client.response_head().did_mime_sniff); } // Tests that we don't sniff the mime type when the server provides one. @@ -2033,7 +2032,6 @@ client.RunUntilResponseReceived(); EXPECT_EQ("image/jpeg", client.response_head().mime_type); - EXPECT_FALSE(client.response_head().did_mime_sniff); } // Tests that we don't sniff the mime type when there is no message body.
diff --git a/content/browser/renderer_host/input/fling_controller.cc b/content/browser/renderer_host/input/fling_controller.cc index ba00279..2729115 100644 --- a/content/browser/renderer_host/input/fling_controller.cc +++ b/content/browser/renderer_host/input/fling_controller.cc
@@ -449,6 +449,11 @@ return fling_booster_ && fling_booster_->fling_cancellation_is_deferred(); } +bool FlingController::TouchscreenFlingInProgress() const { + return fling_in_progress_ && current_fling_parameters_.source_device == + blink::kWebGestureDeviceTouchscreen; +} + gfx::Vector2dF FlingController::CurrentFlingVelocity() const { return current_fling_parameters_.velocity; }
diff --git a/content/browser/renderer_host/input/fling_controller.h b/content/browser/renderer_host/input/fling_controller.h index 03288332..869e17b 100644 --- a/content/browser/renderer_host/input/fling_controller.h +++ b/content/browser/renderer_host/input/fling_controller.h
@@ -99,6 +99,8 @@ bool FlingCancellationIsDeferred() const; + bool TouchscreenFlingInProgress() const; + gfx::Vector2dF CurrentFlingVelocity() const; // Returns the |TouchpadTapSuppressionController| instance.
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc index 93347d9..a9ff466e 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.cc +++ b/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -94,6 +94,9 @@ return fling_controller_.FlingCancellationIsDeferred(); } +bool GestureEventQueue::TouchscreenFlingInProgress() const { + return fling_controller_.TouchscreenFlingInProgress(); +} gfx::Vector2dF GestureEventQueue::CurrentFlingVelocity() const { return fling_controller_.CurrentFlingVelocity(); }
diff --git a/content/browser/renderer_host/input/gesture_event_queue.h b/content/browser/renderer_host/input/gesture_event_queue.h index 3dec354..f07f3cd 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.h +++ b/content/browser/renderer_host/input/gesture_event_queue.h
@@ -117,6 +117,8 @@ bool FlingCancellationIsDeferred() const; + bool TouchscreenFlingInProgress() const; + gfx::Vector2dF CurrentFlingVelocity() const; void set_debounce_interval_time_ms_for_testing(int interval_ms) {
diff --git a/content/browser/renderer_host/input/input_router_client.h b/content/browser/renderer_host/input/input_router_client.h index 01c2c1f..e714ee3 100644 --- a/content/browser/renderer_host/input/input_router_client.h +++ b/content/browser/renderer_host/input/input_router_client.h
@@ -51,6 +51,9 @@ // from the renderer. virtual void OnSetWhiteListedTouchAction(cc::TouchAction touch_action) = 0; + // Called when a renderer fling has terminated. + virtual void DidStopFlinging() = 0; + // Called when a GSB has started scrolling a viewport. virtual void DidStartScrollingViewport() = 0;
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc index 2028e30..788b74b 100644 --- a/content/browser/renderer_host/input/input_router_impl.cc +++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -257,6 +257,15 @@ client_->DidOverscroll(fling_updated_params); } +void InputRouterImpl::DidStopFlinging() { + DCHECK_GT(active_renderer_fling_count_, 0); + // Note that we're only guaranteed to get a fling end notification from the + // renderer, not from any other consumers. Consequently, the GestureEventQueue + // cannot use this bookkeeping for logic like tap suppression. + --active_renderer_fling_count_; + client_->DidStopFlinging(); +} + void InputRouterImpl::DidStartScrollingViewport() { client_->DidStartScrollingViewport(); } @@ -363,6 +372,10 @@ output_stream_validator_.Validate(touch_event); } +bool InputRouterImpl::TouchscreenFlingInProgress() { + return gesture_event_queue_.TouchscreenFlingInProgress(); +} + void InputRouterImpl::SendGestureEventImmediately( const GestureEventWithLatencyInfo& gesture_event) { mojom::WidgetInputHandler::DispatchEventCallback callback = base::BindOnce( @@ -548,6 +561,11 @@ InputEventAckStateToString(state)); if (source != InputEventAckSource::BROWSER) client_->DecrementInFlightEventCount(source); + if (gesture_event.event.GetType() == + blink::WebInputEvent::kGestureFlingStart && + state == INPUT_EVENT_ACK_STATE_CONSUMED) { + ++active_renderer_fling_count_; + } if (overscroll) { DCHECK_EQ(WebInputEvent::kGestureScrollUpdate,
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h index b954551..53605ce 100644 --- a/content/browser/renderer_host/input/input_router_impl.h +++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -93,6 +93,7 @@ uint32_t unique_touch_event_id, InputEventAckState state) override; void DidOverscroll(const ui::DidOverscrollParams& params) override; + void DidStopFlinging() override; void ImeCancelComposition() override; void DidStartScrollingViewport() override; void ImeCompositionRangeChanged( @@ -126,6 +127,7 @@ InputEventAckSource ack_source, InputEventAckState ack_result) override; void OnFilteringTouchEvent(const blink::WebTouchEvent& touch_event) override; + bool TouchscreenFlingInProgress() override; // GestureEventFilterClient void SendGestureEventImmediately(
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc index b6b236d1..a4df1ae 100644 --- a/content/browser/renderer_host/input/input_router_impl_unittest.cc +++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -134,6 +134,8 @@ input_router_client_.DidOverscroll(params); } + void DidStopFlinging() override { input_router_client_.DidStopFlinging(); } + void DidStartScrollingViewport() override { input_router_client_.DidStartScrollingViewport(); }
diff --git a/content/browser/renderer_host/input/mock_input_router_client.cc b/content/browser/renderer_host/input/mock_input_router_client.cc index 3d93e01..33168e9 100644 --- a/content/browser/renderer_host/input/mock_input_router_client.cc +++ b/content/browser/renderer_host/input/mock_input_router_client.cc
@@ -60,6 +60,9 @@ white_listed_touch_action_ = white_listed_touch_action; } +void MockInputRouterClient::DidStopFlinging() { +} + void MockInputRouterClient::DidStartScrollingViewport() {} void MockInputRouterClient::ForwardGestureEventWithLatencyInfo(
diff --git a/content/browser/renderer_host/input/mock_input_router_client.h b/content/browser/renderer_host/input/mock_input_router_client.h index 1ddce1a..8e161f5 100644 --- a/content/browser/renderer_host/input/mock_input_router_client.h +++ b/content/browser/renderer_host/input/mock_input_router_client.h
@@ -33,6 +33,7 @@ void OnHasTouchEventHandlers(bool has_handlers) override; void DidOverscroll(const ui::DidOverscrollParams& params) override; void OnSetWhiteListedTouchAction(cc::TouchAction touch_action) override; + void DidStopFlinging() override; void DidStartScrollingViewport() override; void ForwardWheelEventWithLatencyInfo( const blink::WebMouseWheelEvent& wheel_event,
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue.h b/content/browser/renderer_host/input/passthrough_touch_event_queue.h index 65d881e..bc5f793 100644 --- a/content/browser/renderer_host/input/passthrough_touch_event_queue.h +++ b/content/browser/renderer_host/input/passthrough_touch_event_queue.h
@@ -33,6 +33,8 @@ virtual void OnFilteringTouchEvent( const blink::WebTouchEvent& touch_event) = 0; + + virtual bool TouchscreenFlingInProgress() = 0; }; // A queue that processes a touch-event and forwards it on to the
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc index 718e02b..3f23c3a3 100644 --- a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc +++ b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
@@ -94,6 +94,8 @@ void OnFilteringTouchEvent(const blink::WebTouchEvent& touch_event) override { } + bool TouchscreenFlingInProgress() override { return false; } + protected: void SetUpForTouchMoveSlopTesting(double slop_length_dips) { slop_length_dips_ = slop_length_dips;
diff --git a/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc b/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc index 3fcb804a..63924d8 100644 --- a/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc +++ b/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc
@@ -46,16 +46,7 @@ weak_factory_.GetWeakPtr())); } -PepperNetworkProxyHost::~PepperNetworkProxyHost() { - while (!pending_requests_.empty()) { - // If the proxy_resolution_service_ is NULL, we shouldn't have any outstanding - // requests. - DCHECK(proxy_resolution_service_); - net::ProxyResolutionService::Request* request = pending_requests_.front(); - proxy_resolution_service_->CancelRequest(request); - pending_requests_.pop(); - } -} +PepperNetworkProxyHost::~PepperNetworkProxyHost() = default; PepperNetworkProxyHost::UIThreadData::UIThreadData() : is_allowed(false) {} @@ -139,7 +130,7 @@ } else { // Everything looks valid, so try to resolve the proxy. net::ProxyInfo* proxy_info = new net::ProxyInfo; - net::ProxyResolutionService::Request* pending_request = nullptr; + std::unique_ptr<net::ProxyResolutionService::Request> pending_request; base::Callback<void(int)> callback = base::Bind(&PepperNetworkProxyHost::OnResolveProxyCompleted, weak_factory_.GetWeakPtr(), @@ -148,7 +139,7 @@ int result = proxy_resolution_service_->ResolveProxy( request.url, std::string(), proxy_info, callback, &pending_request, nullptr, net::NetLogWithSource()); - pending_requests_.push(pending_request); + pending_requests_.push(std::move(pending_request)); // If it was handled synchronously, we must run the callback now; // proxy_resolution_service_ won't run it for us in this case. if (result != net::ERR_IO_PENDING)
diff --git a/content/browser/renderer_host/pepper/pepper_network_proxy_host.h b/content/browser/renderer_host/pepper/pepper_network_proxy_host.h index a3b9424ae..f1c5fe68 100644 --- a/content/browser/renderer_host/pepper/pepper_network_proxy_host.h +++ b/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
@@ -99,7 +99,8 @@ // Requests awaiting a response from ProxyResolutionService. We need to store // these so that we can cancel them if we get destroyed. - base::queue<net::ProxyResolutionService::Request*> pending_requests_; + base::queue<std::unique_ptr<net::ProxyResolutionService::Request>> + pending_requests_; base::WeakPtrFactory<PepperNetworkProxyHost> weak_factory_;
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 8ac129f..89e3ced 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -713,7 +713,7 @@ // Returns the keyboard layout mapping. base::flat_map<std::string, std::string> GetKeyboardLayoutMap(); - void DidStopFlinging(); + void DidStopFlinging() override; void GetContentRenderingTimeoutFrom(RenderWidgetHostImpl* other);
diff --git a/content/browser/resolve_proxy_msg_helper.cc b/content/browser/resolve_proxy_msg_helper.cc index 347e7efea..7b77c5f 100644 --- a/content/browser/resolve_proxy_msg_helper.cc +++ b/content/browser/resolve_proxy_msg_helper.cc
@@ -44,44 +44,28 @@ StartPendingRequest(); } -ResolveProxyMsgHelper::~ResolveProxyMsgHelper() { - // Clear all pending requests if the ProxyResolutionService is still alive (if - // we have a default request context or override). - if (!pending_requests_.empty()) { - PendingRequest req = pending_requests_.front(); - proxy_resolution_service_->CancelRequest(req.request); - } - - for (PendingRequestList::iterator it = pending_requests_.begin(); - it != pending_requests_.end(); - ++it) { - delete it->reply_msg; - } - - pending_requests_.clear(); -} +ResolveProxyMsgHelper::~ResolveProxyMsgHelper() = default; void ResolveProxyMsgHelper::OnResolveProxyCompleted(int result) { CHECK(!pending_requests_.empty()); - const PendingRequest& completed_req = pending_requests_.front(); - ViewHostMsg_ResolveProxy::WriteReplyParams( - completed_req.reply_msg, result == net::OK, proxy_info_.ToPacString()); - Send(completed_req.reply_msg); - // Clear the current (completed) request. + PendingRequest completed_req = std::move(pending_requests_.front()); pending_requests_.pop_front(); + ViewHostMsg_ResolveProxy::WriteReplyParams(completed_req.reply_msg.get(), + result == net::OK, + proxy_info_.ToPacString()); + Send(completed_req.reply_msg.release()); + // Start the next request. if (!pending_requests_.empty()) StartPendingRequest(); } void ResolveProxyMsgHelper::StartPendingRequest() { - PendingRequest& req = pending_requests_.front(); - // Verify the request wasn't started yet. - DCHECK(nullptr == req.request); + DCHECK(nullptr == pending_requests_.front().request); if (context_getter_.get()) { proxy_resolution_service_ = context_getter_->GetURLRequestContext()->proxy_resolution_service(); @@ -90,14 +74,26 @@ // Start the request. int result = proxy_resolution_service_->ResolveProxy( - req.url, std::string(), &proxy_info_, + pending_requests_.front().url, std::string(), &proxy_info_, base::BindOnce(&ResolveProxyMsgHelper::OnResolveProxyCompleted, base::Unretained(this)), - &req.request, nullptr, net::NetLogWithSource()); + &pending_requests_.front().request, nullptr, net::NetLogWithSource()); // Completed synchronously. if (result != net::ERR_IO_PENDING) OnResolveProxyCompleted(result); } +ResolveProxyMsgHelper::PendingRequest::PendingRequest(const GURL& url, + IPC::Message* reply_msg) + : url(url), reply_msg(reply_msg) {} + +ResolveProxyMsgHelper::PendingRequest::PendingRequest( + PendingRequest&& pending_request) = default; + +ResolveProxyMsgHelper::PendingRequest::~PendingRequest() noexcept = default; + +ResolveProxyMsgHelper::PendingRequest& ResolveProxyMsgHelper::PendingRequest:: +operator=(PendingRequest&& pending_request) noexcept = default; + } // namespace content
diff --git a/content/browser/resolve_proxy_msg_helper.h b/content/browser/resolve_proxy_msg_helper.h index 8eacab90..ae5c0ff7 100644 --- a/content/browser/resolve_proxy_msg_helper.h +++ b/content/browser/resolve_proxy_msg_helper.h
@@ -58,17 +58,23 @@ // A PendingRequest is a resolve request that is in progress, or queued. struct PendingRequest { public: - PendingRequest(const GURL& url, IPC::Message* reply_msg) - : url(url), reply_msg(reply_msg), request(NULL) {} + PendingRequest(const GURL& url, IPC::Message* reply_msg); + PendingRequest(PendingRequest&& pending_request) noexcept; + ~PendingRequest(); + + PendingRequest& operator=(PendingRequest&& pending_request) noexcept; // The URL of the request. GURL url; // Data to pass back to the delegate on completion (we own it until then). - IPC::Message* reply_msg; + std::unique_ptr<IPC::Message> reply_msg; // Handle for cancelling the current request if it has started (else NULL). - net::ProxyResolutionService::Request* request; + std::unique_ptr<net::ProxyResolutionService::Request> request; + + private: + DISALLOW_COPY_AND_ASSIGN(PendingRequest); }; // Info about the current outstanding proxy request.
diff --git a/content/browser/shared_worker/shared_worker_service_impl_unittest.cc b/content/browser/shared_worker/shared_worker_service_impl_unittest.cc index cf56ef37..e5d67bd 100644 --- a/content/browser/shared_worker/shared_worker_service_impl_unittest.cc +++ b/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
@@ -21,6 +21,7 @@ #include "content/test/test_render_view_host.h" #include "content/test/test_web_contents.h" #include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/test_support/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/message_port/message_port_channel.h" @@ -29,6 +30,42 @@ namespace content { +namespace { + +// A mock URLLoaderFactory which just fails to create a loader. This is +// sufficient because the tests don't exercise script loading. Used when +// S13nServiceWorker is enabled. +class NotImplementedNetworkURLLoaderFactory final + : public network::mojom::URLLoaderFactory { + public: + NotImplementedNetworkURLLoaderFactory() = default; + + // network::mojom::URLLoaderFactory implementation. + void CreateLoaderAndStart(network::mojom::URLLoaderRequest request, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& url_request, + network::mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& + traffic_annotation) override { + network::URLLoaderCompletionStatus status; + status.error_code = net::ERR_NOT_IMPLEMENTED; + client->OnComplete(status); + } + + void Clone(network::mojom::URLLoaderFactoryRequest request) override { + bindings_.AddBinding(this, std::move(request)); + } + + private: + mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_; + + DISALLOW_COPY_AND_ASSIGN(NotImplementedNetworkURLLoaderFactory); +}; + +} // namespace + class SharedWorkerServiceImplTest : public RenderViewHostImplTestHarness { public: mojom::SharedWorkerConnectorPtr MakeSharedWorkerConnector( @@ -75,6 +112,8 @@ std::make_unique<MockRenderProcessHostFactory>(); RenderProcessHostImpl::set_render_process_host_factory_for_testing( render_process_host_factory_.get()); + url_loader_factory_ = + std::make_unique<NotImplementedNetworkURLLoaderFactory>(); } void TearDown() override { @@ -86,6 +125,7 @@ static std::queue<mojom::SharedWorkerFactoryRequest> s_factory_request_received_; std::unique_ptr<MockRenderProcessHostFactory> render_process_host_factory_; + std::unique_ptr<NotImplementedNetworkURLLoaderFactory> url_loader_factory_; private: DISALLOW_COPY_AND_ASSIGN(SharedWorkerServiceImplTest); @@ -127,6 +167,7 @@ renderer_host->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host->OverrideURLLoaderFactory(url_loader_factory_.get()); MockSharedWorkerClient client; MessagePortChannel local_port; @@ -202,6 +243,7 @@ renderer_host0->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); MockSharedWorkerClient client0; MessagePortChannel local_port0; @@ -270,6 +312,7 @@ renderer_host1->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host1->OverrideURLLoaderFactory(url_loader_factory_.get()); MockSharedWorkerClient client1; MessagePortChannel local_port1; @@ -331,6 +374,7 @@ renderer_host0->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); // The second renderer host. std::unique_ptr<TestWebContents> web_contents1 = @@ -402,6 +446,7 @@ renderer_host0->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); // The second renderer host. std::unique_ptr<TestWebContents> web_contents1 = @@ -411,6 +456,7 @@ renderer_host1->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host1->OverrideURLLoaderFactory(url_loader_factory_.get()); // First client, creates worker. @@ -485,6 +531,7 @@ renderer_host0->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); // The second renderer host. std::unique_ptr<TestWebContents> web_contents1 = @@ -494,6 +541,7 @@ renderer_host1->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host1->OverrideURLLoaderFactory(url_loader_factory_.get()); // First client, creates worker. @@ -567,6 +615,7 @@ renderer_host0->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); // The second renderer host. std::unique_ptr<TestWebContents> web_contents1 = @@ -576,6 +625,7 @@ renderer_host1->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host1->OverrideURLLoaderFactory(url_loader_factory_.get()); // First client and second client are created before the worker starts. @@ -640,6 +690,7 @@ renderer_host0->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); // The second renderer host. std::unique_ptr<TestWebContents> web_contents1 = @@ -649,6 +700,7 @@ renderer_host1->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host1->OverrideURLLoaderFactory(url_loader_factory_.get()); // First client and second client are created before the workers start. @@ -727,6 +779,7 @@ renderer_host0->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); // The second renderer host. std::unique_ptr<TestWebContents> web_contents1 = @@ -736,6 +789,7 @@ renderer_host1->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host1->OverrideURLLoaderFactory(url_loader_factory_.get()); // First client and second client are created before the workers start. @@ -814,6 +868,7 @@ renderer_host0->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); std::unique_ptr<TestWebContents> web_contents1 = CreateWebContents(GURL("http://example.com/")); @@ -822,6 +877,7 @@ renderer_host1->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host1->OverrideURLLoaderFactory(url_loader_factory_.get()); std::unique_ptr<TestWebContents> web_contents2 = CreateWebContents(GURL("http://example.com/")); @@ -830,6 +886,7 @@ renderer_host2->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host2->OverrideURLLoaderFactory(url_loader_factory_.get()); MockSharedWorkerClient client0; MessagePortChannel local_port0; @@ -922,6 +979,7 @@ renderer_host0->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); std::unique_ptr<TestWebContents> web_contents1 = CreateWebContents(GURL("http://example.com/")); @@ -930,6 +988,7 @@ renderer_host1->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host1->OverrideURLLoaderFactory(url_loader_factory_.get()); std::unique_ptr<TestWebContents> web_contents2 = CreateWebContents(GURL("http://example.com/")); @@ -938,6 +997,7 @@ renderer_host2->OverrideBinderForTesting( mojom::SharedWorkerFactory::Name_, base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host2->OverrideURLLoaderFactory(url_loader_factory_.get()); MockSharedWorkerClient client0; MessagePortChannel local_port0; @@ -1007,6 +1067,7 @@ mojom::SharedWorkerFactory::Name_, base::BindRepeating( &SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host0->OverrideURLLoaderFactory(url_loader_factory_.get()); // The second renderer host. std::unique_ptr<TestWebContents> web_contents1 = @@ -1017,6 +1078,7 @@ mojom::SharedWorkerFactory::Name_, base::BindRepeating( &SharedWorkerServiceImplTest::BindSharedWorkerFactory)); + renderer_host1->OverrideURLLoaderFactory(url_loader_factory_.get()); // Both clients try to connect/create a worker.
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index ffe38296..cf983f0 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -210,10 +210,6 @@ "media/midi_messages.h", "media/peer_connection_tracker_messages.h", "media/video_capture.h", - "mime_sniffing_throttle.cc", - "mime_sniffing_throttle.h", - "mime_sniffing_url_loader.cc", - "mime_sniffing_url_loader.h", "navigation_gesture.h", "navigation_params.cc", "navigation_params.h",
diff --git a/content/common/DEPS b/content/common/DEPS index 5f9362d..03fa018 100644 --- a/content/common/DEPS +++ b/content/common/DEPS
@@ -84,8 +84,3 @@ "+third_party/blink/public/web/web_triggering_event_info.h", "+third_party/blink/public/web/win/web_font_rendering.h", ] -specific_include_rules = { - '.*_unittest.*': [ - "+services/network/test", - ] -}
diff --git a/content/common/input/input_handler.mojom b/content/common/input/input_handler.mojom index bbf17cd..389e82b6 100644 --- a/content/common/input/input_handler.mojom +++ b/content/common/input/input_handler.mojom
@@ -174,6 +174,9 @@ // restrictions on the root scroll offset. DidOverscroll(DidOverscrollParams params); + // Sent by the compositor when a fling animation is stopped. + DidStopFlinging(); + // Sent by the compositor when a GSB has started scrolling the viewport. DidStartScrollingViewport();
diff --git a/content/common/mime_sniffing_throttle.cc b/content/common/mime_sniffing_throttle.cc deleted file mode 100644 index dfeabde..0000000 --- a/content/common/mime_sniffing_throttle.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/mime_sniffing_throttle.h" - -#include "content/common/mime_sniffing_url_loader.h" -#include "net/base/mime_sniffer.h" - -namespace content { - -MimeSniffingThrottle::MimeSniffingThrottle() : weak_factory_(this) {} - -MimeSniffingThrottle::~MimeSniffingThrottle() = default; - -void MimeSniffingThrottle::WillProcessResponse( - const GURL& response_url, - const network::ResourceResponseHead& response_head, - bool* defer) { - // No need to do mime sniffing again. - if (response_head.did_mime_sniff) - return; - - bool blocked_sniffing_mime = false; - std::string content_type_options; - if (response_head.headers && - response_head.headers->GetNormalizedHeader("x-content-type-options", - &content_type_options)) { - blocked_sniffing_mime = - base::LowerCaseEqualsASCII(content_type_options, "nosniff"); - } - - if (!blocked_sniffing_mime && - net::ShouldSniffMimeType(response_url, response_head.mime_type)) { - // Pause the response until the mime type becomes ready. - *defer = true; - - network::mojom::URLLoaderPtr new_loader; - network::mojom::URLLoaderClientRequest new_loader_request; - network::mojom::URLLoaderPtr source_loader; - network::mojom::URLLoaderClientRequest source_client_request; - MimeSniffingURLLoader* mime_sniffing_loader; - std::tie(new_loader, new_loader_request, mime_sniffing_loader) = - MimeSniffingURLLoader::CreateLoader(weak_factory_.GetWeakPtr(), - response_url, response_head); - delegate_->InterceptResponse(std::move(new_loader), - std::move(new_loader_request), &source_loader, - &source_client_request); - mime_sniffing_loader->Start(std::move(source_loader), - std::move(source_client_request)); - } -} - -void MimeSniffingThrottle::ResumeWithNewResponseHead( - const network::ResourceResponseHead& new_response_head) { - delegate_->UpdateDeferredResponseHead(new_response_head); - delegate_->Resume(); -} - -} // namespace content
diff --git a/content/common/mime_sniffing_throttle.h b/content/common/mime_sniffing_throttle.h deleted file mode 100644 index f8f35189..0000000 --- a/content/common/mime_sniffing_throttle.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_MIME_SNIFFING_THROTTLE_H_ -#define CONTENT_COMMON_MIME_SNIFFING_THROTTLE_H_ - -#include "base/memory/weak_ptr.h" -#include "content/common/content_export.h" -#include "content/public/common/url_loader_throttle.h" - -namespace content { - -// Throttle for mime type sniffing. This may intercept the request and -// modify the response's mime type in the response head. -class CONTENT_EXPORT MimeSniffingThrottle : public URLLoaderThrottle { - public: - MimeSniffingThrottle(); - ~MimeSniffingThrottle() override; - - // Implements URLLoaderThrottle. - void WillProcessResponse(const GURL& response_url, - const network::ResourceResponseHead& response_head, - bool* defer) override; - - // Called from MimeSniffingURLLoader once mime type is ready. - void ResumeWithNewResponseHead( - const network::ResourceResponseHead& new_response_head); - - private: - base::WeakPtrFactory<MimeSniffingThrottle> weak_factory_; -}; - -} // namespace content - -#endif // CONTENT_COMMON_MIME_SNIFFING_THROTTLE_H_
diff --git a/content/common/mime_sniffing_throttle_unittest.cc b/content/common/mime_sniffing_throttle_unittest.cc deleted file mode 100644 index 0e61e99..0000000 --- a/content/common/mime_sniffing_throttle_unittest.cc +++ /dev/null
@@ -1,429 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/mime_sniffing_throttle.h" - -#include <memory> - -#include "base/run_loop.h" -#include "base/test/scoped_task_environment.h" -#include "content/common/mime_sniffing_url_loader.h" -#include "content/public/common/url_loader_throttle.h" -#include "mojo/public/cpp/system/data_pipe_utils.h" -#include "services/network/test/test_url_loader_client.h" -#include "services/network/test/test_url_loader_factory.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace content { - -namespace { - -class MojoDataPipeSender { - public: - MojoDataPipeSender(mojo::ScopedDataPipeProducerHandle handle) - : handle_(std::move(handle)), - watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {} - - void Start(std::string data, base::OnceClosure done_callback) { - data_ = std::move(data); - done_callback_ = std::move(done_callback); - watcher_.Watch(handle_.get(), - MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - base::BindRepeating(&MojoDataPipeSender::OnWritable, - base::Unretained(this))); - } - - void OnWritable(MojoResult) { - uint32_t sending_bytes = data_.size() - sent_bytes_; - MojoResult result = handle_->WriteData( - data_.c_str() + sent_bytes_, &sending_bytes, MOJO_WRITE_DATA_FLAG_NONE); - switch (result) { - case MOJO_RESULT_OK: - break; - case MOJO_RESULT_FAILED_PRECONDITION: - // Finished unexpectedly. - std::move(done_callback_).Run(); - return; - case MOJO_RESULT_SHOULD_WAIT: - // Just wait until OnWritable() is called by the watcher. - return; - default: - NOTREACHED(); - return; - } - sent_bytes_ += sending_bytes; - if (data_.size() == sent_bytes_) - std::move(done_callback_).Run(); - } - - mojo::ScopedDataPipeProducerHandle ReleaseHandle() { - return std::move(handle_); - } - - bool has_succeeded() const { return data_.size() == sent_bytes_; } - - private: - mojo::ScopedDataPipeProducerHandle handle_; - mojo::SimpleWatcher watcher_; - base::OnceClosure done_callback_; - std::string data_; - uint32_t sent_bytes_ = 0; -}; - -class MockDelegate : public URLLoaderThrottle::Delegate { - public: - // Implements URLLoaderThrottle::Delegate. - void CancelWithError(int error_code, - base::StringPiece custom_reason) override { - NOTIMPLEMENTED(); - } - void Resume() override { - is_resumed_ = true; - // Resume from OnReceiveResponse() with a customized response header. - destination_loader_client()->OnReceiveResponse( - updated_response_head().value()); - } - - void SetPriority(net::RequestPriority priority) override { NOTIMPLEMENTED(); } - void UpdateDeferredResponseHead( - const network::ResourceResponseHead& new_response_head) override { - updated_response_head_ = new_response_head; - } - void PauseReadingBodyFromNet() override { NOTIMPLEMENTED(); } - void ResumeReadingBodyFromNet() override { NOTIMPLEMENTED(); } - void InterceptResponse( - network::mojom::URLLoaderPtr new_loader, - network::mojom::URLLoaderClientRequest new_client_request, - network::mojom::URLLoaderPtr* original_loader, - network::mojom::URLLoaderClientRequest* original_client_request) - override { - is_intercepted_ = true; - - destination_loader_ptr_ = std::move(new_loader); - ASSERT_TRUE(mojo::FuseInterface( - std::move(new_client_request), - destination_loader_client_.CreateInterfacePtr().PassInterface())); - source_loader_request_ = mojo::MakeRequest(original_loader); - *original_client_request = mojo::MakeRequest(&source_loader_client_ptr_); - } - - void LoadResponseBody(const std::string& body) { - if (!source_body_handle_.is_valid()) { - // Send OnStartLoadingResponseBody() if it's the first call. - mojo::ScopedDataPipeConsumerHandle consumer; - EXPECT_EQ(MOJO_RESULT_OK, - mojo::CreateDataPipe(nullptr, &source_body_handle_, &consumer)); - source_loader_client()->OnStartLoadingResponseBody(std::move(consumer)); - } - - MojoDataPipeSender sender(std::move(source_body_handle_)); - base::RunLoop loop; - sender.Start(body, loop.QuitClosure()); - loop.Run(); - - EXPECT_TRUE(sender.has_succeeded()); - source_body_handle_ = sender.ReleaseHandle(); - } - - void CompleteResponse() { - source_loader_client()->OnComplete(network::URLLoaderCompletionStatus()); - source_body_handle_.reset(); - } - - uint32_t ReadResponseBody(uint32_t size) { - std::vector<uint8_t> buffer(size); - MojoResult result = destination_loader_client_.response_body().ReadData( - buffer.data(), &size, MOJO_READ_DATA_FLAG_NONE); - switch (result) { - case MOJO_RESULT_OK: - return size; - case MOJO_RESULT_FAILED_PRECONDITION: - return 0; - case MOJO_RESULT_SHOULD_WAIT: - return 0; - default: - NOTREACHED(); - } - return 0; - } - - bool is_intercepted() const { return is_intercepted_; } - bool is_resumed() const { return is_resumed_; } - - const base::Optional<network::ResourceResponseHead>& updated_response_head() - const { - return updated_response_head_; - } - - network::TestURLLoaderClient* destination_loader_client() { - return &destination_loader_client_; - } - - network::mojom::URLLoaderClient* source_loader_client() { - return source_loader_client_ptr_.get(); - } - - private: - bool is_intercepted_ = false; - bool is_resumed_ = false; - base::Optional<network::ResourceResponseHead> updated_response_head_; - - // A pair of a loader and a loader client for destination of the response. - network::mojom::URLLoaderPtr destination_loader_ptr_; - network::TestURLLoaderClient destination_loader_client_; - - // A pair of a loader and a loader client for source of the response. - network::mojom::URLLoaderClientPtr source_loader_client_ptr_; - network::mojom::URLLoaderRequest source_loader_request_; - - mojo::ScopedDataPipeProducerHandle source_body_handle_; -}; - -} // namespace - -class MimeSniffingThrottleTest : public testing::Test { - protected: - // Be the first member so it is destroyed last. - base::test::ScopedTaskEnvironment scoped_task_environment_; -}; - -TEST_F(MimeSniffingThrottleTest, NoMimeTypeWithSniffableScheme) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - network::ResourceResponseHead response_head; - bool defer = false; - throttle->WillProcessResponse(GURL("https://example.com"), response_head, - &defer); - EXPECT_TRUE(defer); - EXPECT_TRUE(delegate->is_intercepted()); -} - -TEST_F(MimeSniffingThrottleTest, SniffableMimeTypeWithSniffableScheme) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - network::ResourceResponseHead response_head; - response_head.mime_type = "text/plain"; - bool defer = false; - throttle->WillProcessResponse(GURL("https://example.com"), response_head, - &defer); - EXPECT_TRUE(defer); - EXPECT_TRUE(delegate->is_intercepted()); -} - -TEST_F(MimeSniffingThrottleTest, NotSniffableMimeTypeWithSniffableScheme) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - network::ResourceResponseHead response_head; - response_head.mime_type = "text/javascript"; - bool defer = false; - throttle->WillProcessResponse(GURL("https://example.com"), response_head, - &defer); - EXPECT_FALSE(defer); - EXPECT_FALSE(delegate->is_intercepted()); -} - -TEST_F(MimeSniffingThrottleTest, NoMimeTypeWithNotSniffableScheme) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - network::ResourceResponseHead response_head; - bool defer = false; - throttle->WillProcessResponse(GURL("wss://example.com"), response_head, - &defer); - EXPECT_FALSE(defer); - EXPECT_FALSE(delegate->is_intercepted()); -} - -TEST_F(MimeSniffingThrottleTest, SniffableMimeTypeWithNotSniffableScheme) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - network::ResourceResponseHead response_head; - response_head.mime_type = "text/plain"; - bool defer = false; - throttle->WillProcessResponse(GURL("wss://example.com"), response_head, - &defer); - EXPECT_FALSE(defer); - EXPECT_FALSE(delegate->is_intercepted()); -} - -TEST_F(MimeSniffingThrottleTest, NotSniffableMimeTypeWithNotSniffableScheme) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - network::ResourceResponseHead response_head; - response_head.mime_type = "text/javascript"; - bool defer = false; - throttle->WillProcessResponse(GURL("wss://example.com"), response_head, - &defer); - EXPECT_FALSE(defer); - EXPECT_FALSE(delegate->is_intercepted()); -} - -TEST_F(MimeSniffingThrottleTest, SniffableButAlreadySniffed) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - network::ResourceResponseHead response_head; - response_head.mime_type = "text/plain"; - response_head.did_mime_sniff = true; - bool defer = false; - throttle->WillProcessResponse(GURL("https://example.com"), response_head, - &defer); - EXPECT_FALSE(defer); - EXPECT_FALSE(delegate->is_intercepted()); -} - -TEST_F(MimeSniffingThrottleTest, NoBody) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - GURL response_url("https://example.com"); - network::ResourceResponseHead response_head; - bool defer = false; - throttle->WillProcessResponse(response_url, response_head, &defer); - EXPECT_TRUE(defer); - EXPECT_TRUE(delegate->is_intercepted()); - - // Call OnComplete() without sending body. - delegate->source_loader_client()->OnComplete( - network::URLLoaderCompletionStatus()); - delegate->destination_loader_client()->RunUntilComplete(); - - // The mime type should be updated to the default mime type ("text/plain"). - EXPECT_TRUE(delegate->destination_loader_client()->has_received_response()); - EXPECT_EQ("text/plain", - delegate->destination_loader_client()->response_head().mime_type); -} - -TEST_F(MimeSniffingThrottleTest, Body_PlainText) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - GURL response_url("https://example.com"); - network::ResourceResponseHead response_head; - bool defer = false; - throttle->WillProcessResponse(response_url, response_head, &defer); - EXPECT_TRUE(defer); - EXPECT_TRUE(delegate->is_intercepted()); - - // Send the body and complete the response. - delegate->LoadResponseBody("This is a text."); - delegate->CompleteResponse(); - delegate->destination_loader_client()->RunUntilComplete(); - - // The mime type should be updated. - EXPECT_TRUE(delegate->is_resumed()); - EXPECT_EQ("text/plain", - delegate->destination_loader_client()->response_head().mime_type); -} - -TEST_F(MimeSniffingThrottleTest, Body_Docx) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - GURL response_url("https://example.com/hogehoge.docx"); - network::ResourceResponseHead response_head; - bool defer = false; - throttle->WillProcessResponse(response_url, response_head, &defer); - EXPECT_TRUE(defer); - EXPECT_TRUE(delegate->is_intercepted()); - - // Send the body and complete the response. - delegate->LoadResponseBody("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"); - delegate->CompleteResponse(); - delegate->destination_loader_client()->RunUntilComplete(); - - // The mime type should be updated. - EXPECT_TRUE(delegate->is_resumed()); - EXPECT_EQ("application/msword", - delegate->destination_loader_client()->response_head().mime_type); -} - -TEST_F(MimeSniffingThrottleTest, Body_PNG) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - GURL response_url("https://example.com/hogehoge.docx"); - network::ResourceResponseHead response_head; - bool defer = false; - throttle->WillProcessResponse(response_url, response_head, &defer); - EXPECT_TRUE(defer); - EXPECT_TRUE(delegate->is_intercepted()); - - // Send the body and complete the response. - delegate->LoadResponseBody("\x89PNG\x0D\x0A\x1A\x0A"); - delegate->CompleteResponse(); - delegate->destination_loader_client()->RunUntilComplete(); - - // The mime type should be updated. - EXPECT_TRUE(delegate->is_resumed()); - EXPECT_EQ("image/png", - delegate->destination_loader_client()->response_head().mime_type); -} - -TEST_F(MimeSniffingThrottleTest, Body_LongPlainText) { - auto throttle = std::make_unique<MimeSniffingThrottle>(); - auto delegate = std::make_unique<MockDelegate>(); - throttle->set_delegate(delegate.get()); - - GURL response_url("https://example.com"); - network::ResourceResponseHead response_head; - bool defer = false; - throttle->WillProcessResponse(response_url, response_head, &defer); - EXPECT_TRUE(defer); - EXPECT_TRUE(delegate->is_intercepted()); - - // 64KiB is coming from the default value used in - // mojo::core::Core::CreateDataPipe(). - const uint32_t kDefaultDataPipeBufferSize = 64 * 1024; - std::string long_body(kDefaultDataPipeBufferSize * 2, 'x'); - - // Send the data to the MimeSniffingURLLoader. - // |delegate|'s MojoDataPipeSender sends the first - // |kDefaultDataPipeBufferSize| bytes to MimeSniffingURLLoader and - // MimeSniffingURLLoader will read the first |kDefaultDataPipeBufferSize| - // bytes of the body, so the MojoDataPipeSender can push the rest of - // |kDefaultDataPipeBufferSize| of the body soon and finishes sending the - // body. After this, MimeSniffingURLLoader is waiting to push the body to the - // destination data pipe since the pipe should be full until it's read. - delegate->LoadResponseBody(long_body); - scoped_task_environment_.RunUntilIdle(); - - // Read the half of the body. This unblocks MimeSniffingURLLoader to push the - // rest of the body to the data pipe. - uint32_t read_bytes = delegate->ReadResponseBody(long_body.size() / 2); - scoped_task_environment_.RunUntilIdle(); - - // Read the rest of the body. - read_bytes += delegate->ReadResponseBody(long_body.size() / 2); - scoped_task_environment_.RunUntilIdle(); - delegate->CompleteResponse(); - delegate->destination_loader_client()->RunUntilComplete(); - - // Check if all data has been read. - EXPECT_EQ(long_body.size(), read_bytes); - - // The mime type should be updated. - EXPECT_TRUE(delegate->is_resumed()); - EXPECT_EQ("text/plain", - delegate->destination_loader_client()->response_head().mime_type); -} - -} // namespace content
diff --git a/content/common/mime_sniffing_url_loader.cc b/content/common/mime_sniffing_url_loader.cc deleted file mode 100644 index d7c2bce..0000000 --- a/content/common/mime_sniffing_url_loader.cc +++ /dev/null
@@ -1,355 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/mime_sniffing_url_loader.h" - -#include "content/common/mime_sniffing_throttle.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "net/base/mime_sniffer.h" - -namespace content { - -// static -const char MimeSniffingURLLoader::kDefaultMimeType[] = "text/plain"; - -// static -std::tuple<network::mojom::URLLoaderPtr, - network::mojom::URLLoaderClientRequest, - MimeSniffingURLLoader*> -MimeSniffingURLLoader::CreateLoader( - base::WeakPtr<MimeSniffingThrottle> throttle, - const GURL& response_url, - const network::ResourceResponseHead& response_head) { - network::mojom::URLLoaderPtr url_loader; - network::mojom::URLLoaderClientPtr url_loader_client; - network::mojom::URLLoaderClientRequest url_loader_client_request = - mojo::MakeRequest(&url_loader_client); - auto loader = base::WrapUnique( - new MimeSniffingURLLoader(std::move(throttle), response_url, - response_head, std::move(url_loader_client))); - MimeSniffingURLLoader* loader_rawptr = loader.get(); - mojo::MakeStrongBinding(std::move(loader), mojo::MakeRequest(&url_loader)); - return std::make_tuple(std::move(url_loader), - std::move(url_loader_client_request), loader_rawptr); -} - -MimeSniffingURLLoader::MimeSniffingURLLoader( - base::WeakPtr<MimeSniffingThrottle> throttle, - const GURL& response_url, - const network::ResourceResponseHead& response_head, - network::mojom::URLLoaderClientPtr destination_url_loader_client) - : throttle_(throttle), - source_url_client_binding_(this), - destination_url_loader_client_(std::move(destination_url_loader_client)), - response_url_(response_url), - response_head_(response_head), - body_consumer_watcher_(FROM_HERE, - mojo::SimpleWatcher::ArmingPolicy::MANUAL), - body_producer_watcher_(FROM_HERE, - mojo::SimpleWatcher::ArmingPolicy::MANUAL) {} - -MimeSniffingURLLoader::~MimeSniffingURLLoader() = default; - -void MimeSniffingURLLoader::Start( - network::mojom::URLLoaderPtr source_url_loader, - network::mojom::URLLoaderClientRequest source_url_loader_client_request) { - source_url_loader_ = std::move(source_url_loader); - source_url_client_binding_.Bind(std::move(source_url_loader_client_request)); -} - -void MimeSniffingURLLoader::OnReceiveResponse( - const network::ResourceResponseHead& response_head) { - // OnReceiveResponse() shouldn't be called because MimeSniffingURLLoader is - // created by MimeSniffingThrottle::WillProcessResponse(), which is equivalent - // to OnReceiveResponse(). - NOTREACHED(); -} - -void MimeSniffingURLLoader::OnReceiveRedirect( - const net::RedirectInfo& redirect_info, - const network::ResourceResponseHead& response_head) { - // OnReceiveRedirect() shouldn't be called because MimeSniffingURLLoader is - // created by MimeSniffingThrottle::WillProcessResponse(), which is equivalent - // to OnReceiveResponse(). - NOTREACHED(); -} - -void MimeSniffingURLLoader::OnUploadProgress( - int64_t current_position, - int64_t total_size, - OnUploadProgressCallback ack_callback) { - destination_url_loader_client_->OnUploadProgress(current_position, total_size, - std::move(ack_callback)); -} - -void MimeSniffingURLLoader::OnReceiveCachedMetadata( - const std::vector<uint8_t>& data) { - destination_url_loader_client_->OnReceiveCachedMetadata(data); -} - -void MimeSniffingURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) { - destination_url_loader_client_->OnTransferSizeUpdated(transfer_size_diff); -} - -void MimeSniffingURLLoader::OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) { - state_ = State::kSniffing; - body_consumer_handle_ = std::move(body); - body_consumer_watcher_.Watch( - body_consumer_handle_.get(), - MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - base::BindRepeating(&MimeSniffingURLLoader::OnBodyReadable, - base::Unretained(this))); - body_consumer_watcher_.ArmOrNotify(); -} - -void MimeSniffingURLLoader::OnComplete( - const network::URLLoaderCompletionStatus& status) { - DCHECK(!complete_status_.has_value()); - switch (state_) { - case State::kWaitForBody: - // OnComplete() is called without OnStartLoadingResponseBody(). There is - // no response body in this case. Use |kDefaultMimeType| as its mime type - // even though it's empty. - state_ = State::kCompleted; - response_head_.mime_type = kDefaultMimeType; - if (!throttle_) { - Abort(); - return; - } - throttle_->ResumeWithNewResponseHead(response_head_); - destination_url_loader_client_->OnComplete(status); - return; - case State::kSniffing: - // Defer calling OnComplete() since we defer calling - // OnStartLoadingResponseBody() until mime sniffing has been finished. - complete_status_ = status; - return; - case State::kSending: - case State::kCompleted: - destination_url_loader_client_->OnComplete(status); - return; - } - NOTREACHED(); -} - -void MimeSniffingURLLoader::FollowRedirect( - const base::Optional<std::vector<std::string>>& - to_be_removed_request_headers, - const base::Optional<net::HttpRequestHeaders>& modified_request_headers) { - // MimeSniffingURLLoader starts handling the request after - // OnReceivedResponse(). A redirect response is not expected. - NOTREACHED(); -} - -void MimeSniffingURLLoader::ProceedWithResponse() { - source_url_loader_->ProceedWithResponse(); -} - -void MimeSniffingURLLoader::SetPriority(net::RequestPriority priority, - int32_t intra_priority_value) { - source_url_loader_->SetPriority(priority, intra_priority_value); -} - -void MimeSniffingURLLoader::PauseReadingBodyFromNet() { - source_url_loader_->PauseReadingBodyFromNet(); -} - -void MimeSniffingURLLoader::ResumeReadingBodyFromNet() { - source_url_loader_->ResumeReadingBodyFromNet(); -} - -void MimeSniffingURLLoader::OnBodyReadable(MojoResult) { - if (state_ == State::kSending) { - // The pipe becoming readable when kSending means all buffered body has - // already been sent. - ForwardBodyToClient(); - return; - } - DCHECK_EQ(State::kSniffing, state_); - - size_t start_size = buffered_body_.size(); - uint32_t read_bytes = net::kMaxBytesToSniff; - buffered_body_.resize(start_size + read_bytes); - MojoResult result = - body_consumer_handle_->ReadData(buffered_body_.data() + start_size, - &read_bytes, MOJO_READ_DATA_FLAG_NONE); - switch (result) { - case MOJO_RESULT_OK: - break; - case MOJO_RESULT_FAILED_PRECONDITION: - // Finished the body before mime type is completely decided. - buffered_body_.resize(start_size); - CompleteSniffing(); - return; - case MOJO_RESULT_SHOULD_WAIT: - body_consumer_watcher_.ArmOrNotify(); - return; - default: - NOTREACHED(); - return; - } - - DCHECK_EQ(MOJO_RESULT_OK, result); - buffered_body_.resize(start_size + read_bytes); - std::string new_type; - bool made_final_decision = - net::SniffMimeType(buffered_body_.data(), buffered_body_.size(), - response_url_, response_head_.mime_type, - net::ForceSniffFileUrlsForHtml::kDisabled, &new_type); - response_head_.mime_type = new_type; - response_head_.did_mime_sniff = true; - if (made_final_decision) { - CompleteSniffing(); - return; - } - body_consumer_watcher_.ArmOrNotify(); -} - -void MimeSniffingURLLoader::OnBodyWritable(MojoResult) { - DCHECK_EQ(State::kSending, state_); - if (bytes_remaining_in_buffer_ > 0) { - SendReceivedBodyToClient(); - } else { - ForwardBodyToClient(); - } -} - -void MimeSniffingURLLoader::CompleteSniffing() { - DCHECK_EQ(State::kSniffing, state_); - if (buffered_body_.empty()) { - // A data pipe for the body was received but no body was provided. Don't - // propagate OnStartLoadingResponseBody() in this case. We treat this - // situation as the same as when OnStartLoadingResponseBody() was not - // called. - // - // TODO(crbug.com/826868): Remove this once all loaders are aligned. - state_ = State::kWaitForBody; - if (complete_status_.has_value()) { - auto status = complete_status_.value(); - complete_status_.reset(); - OnComplete(status); - } - return; - } - - state_ = State::kSending; - bytes_remaining_in_buffer_ = buffered_body_.size(); - if (!throttle_) { - Abort(); - return; - } - throttle_->ResumeWithNewResponseHead(response_head_); - mojo::ScopedDataPipeConsumerHandle body_to_send; - MojoResult result = - mojo::CreateDataPipe(nullptr, &body_producer_handle_, &body_to_send); - if (result != MOJO_RESULT_OK) { - Abort(); - return; - } - // Set up the watcher for the producer handle. - body_producer_watcher_.Watch( - body_producer_handle_.get(), - MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - base::BindRepeating(&MimeSniffingURLLoader::OnBodyWritable, - base::Unretained(this))); - // Send deferred messages. - destination_url_loader_client_->OnStartLoadingResponseBody( - std::move(body_to_send)); - // Call OnComplete() if OnComplete() has already been called. - if (complete_status_.has_value()) - destination_url_loader_client_->OnComplete(complete_status_.value()); - SendReceivedBodyToClient(); -} - -void MimeSniffingURLLoader::CompleteSending() { - DCHECK_EQ(State::kSending, state_); - state_ = State::kCompleted; - body_consumer_watcher_.Cancel(); - body_producer_watcher_.Cancel(); - body_consumer_handle_.reset(); - body_producer_handle_.reset(); -} - -void MimeSniffingURLLoader::SendReceivedBodyToClient() { - DCHECK_EQ(State::kSending, state_); - // Send the buffered data first. - DCHECK_GT(bytes_remaining_in_buffer_, 0u); - size_t start_position = buffered_body_.size() - bytes_remaining_in_buffer_; - uint32_t bytes_sent = bytes_remaining_in_buffer_; - MojoResult result = - body_producer_handle_->WriteData(buffered_body_.data() + start_position, - &bytes_sent, MOJO_WRITE_DATA_FLAG_NONE); - switch (result) { - case MOJO_RESULT_OK: - break; - case MOJO_RESULT_FAILED_PRECONDITION: - // The pipe is closed unexpectedly. |this| should be deleted once - // URLLoaderPtr on the destination is released. - Abort(); - return; - case MOJO_RESULT_SHOULD_WAIT: - body_producer_watcher_.ArmOrNotify(); - return; - default: - NOTREACHED(); - return; - } - bytes_remaining_in_buffer_ -= bytes_sent; - body_producer_watcher_.ArmOrNotify(); -} - -void MimeSniffingURLLoader::ForwardBodyToClient() { - DCHECK_EQ(0u, bytes_remaining_in_buffer_); - // Send the body from the consumer to the producer. - const void* buffer; - uint32_t buffer_size = 0; - MojoResult result = body_consumer_handle_->BeginReadData( - &buffer, &buffer_size, MOJO_BEGIN_READ_DATA_FLAG_NONE); - switch (result) { - case MOJO_RESULT_OK: - break; - case MOJO_RESULT_SHOULD_WAIT: - body_consumer_watcher_.ArmOrNotify(); - return; - case MOJO_RESULT_FAILED_PRECONDITION: - // All data has been sent. - CompleteSending(); - return; - default: - NOTREACHED(); - return; - } - - result = body_producer_handle_->WriteData(buffer, &buffer_size, - MOJO_WRITE_DATA_FLAG_NONE); - switch (result) { - case MOJO_RESULT_OK: - break; - case MOJO_RESULT_FAILED_PRECONDITION: - // The pipe is closed unexpectedly. |this| should be deleted once - // URLLoaderPtr on the destination is released. - Abort(); - return; - case MOJO_RESULT_SHOULD_WAIT: - body_consumer_handle_->EndReadData(0); - body_producer_watcher_.ArmOrNotify(); - return; - default: - NOTREACHED(); - return; - } - - body_consumer_handle_->EndReadData(buffer_size); - body_consumer_watcher_.ArmOrNotify(); -} - -void MimeSniffingURLLoader::Abort() { - source_url_loader_.reset(); - destination_url_loader_client_.reset(); - // |this| should be removed since the owner will destroy |this| or the owner - // has already been destroyed by some reason. -} - -} // namespace content
diff --git a/content/common/mime_sniffing_url_loader.h b/content/common/mime_sniffing_url_loader.h deleted file mode 100644 index 4e7a3c4..0000000 --- a/content/common/mime_sniffing_url_loader.h +++ /dev/null
@@ -1,145 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_MIME_SNIFFING_URL_LOADER_H_ -#define CONTENT_COMMON_MIME_SNIFFING_URL_LOADER_H_ - -#include <tuple> - -#include "base/callback.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/strings/string_piece.h" -#include "content/common/content_export.h" -#include "content/common/possibly_associated_interface_ptr.h" -#include "content/public/common/url_loader_throttle.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/system/data_pipe.h" -#include "mojo/public/cpp/system/simple_watcher.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "services/network/public/mojom/url_loader.mojom.h" -#include "services/network/public/mojom/url_loader_factory.mojom.h" - -namespace content { - -class MimeSniffingThrottle; - -// Reads the response body and determines its mime type. This url loader buffers -// the response body until the mime type is decided. MimeSniffingURLLoader -// is expected to be created just after receiving OnReceiveResponse(), so this -// handles only OnStartLoadingResponseBody() and OnComplete() as a -// network::mojom::URLLoaderClient. -// -// This loader has four state: -// kWaitForBody: The initial state until the body is received (= -// OnStartLoadingResponseBody() is called) or the response is -// finished (= OnComplete() is called). When body is provided, the -// state is changed to kSniffing. Otherwise the state goes to -// kCompleted. -// kSniffing: Receives the body from the source loader and estimate the mime -// type. The received body is kept in this loader until the mime type -// is decided. When the mime type is decided or all body has been -// received, this loader will dispatch queued messages like -// OnStartLoadingResponseBody() and OnComplete() to the destination -// loader client, and then the state is changed to kSending. -// kSending: Receives the body and send it to the destination loader client. All -// data has been read by this loader, the state goes to kCompleted. -// kCompleted: All data has been sent to the destination loader. -class CONTENT_EXPORT MimeSniffingURLLoader - : public network::mojom::URLLoaderClient, - public network::mojom::URLLoader { - public: - ~MimeSniffingURLLoader() override; - - // Start waiting for the body. - void Start( - network::mojom::URLLoaderPtr source_url_loader, - network::mojom::URLLoaderClientRequest source_url_loader_client_request); - - // network::mojom::URLLoaderPtr controls the lifetime of the loader. - static std::tuple<network::mojom::URLLoaderPtr, - network::mojom::URLLoaderClientRequest, - MimeSniffingURLLoader*> - CreateLoader(base::WeakPtr<MimeSniffingThrottle> throttle, - const GURL& response_url, - const network::ResourceResponseHead& response_head); - - private: - MimeSniffingURLLoader( - base::WeakPtr<MimeSniffingThrottle> throttle, - const GURL& response_url, - const network::ResourceResponseHead& response_head, - network::mojom::URLLoaderClientPtr destination_url_loader_client); - - // network::mojom::URLLoaderClient implementation (called from the source of - // the response): - void OnReceiveResponse( - const network::ResourceResponseHead& response_head) override; - void OnReceiveRedirect( - const net::RedirectInfo& redirect_info, - const network::ResourceResponseHead& response_head) override; - void OnUploadProgress(int64_t current_position, - int64_t total_size, - OnUploadProgressCallback ack_callback) override; - void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override; - void OnTransferSizeUpdated(int32_t transfer_size_diff) override; - void OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) override; - void OnComplete(const network::URLLoaderCompletionStatus& status) override; - - // network::mojom::URLLoader implementation (called from the destination of - // the response): - void FollowRedirect(const base::Optional<std::vector<std::string>>& - to_be_removed_request_headers, - const base::Optional<net::HttpRequestHeaders>& - modified_request_headers) override; - void ProceedWithResponse() override; - void SetPriority(net::RequestPriority priority, - int32_t intra_priority_value) override; - void PauseReadingBodyFromNet() override; - void ResumeReadingBodyFromNet() override; - - void OnBodyReadable(MojoResult); - void OnBodyWritable(MojoResult); - void CompleteSniffing(); - void CompleteSending(); - void SendReceivedBodyToClient(); - void ForwardBodyToClient(); - - void Abort(); - - static const char kDefaultMimeType[]; - - base::WeakPtr<MimeSniffingThrottle> throttle_; - - mojo::Binding<network::mojom::URLLoaderClient> source_url_client_binding_; - network::mojom::URLLoaderPtr source_url_loader_; - network::mojom::URLLoaderClientPtr destination_url_loader_client_; - - GURL response_url_; - - // Capture the response head to defer to send it to the destination until the - // mime type is decided. - network::ResourceResponseHead response_head_; - - enum class State { kWaitForBody, kSniffing, kSending, kCompleted }; - State state_ = State::kWaitForBody; - - // Set if OnComplete() is called during sniffing. - base::Optional<network::URLLoaderCompletionStatus> complete_status_; - - std::vector<char> buffered_body_; - size_t bytes_remaining_in_buffer_; - - mojo::ScopedDataPipeConsumerHandle body_consumer_handle_; - mojo::ScopedDataPipeProducerHandle body_producer_handle_; - mojo::SimpleWatcher body_consumer_watcher_; - mojo::SimpleWatcher body_producer_watcher_; - - DISALLOW_COPY_AND_ASSIGN(MimeSniffingURLLoader); -}; - -} // namespace content - -#endif // CONTENT_COMMON_MIME_SNIFFING_URL_LOADER_H_
diff --git a/content/common/service_worker/service_worker_loader_helpers.cc b/content/common/service_worker/service_worker_loader_helpers.cc index 431207de..b01b6825 100644 --- a/content/common/service_worker/service_worker_loader_helpers.cc +++ b/content/common/service_worker/service_worker_loader_helpers.cc
@@ -64,11 +64,15 @@ net::HttpUtil::AssembleRawHeaders(buf.c_str(), buf.size())); // Populate |out_head|'s MIME type with the value from the HTTP response - // headers. + // headers. If there is none, set a default value. + // TODO(crbug.com/771118): Make the MIME sniffer work for SW controlled page + // loads, so we don't need to set a simple default value. if (out_head->mime_type.empty()) { std::string mime_type; - if (out_head->headers->GetMimeType(&mime_type)) - out_head->mime_type = mime_type; + out_head->headers->GetMimeType(&mime_type); + if (mime_type.empty()) + mime_type = "text/plain"; + out_head->mime_type = mime_type; } // Populate |out_head|'s charset with the value from the HTTP response
diff --git a/content/common/throttling_url_loader.cc b/content/common/throttling_url_loader.cc index 7e49564..1a33248 100644 --- a/content/common/throttling_url_loader.cc +++ b/content/common/throttling_url_loader.cc
@@ -44,14 +44,6 @@ loader_->SetPriority(priority); } - void UpdateDeferredResponseHead( - const network::ResourceResponseHead& new_response_head) override { - if (!loader_) - return; - ScopedDelegateCall scoped_delegate_call(this); - loader_->UpdateDeferredResponseHead(new_response_head); - } - void PauseReadingBodyFromNet() override { if (!loader_) return; @@ -201,7 +193,7 @@ void ThrottlingURLLoader::SetPriority(net::RequestPriority priority, int32_t intra_priority_value) { if (!url_loader_) { - if (!loader_completed_) { + if (!loader_cancelled_) { DCHECK_EQ(DEFERRED_START, deferred_stage_); priority_info_ = std::make_unique<PriorityInfo>(priority, intra_priority_value); @@ -238,7 +230,7 @@ network::ResourceRequest* url_request, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { DCHECK_EQ(DEFERRED_NONE, deferred_stage_); - DCHECK(!loader_completed_); + DCHECK(!loader_cancelled_); if (options & network::mojom::kURLLoadOptionSynchronous) is_synchronous_ = true; @@ -302,7 +294,7 @@ bool throttle_deferred, bool* should_defer) { DCHECK(!deferring_throttles_.count(throttle)); - if (loader_completed_) + if (loader_cancelled_) return false; *should_defer |= throttle_deferred; if (throttle_deferred) @@ -316,14 +308,14 @@ return; deferring_throttles_.erase(throttle); - if (deferring_throttles_.empty() && !loader_completed_) + if (deferring_throttles_.empty() && !loader_cancelled_) Resume(); } void ThrottlingURLLoader::OnReceiveResponse( const network::ResourceResponseHead& response_head) { DCHECK_EQ(DEFERRED_NONE, deferred_stage_); - DCHECK(!loader_completed_); + DCHECK(!loader_cancelled_); DCHECK(deferring_throttles_.empty()); if (!throttles_.empty()) { @@ -352,7 +344,7 @@ const net::RedirectInfo& redirect_info, const network::ResourceResponseHead& response_head) { DCHECK_EQ(DEFERRED_NONE, deferred_stage_); - DCHECK(!loader_completed_); + DCHECK(!loader_cancelled_); DCHECK(deferring_throttles_.empty()); if (!throttles_.empty()) { @@ -394,7 +386,7 @@ int64_t total_size, OnUploadProgressCallback ack_callback) { DCHECK_EQ(DEFERRED_NONE, deferred_stage_); - DCHECK(!loader_completed_); + DCHECK(!loader_cancelled_); forwarding_client_->OnUploadProgress(current_position, total_size, std::move(ack_callback)); @@ -403,14 +395,14 @@ void ThrottlingURLLoader::OnReceiveCachedMetadata( const std::vector<uint8_t>& data) { DCHECK_EQ(DEFERRED_NONE, deferred_stage_); - DCHECK(!loader_completed_); + DCHECK(!loader_cancelled_); forwarding_client_->OnReceiveCachedMetadata(data); } void ThrottlingURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) { DCHECK_EQ(DEFERRED_NONE, deferred_stage_); - DCHECK(!loader_completed_); + DCHECK(!loader_cancelled_); forwarding_client_->OnTransferSizeUpdated(transfer_size_diff); } @@ -418,7 +410,7 @@ void ThrottlingURLLoader::OnStartLoadingResponseBody( mojo::ScopedDataPipeConsumerHandle body) { DCHECK_EQ(DEFERRED_NONE, deferred_stage_); - DCHECK(!loader_completed_); + DCHECK(!loader_cancelled_); forwarding_client_->OnStartLoadingResponseBody(std::move(body)); } @@ -426,14 +418,12 @@ void ThrottlingURLLoader::OnComplete( const network::URLLoaderCompletionStatus& status) { DCHECK_EQ(DEFERRED_NONE, deferred_stage_); - DCHECK(!loader_completed_); + DCHECK(!loader_cancelled_); // This is the last expected message. Pipe closure before this is an error // (see OnClientConnectionError). After this it is expected and should be - // ignored. The owner of |this| is expected to destroy |this| when - // OnComplete() and all data has been read. Destruction of |this| will - // destroy |url_loader_| appropriately. - loader_completed_ = true; + // ignored. + DisconnectClient(nullptr); forwarding_client_->OnComplete(status); } @@ -447,7 +437,7 @@ void ThrottlingURLLoader::CancelWithError(int error_code, base::StringPiece custom_reason) { - if (loader_completed_) + if (loader_cancelled_) return; network::URLLoaderCompletionStatus status; @@ -460,7 +450,7 @@ } void ThrottlingURLLoader::Resume() { - if (loader_completed_ || deferred_stage_ == DEFERRED_NONE) + if (loader_cancelled_ || deferred_stage_ == DEFERRED_NONE) return; auto prev_deferred_stage = deferred_stage_; @@ -500,13 +490,6 @@ url_loader_->SetPriority(priority, -1); } -void ThrottlingURLLoader::UpdateDeferredResponseHead( - const network::ResourceResponseHead& new_response_head) { - DCHECK(response_info_); - DCHECK_EQ(DEFERRED_RESPONSE, deferred_stage_); - response_info_->response_head = new_response_head; -} - void ThrottlingURLLoader::PauseReadingBodyFromNet(URLLoaderThrottle* throttle) { if (pausing_reading_body_from_net_throttles_.empty() && url_loader_) url_loader_->PauseReadingBodyFromNet(); @@ -554,7 +537,7 @@ url_loader_ = nullptr; } - loader_completed_ = true; + loader_cancelled_ = true; } ThrottlingURLLoader::ThrottleEntry::ThrottleEntry(
diff --git a/content/common/throttling_url_loader.h b/content/common/throttling_url_loader.h index 7397d10..9fb0cdf 100644 --- a/content/common/throttling_url_loader.h +++ b/content/common/throttling_url_loader.h
@@ -120,8 +120,6 @@ void CancelWithError(int error_code, base::StringPiece custom_reason); void Resume(); void SetPriority(net::RequestPriority priority); - void UpdateDeferredResponseHead( - const network::ResourceResponseHead& new_response_head); void PauseReadingBodyFromNet(URLLoaderThrottle* throttle); void ResumeReadingBodyFromNet(URLLoaderThrottle* throttle); void InterceptResponse( @@ -140,7 +138,7 @@ DEFERRED_RESPONSE }; DeferredStage deferred_stage_ = DEFERRED_NONE; - bool loader_completed_ = false; + bool loader_cancelled_ = false; bool is_synchronous_ = false; struct ThrottleEntry {
diff --git a/content/public/common/url_loader_throttle.cc b/content/public/common/url_loader_throttle.cc index 891164f..a919a363 100644 --- a/content/public/common/url_loader_throttle.cc +++ b/content/public/common/url_loader_throttle.cc
@@ -9,8 +9,6 @@ namespace content { void URLLoaderThrottle::Delegate::SetPriority(net::RequestPriority priority) {} -void URLLoaderThrottle::Delegate::UpdateDeferredResponseHead( - const network::ResourceResponseHead& new_response_head) {} void URLLoaderThrottle::Delegate::PauseReadingBodyFromNet() {} void URLLoaderThrottle::Delegate::ResumeReadingBodyFromNet() {}
diff --git a/content/public/common/url_loader_throttle.h b/content/public/common/url_loader_throttle.h index 5a263b53..37faba0 100644 --- a/content/public/common/url_loader_throttle.h +++ b/content/public/common/url_loader_throttle.h
@@ -57,13 +57,6 @@ virtual void SetPriority(net::RequestPriority priority); - // Updates the response head which is deferred to be sent. This method needs - // to be called when the response is deferred on - // URLLoaderThrottle::WillProcessResponse() and before calling - // Delegate::Resume(). - virtual void UpdateDeferredResponseHead( - const network::ResourceResponseHead& new_response_head); - // Pauses/resumes reading response body if the resource is fetched from // network. virtual void PauseReadingBodyFromNet();
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index 499fe2db..620ba63d 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -57,6 +57,7 @@ child_identity_(mojom::kRendererServiceName, BrowserContext::GetServiceUserIdFor(browser_context), base::StringPrintf("%d", id_)), + url_loader_factory_(nullptr), weak_ptr_factory_(this) { // Child process security operations can't be unit tested unless we add // ourselves as an existing child process.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 177147e..bce0c21 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -439,6 +439,8 @@ "media/webrtc/webrtc_video_capturer_adapter.h", "media/webrtc/webrtc_video_frame_adapter.cc", "media/webrtc/webrtc_video_frame_adapter.h", + "media/webrtc/webrtc_video_utils.cc", + "media/webrtc/webrtc_video_utils.h", "media/webrtc_local_audio_source_provider.cc", "media/webrtc_local_audio_source_provider.h", "media/webrtc_logging.cc",
diff --git a/content/renderer/input/input_handler_manager_client.h b/content/renderer/input/input_handler_manager_client.h index 6f91e63a3..7793a65 100644 --- a/content/renderer/input/input_handler_manager_client.h +++ b/content/renderer/input/input_handler_manager_client.h
@@ -49,6 +49,7 @@ // Otherwise |DidOverscroll| will be fired. virtual void DidOverscroll(int routing_id, const ui::DidOverscrollParams& params) = 0; + virtual void DidStopFlinging(int routing_id) = 0; virtual void DidStartScrollingViewport(int routing_id) = 0; virtual void DispatchNonBlockingEventToMainThread( int routing_id,
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc index 390de26..3d5bd290 100644 --- a/content/renderer/loader/resource_dispatcher.cc +++ b/content/renderer/loader/resource_dispatcher.cc
@@ -22,7 +22,6 @@ #include "base/time/time.h" #include "build/build_config.h" #include "content/common/inter_process_time_ticks_converter.h" -#include "content/common/mime_sniffing_throttle.h" #include "content/common/navigation_params.h" #include "content/common/net/record_load_histograms.h" #include "content/common/throttling_url_loader.h" @@ -46,7 +45,6 @@ #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/resource_response.h" #include "services/network/public/cpp/url_loader_completion_status.h" -#include "third_party/blink/public/common/service_worker/service_worker_utils.h" namespace content { @@ -698,12 +696,10 @@ uint32_t options = network::mojom::kURLLoadOptionNone; // TODO(jam): use this flag for ResourceDispatcherHost code path once // MojoLoading is the only IPC code path. - if ((blink::ServiceWorkerUtils::IsServicificationEnabled() || - base::FeatureList::IsEnabled(network::features::kNetworkService)) && + if (base::FeatureList::IsEnabled(network::features::kNetworkService) && request->fetch_request_context_type != REQUEST_CONTEXT_TYPE_FETCH) { // MIME sniffing should be disabled for a request initiated by fetch(). options |= network::mojom::kURLLoadOptionSniffMimeType; - throttles.push_back(std::make_unique<MimeSniffingThrottle>()); } if (is_sync) { options |= network::mojom::kURLLoadOptionSynchronous;
diff --git a/content/renderer/media/stream/media_stream_video_track.h b/content/renderer/media/stream/media_stream_video_track.h index 09bc143..c46e29b 100644 --- a/content/renderer/media/stream/media_stream_video_track.h +++ b/content/renderer/media/stream/media_stream_video_track.h
@@ -114,6 +114,8 @@ friend class MediaStreamVideoSink; FRIEND_TEST_ALL_PREFIXES(MediaStreamRemoteVideoSourceTest, StartTrack); FRIEND_TEST_ALL_PREFIXES(MediaStreamRemoteVideoSourceTest, RemoteTrackStop); + FRIEND_TEST_ALL_PREFIXES(MediaStreamRemoteVideoSourceTest, + PreservesColorSpace); FRIEND_TEST_ALL_PREFIXES(PepperToVideoTrackAdapterTest, PutFrame); // Add |sink| to receive state changes on the main render thread and video
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/content/renderer/media/webrtc/media_stream_remote_video_source.cc index 0e810df..a3869e8 100644 --- a/content/renderer/media/webrtc/media_stream_remote_video_source.cc +++ b/content/renderer/media/webrtc/media_stream_remote_video_source.cc
@@ -13,6 +13,7 @@ #include "base/trace_event/trace_event.h" #include "content/renderer/media/webrtc/track_observer.h" #include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h" +#include "content/renderer/media/webrtc/webrtc_video_utils.h" #include "media/base/bind_to_current_loop.h" #include "media/base/timestamp_constants.h" #include "media/base/video_frame.h" @@ -22,25 +23,6 @@ namespace content { -namespace { - -media::VideoRotation WebRTCToMediaVideoRotation( - webrtc::VideoRotation rotation) { - switch (rotation) { - case webrtc::kVideoRotation_0: - return media::VIDEO_ROTATION_0; - case webrtc::kVideoRotation_90: - return media::VIDEO_ROTATION_90; - case webrtc::kVideoRotation_180: - return media::VIDEO_ROTATION_180; - case webrtc::kVideoRotation_270: - return media::VIDEO_ROTATION_270; - } - return media::VIDEO_ROTATION_0; -} - -} // anonymous namespace - // Internal class used for receiving frames from the webrtc track on a // libjingle thread and forward it to the IO-thread. class MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate @@ -192,7 +174,13 @@ if (incoming_frame.rotation() != webrtc::kVideoRotation_0) { video_frame->metadata()->SetRotation( media::VideoFrameMetadata::ROTATION, - WebRTCToMediaVideoRotation(incoming_frame.rotation())); + WebRtcToMediaVideoRotation(incoming_frame.rotation())); + } + + if (incoming_frame.color_space().has_value()) { + video_frame->set_color_space( + WebRtcToMediaVideoColorSpace(incoming_frame.color_space().value()) + .ToGfxColorSpace()); } // Run render smoothness algorithm only when we don't have to render
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc b/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc index e721651..89c42fff3 100644 --- a/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc +++ b/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
@@ -22,7 +22,9 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/web/web_heap.h" +#include "third_party/webrtc/api/video/color_space.h" #include "third_party/webrtc/api/video/i420_buffer.h" +#include "ui/gfx/color_space.h" namespace content { @@ -37,6 +39,7 @@ std::unique_ptr<TrackObserver> observer) : MediaStreamRemoteVideoSource(std::move(observer)) {} using MediaStreamRemoteVideoSource::SinkInterfaceForTesting; + using MediaStreamRemoteVideoSource::StartSourceImpl; }; class MediaStreamRemoteVideoSourceTest @@ -196,4 +199,39 @@ track->RemoveSink(&sink); } +TEST_F(MediaStreamRemoteVideoSourceTest, PreservesColorSpace) { + std::unique_ptr<MediaStreamVideoTrack> track(CreateTrack()); + MockMediaStreamVideoSink sink; + track->AddSink(&sink, sink.GetDeliverFrameCB(), false); + + base::RunLoop run_loop; + EXPECT_CALL(sink, OnVideoFrame()) + .WillOnce(RunClosure(run_loop.QuitClosure())); + rtc::scoped_refptr<webrtc::I420Buffer> buffer( + new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240)); + webrtc::ColorSpace kColorSpace(webrtc::ColorSpace::PrimaryID::kSMPTE240M, + webrtc::ColorSpace::TransferID::kSMPTE240M, + webrtc::ColorSpace::MatrixID::kSMPTE240M, + webrtc::ColorSpace::RangeID::kLimited); + const webrtc::VideoFrame& input_frame = + webrtc::VideoFrame::Builder() + .set_video_frame_buffer(buffer) + .set_timestamp_ms(0) + .set_rotation(webrtc::kVideoRotation_0) + .set_color_space(kColorSpace) + .build(); + source()->SinkInterfaceForTesting()->OnFrame(input_frame); + run_loop.Run(); + + EXPECT_EQ(1, sink.number_of_frames()); + scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); + EXPECT_TRUE(output_frame); + EXPECT_TRUE(output_frame->ColorSpace() == + gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE240M, + gfx::ColorSpace::TransferID::SMPTE240M, + gfx::ColorSpace::MatrixID::SMPTE240M, + gfx::ColorSpace::RangeID::LIMITED)); + track->RemoveSink(&sink); +} + } // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_video_utils.cc b/content/renderer/media/webrtc/webrtc_video_utils.cc new file mode 100644 index 0000000..0c7662f4 --- /dev/null +++ b/content/renderer/media/webrtc/webrtc_video_utils.cc
@@ -0,0 +1,177 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/webrtc/webrtc_video_utils.h" + +namespace content { + +media::VideoRotation WebRtcToMediaVideoRotation( + webrtc::VideoRotation rotation) { + switch (rotation) { + case webrtc::kVideoRotation_0: + return media::VIDEO_ROTATION_0; + case webrtc::kVideoRotation_90: + return media::VIDEO_ROTATION_90; + case webrtc::kVideoRotation_180: + return media::VIDEO_ROTATION_180; + case webrtc::kVideoRotation_270: + return media::VIDEO_ROTATION_270; + } + return media::VIDEO_ROTATION_0; +} + +media::VideoColorSpace WebRtcToMediaVideoColorSpace( + const webrtc::ColorSpace& color_space) { + media::VideoColorSpace::PrimaryID primaries = + media::VideoColorSpace::PrimaryID::INVALID; + switch (color_space.primaries()) { + case webrtc::ColorSpace::PrimaryID::kBT709: + primaries = media::VideoColorSpace::PrimaryID::BT709; + break; + case webrtc::ColorSpace::PrimaryID::kBT470M: + primaries = media::VideoColorSpace::PrimaryID::BT470M; + break; + case webrtc::ColorSpace::PrimaryID::kBT470BG: + primaries = media::VideoColorSpace::PrimaryID::BT470BG; + break; + case webrtc::ColorSpace::PrimaryID::kSMPTE170M: + primaries = media::VideoColorSpace::PrimaryID::SMPTE170M; + break; + case webrtc::ColorSpace::PrimaryID::kSMPTE240M: + primaries = media::VideoColorSpace::PrimaryID::SMPTE240M; + break; + case webrtc::ColorSpace::PrimaryID::kFILM: + primaries = media::VideoColorSpace::PrimaryID::FILM; + break; + case webrtc::ColorSpace::PrimaryID::kBT2020: + primaries = media::VideoColorSpace::PrimaryID::BT2020; + break; + case webrtc::ColorSpace::PrimaryID::kSMPTEST428: + primaries = media::VideoColorSpace::PrimaryID::SMPTEST428_1; + break; + case webrtc::ColorSpace::PrimaryID::kSMPTEST431: + primaries = media::VideoColorSpace::PrimaryID::SMPTEST431_2; + break; + case webrtc::ColorSpace::PrimaryID::kSMPTEST432: + primaries = media::VideoColorSpace::PrimaryID::SMPTEST432_1; + break; + case webrtc::ColorSpace::PrimaryID::kJEDECP22: + primaries = media::VideoColorSpace::PrimaryID::EBU_3213_E; + break; + case webrtc::ColorSpace::PrimaryID::kInvalid: + default: + break; + } + + media::VideoColorSpace::TransferID transfer = + media::VideoColorSpace::TransferID::INVALID; + switch (color_space.transfer()) { + case webrtc::ColorSpace::TransferID::kBT709: + transfer = media::VideoColorSpace::TransferID::BT709; + break; + case webrtc::ColorSpace::TransferID::kGAMMA22: + transfer = media::VideoColorSpace::TransferID::GAMMA22; + break; + case webrtc::ColorSpace::TransferID::kGAMMA28: + transfer = media::VideoColorSpace::TransferID::GAMMA28; + break; + case webrtc::ColorSpace::TransferID::kSMPTE170M: + transfer = media::VideoColorSpace::TransferID::SMPTE170M; + break; + case webrtc::ColorSpace::TransferID::kSMPTE240M: + transfer = media::VideoColorSpace::TransferID::SMPTE240M; + break; + case webrtc::ColorSpace::TransferID::kLINEAR: + transfer = media::VideoColorSpace::TransferID::LINEAR; + break; + case webrtc::ColorSpace::TransferID::kLOG: + transfer = media::VideoColorSpace::TransferID::LOG; + break; + case webrtc::ColorSpace::TransferID::kLOG_SQRT: + transfer = media::VideoColorSpace::TransferID::LOG_SQRT; + break; + case webrtc::ColorSpace::TransferID::kIEC61966_2_4: + transfer = media::VideoColorSpace::TransferID::IEC61966_2_4; + break; + case webrtc::ColorSpace::TransferID::kBT1361_ECG: + transfer = media::VideoColorSpace::TransferID::BT1361_ECG; + break; + case webrtc::ColorSpace::TransferID::kIEC61966_2_1: + transfer = media::VideoColorSpace::TransferID::IEC61966_2_1; + break; + case webrtc::ColorSpace::TransferID::kBT2020_10: + transfer = media::VideoColorSpace::TransferID::BT2020_10; + break; + case webrtc::ColorSpace::TransferID::kBT2020_12: + transfer = media::VideoColorSpace::TransferID::BT2020_12; + break; + case webrtc::ColorSpace::TransferID::kSMPTEST2084: + transfer = media::VideoColorSpace::TransferID::SMPTEST2084; + break; + case webrtc::ColorSpace::TransferID::kSMPTEST428: + transfer = media::VideoColorSpace::TransferID::SMPTEST428_1; + break; + case webrtc::ColorSpace::TransferID::kARIB_STD_B67: + transfer = media::VideoColorSpace::TransferID::ARIB_STD_B67; + break; + case webrtc::ColorSpace::TransferID::kInvalid: + default: + break; + } + + media::VideoColorSpace::MatrixID matrix = + media::VideoColorSpace::MatrixID::INVALID; + switch (color_space.matrix()) { + case webrtc::ColorSpace::MatrixID::kRGB: + matrix = media::VideoColorSpace::MatrixID::RGB; + break; + case webrtc::ColorSpace::MatrixID::kBT709: + matrix = media::VideoColorSpace::MatrixID::BT709; + break; + case webrtc::ColorSpace::MatrixID::kFCC: + matrix = media::VideoColorSpace::MatrixID::FCC; + break; + case webrtc::ColorSpace::MatrixID::kBT470BG: + matrix = media::VideoColorSpace::MatrixID::BT470BG; + break; + case webrtc::ColorSpace::MatrixID::kSMPTE170M: + matrix = media::VideoColorSpace::MatrixID::SMPTE170M; + break; + case webrtc::ColorSpace::MatrixID::kSMPTE240M: + matrix = media::VideoColorSpace::MatrixID::SMPTE240M; + break; + case webrtc::ColorSpace::MatrixID::kYCOCG: + matrix = media::VideoColorSpace::MatrixID::YCOCG; + break; + case webrtc::ColorSpace::MatrixID::kBT2020_NCL: + matrix = media::VideoColorSpace::MatrixID::BT2020_NCL; + break; + case webrtc::ColorSpace::MatrixID::kBT2020_CL: + matrix = media::VideoColorSpace::MatrixID::BT2020_CL; + break; + case webrtc::ColorSpace::MatrixID::kSMPTE2085: + matrix = media::VideoColorSpace::MatrixID::YDZDX; + break; + case webrtc::ColorSpace::MatrixID::kInvalid: + default: + break; + } + + gfx::ColorSpace::RangeID range = gfx::ColorSpace::RangeID::INVALID; + switch (color_space.range()) { + case webrtc::ColorSpace::RangeID::kLimited: + range = gfx::ColorSpace::RangeID::LIMITED; + break; + case webrtc::ColorSpace::RangeID::kFull: + range = gfx::ColorSpace::RangeID::FULL; + break; + case webrtc::ColorSpace::RangeID::kInvalid: + default: + break; + } + + return media::VideoColorSpace(primaries, transfer, matrix, range); +} + +} // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_video_utils.h b/content/renderer/media/webrtc/webrtc_video_utils.h new file mode 100644 index 0000000..1d91b2a4 --- /dev/null +++ b/content/renderer/media/webrtc/webrtc_video_utils.h
@@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_UTILS_H_ +#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_UTILS_H_ + +#include "media/base/video_color_space.h" +#include "media/base/video_rotation.h" +#include "third_party/webrtc/api/video/color_space.h" +#include "third_party/webrtc/api/video/video_rotation.h" + +namespace content { + +// This file has helper methods for conversion between chromium types and +// webrtc/api/video types. + +media::VideoRotation WebRtcToMediaVideoRotation(webrtc::VideoRotation rotation); + +media::VideoColorSpace WebRtcToMediaVideoColorSpace( + const webrtc::ColorSpace& color_space); + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_UTILS_H_
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 413b97c3..e754e7e 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1603,7 +1603,6 @@ "../common/mac/attributed_string_coder_unittest.mm", "../common/manifest_util_unittest.cc", "../common/media/media_devices_unittest.cc", - "../common/mime_sniffing_throttle_unittest.cc", "../common/notifications/notification_struct_traits_unittest.cc", "../common/origin_util_unittest.cc", "../common/page_state_serialization_unittest.cc",
diff --git a/content/test/data/accessibility/aria/dpub-roles-expected-auralinux.txt b/content/test/data/accessibility/aria/dpub-roles-expected-auralinux.txt index 37d27c82..e0e10c8 100644 --- a/content/test/data/accessibility/aria/dpub-roles-expected-auralinux.txt +++ b/content/test/data/accessibility/aria/dpub-roles-expected-auralinux.txt
@@ -1,40 +1,40 @@ -[document web] enabled focusable focused<newline> -++[section] name='doc-abstract' enabled<newline> -++[landmark] name='doc-acknowledgments' enabled<newline> -++[landmark] name='doc-afterword' enabled<newline> -++[landmark] name='doc-appendix' enabled<newline> -++[link] name='doc-backlink' enabled<newline> -++[list item] name='doc-biblioentry' enabled<newline> -++[landmark] name='doc-bibliography' enabled<newline> -++[link] name='doc-biblioref' enabled<newline> -++[landmark] name='doc-chapter' enabled<newline> -++[section] name='doc-colophon' enabled<newline> -++[landmark] name='doc-conclusion' enabled<newline> -++[image] name='doc-cover' enabled<newline> -++[section] name='doc-credit' enabled<newline> -++[landmark] name='doc-credits' enabled<newline> -++[section] name='doc-dedication' enabled<newline> -++[list item] name='doc-endnote' enabled<newline> -++[landmark] name='doc-endnotes' enabled<newline> -++[section] name='doc-epigraph' enabled<newline> -++[landmark] name='doc-epilogue' enabled<newline> -++[landmark] name='doc-errata' enabled<newline> -++[section] name='doc-example' enabled<newline> -++[footnote] name='doc-footnote' enabled<newline> -++[landmark] name='doc-foreword' enabled<newline> -++[landmark] name='doc-glossary' enabled<newline> -++[link] name='doc-glossref' enabled<newline> -++[landmark] name='doc-index' enabled<newline> -++[landmark] name='doc-introduction' enabled<newline> -++[link] name='doc-noteref' enabled<newline> -++[comment] name='doc-notice' enabled<newline> -++[separator] name='doc-pagebreak' enabled<newline> -++[landmark] name='doc-pagelist' enabled<newline> -++[landmark] name='doc-part' enabled<newline> -++[landmark] name='doc-preface' enabled<newline> -++[landmark] name='doc-prologue' enabled<newline> -++[section] name='doc-pullquote' enabled<newline> -++[section] name='doc-qna' enabled<newline> -++[heading] name='doc-subtitle' enabled<newline> -++[comment] name='doc-tip' enabled<newline> -++[landmark] name='doc-toc' enabled<newline> +[document web] enabled focusable focused sensitive showing visible<newline> +++[section] name='doc-abstract' enabled sensitive showing visible<newline> +++[landmark] name='doc-acknowledgments' enabled sensitive showing visible<newline> +++[landmark] name='doc-afterword' enabled sensitive showing visible<newline> +++[landmark] name='doc-appendix' enabled sensitive showing visible<newline> +++[link] name='doc-backlink' enabled sensitive showing visible<newline> +++[list item] name='doc-biblioentry' enabled sensitive showing visible<newline> +++[landmark] name='doc-bibliography' enabled sensitive showing visible<newline> +++[link] name='doc-biblioref' enabled sensitive showing visible<newline> +++[landmark] name='doc-chapter' enabled sensitive showing visible<newline> +++[section] name='doc-colophon' enabled sensitive showing visible<newline> +++[landmark] name='doc-conclusion' enabled sensitive showing visible<newline> +++[image] name='doc-cover' enabled sensitive showing visible<newline> +++[section] name='doc-credit' enabled sensitive showing visible<newline> +++[landmark] name='doc-credits' enabled sensitive showing visible<newline> +++[section] name='doc-dedication' enabled sensitive showing visible<newline> +++[list item] name='doc-endnote' enabled sensitive showing visible<newline> +++[landmark] name='doc-endnotes' enabled sensitive showing visible<newline> +++[section] name='doc-epigraph' enabled sensitive showing visible<newline> +++[landmark] name='doc-epilogue' enabled sensitive showing visible<newline> +++[landmark] name='doc-errata' enabled sensitive showing visible<newline> +++[section] name='doc-example' enabled sensitive showing visible<newline> +++[footnote] name='doc-footnote' enabled sensitive showing visible<newline> +++[landmark] name='doc-foreword' enabled sensitive showing visible<newline> +++[landmark] name='doc-glossary' enabled sensitive showing visible<newline> +++[link] name='doc-glossref' enabled sensitive showing visible<newline> +++[landmark] name='doc-index' enabled sensitive showing visible<newline> +++[landmark] name='doc-introduction' enabled sensitive showing visible<newline> +++[link] name='doc-noteref' enabled sensitive showing visible<newline> +++[comment] name='doc-notice' enabled sensitive showing visible<newline> +++[separator] name='doc-pagebreak' enabled sensitive showing visible<newline> +++[landmark] name='doc-pagelist' enabled sensitive showing visible<newline> +++[landmark] name='doc-part' enabled sensitive showing visible<newline> +++[landmark] name='doc-preface' enabled sensitive showing visible<newline> +++[landmark] name='doc-prologue' enabled sensitive showing visible<newline> +++[section] name='doc-pullquote' enabled sensitive showing visible<newline> +++[section] name='doc-qna' enabled sensitive showing visible<newline> +++[heading] name='doc-subtitle' enabled sensitive showing visible<newline> +++[comment] name='doc-tip' enabled sensitive showing visible<newline> +++[landmark] name='doc-toc' enabled sensitive showing visible<newline>
diff --git a/content/test/data/accessibility/aria/graphics-roles-expected-auralinux.txt b/content/test/data/accessibility/aria/graphics-roles-expected-auralinux.txt index 77b11860..9372606f 100644 --- a/content/test/data/accessibility/aria/graphics-roles-expected-auralinux.txt +++ b/content/test/data/accessibility/aria/graphics-roles-expected-auralinux.txt
@@ -1,4 +1,4 @@ -[document web] enabled focusable focused<newline> -++[document web] name='graphics-document' enabled<newline> -++[panel] name='graphics-object' enabled<newline> -++[image] name='graphics-symbol' enabled<newline> +[document web] enabled focusable focused sensitive showing visible<newline> +++[document web] name='graphics-document' enabled sensitive showing visible<newline> +++[panel] name='graphics-object' enabled sensitive showing visible<newline> +++[image] name='graphics-symbol' enabled sensitive showing visible<newline>
diff --git a/content/test/data/accessibility/html/a-expected-auralinux.txt b/content/test/data/accessibility/html/a-expected-auralinux.txt index 4879349..cb5e5d3a 100644 --- a/content/test/data/accessibility/html/a-expected-auralinux.txt +++ b/content/test/data/accessibility/html/a-expected-auralinux.txt
@@ -1,4 +1,4 @@ -[document web] enabled focusable focused<newline> -++[panel] enabled<newline> -++++[link] name='normal link' enabled focusable<newline> -++++++[text] name='normal link' enabled<newline> +[document web] enabled focusable focused sensitive showing visible<newline> +++[panel] enabled sensitive showing visible<newline> +++++[link] name='normal link' enabled focusable sensitive showing visible<newline> +++++++[text] name='normal link' enabled sensitive showing visible<newline>
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index 16eb9d60..af2d4afd 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -57,6 +57,8 @@ ['win', 'mac', 'linux', 'android']) self.Skip('WebglExtension_EXT_disjoint_timer_query', ['android'], bug=808744) + self.Fail('WebglExtension_EXT_disjoint_timer_query', + ['linux', 'intel'], bug=867675) # Extensions not available under D3D9 self.Fail('WebglExtension_EXT_sRGB',
diff --git a/content/test/gpu/ipg_utils.py b/content/test/gpu/ipg_utils.py new file mode 100644 index 0000000..749ea070 --- /dev/null +++ b/content/test/gpu/ipg_utils.py
@@ -0,0 +1,111 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""This script implements a few IntelPowerGadget related helper functions. + +This script only works on Windows with Intel CPU. Intel Power Gadget needs to +be installed on the machine before this script works. The software can be +downloaded from: + https://software.intel.com/en-us/articles/intel-power-gadget-20 + +An easy way to use the APIs are: +1) Launch your program. +2) Call RunIPG() with no args. It will automatically locate the IPG installed + on the machine. +3) Call AnalyzeIPGLogFile() with no args. It will analyze the default IPG log + file, which is PowerLog.csv at current dir; then it will print out the power + usage summary. If you want to skip a few seconds of the power log data, say, + 5 seconds, call AnalyzeIPGLogFile(skip_in_sec=5). +""" + +import logging +import os +import subprocess +import datetime + +def LocateIPG(): + ipg_dir = os.getenv('IPG_Dir') + if not ipg_dir: + logging.warning("No env IPG_Dir") + return None + gadget_path = os.path.join(ipg_dir, "PowerLog3.0.exe") + logging.debug("Try to locale Intel Power Gadget at " + gadget_path) + if os.path.isfile(gadget_path): + logging.debug("Intel Power Gadget Found") + return gadget_path + return None + +def GenerateIPGLogFilename(prefix='PowerLog', dir=None, current_run=1, + total_runs=1, timestamp=False): + # If all args take default value, it is the IPG's default log path. + dir = dir or os.getcwd() + dir = os.path.abspath(dir) + if total_runs > 1: + prefix = "%s_%d_%d" % (prefix, current_run, total_runs) + if timestamp: + now = datetime.datetime.now() + prefix = "%s_%s" % (prefix, now.strftime('%Y%m%d%H%M%S')) + return os.path.join(dir, prefix + '.csv') + +def RunIPG(duration_in_s=60, resolution_in_ms=100, logfile=None): + intel_power_gadget_path = LocateIPG() + if not intel_power_gadget_path: + logging.warning("Can't locate Intel Power Gadget") + return + command = ('"%s" -duration %d -resolution %d' % + (intel_power_gadget_path, duration_in_s, resolution_in_ms)) + if not logfile: + # It is not necessary but allows to print out the log path for debugging. + logfile = GenerateIPGLogFilename(); + command = command + (' -file %s' %logfile) + logging.debug("Running: " + command) + try: + output = subprocess.check_output(command) + logging.debug("Running: DONE") + logging.debug(output) + except subprocess.CalledProcessError as err: + logging.warning(err) + +def AnalyzeIPGLogFile(logfile=None, skip_in_sec=0): + if not logfile: + logfile = GenerateIPGLogFilename() + if not os.path.isfile(logfile): + logging.warning("Can't locate logfile at " + logfile) + return {} + first_line = True + samples = 0 + cols = 0 + indices = [] + labels = [] + sums = [] + col_time = None + for line in open(logfile): + tokens = line.split(',') + if first_line: + first_line = False + cols = len(tokens) + for ii in range(0, cols): + if tokens[ii].startswith('Elapsed Time'): + col_time = ii; + elif tokens[ii].endswith('(Watt)'): + indices.append(ii) + labels.append(tokens[ii][:-len('(Watt)')]) + sums.append(0.0) + assert col_time + assert cols > 0 + assert len(indices) > 0 + continue + if len(tokens) != cols: + continue + if skip_in_sec > 0 and float(tokens[col_time]) < skip_in_sec: + continue + samples += 1 + for ii in range(0, len(indices)): + index = indices[ii] + sums[ii] += float(tokens[index]) + results = {'samples': samples} + if samples > 0: + for ii in range(0, len(indices)): + results[labels[ii]] = sums[ii] / samples + return results
diff --git a/content/test/gpu/measure_power_win_intel.py b/content/test/gpu/measure_power_win_intel.py new file mode 100644 index 0000000..505ac52 --- /dev/null +++ b/content/test/gpu/measure_power_win_intel.py
@@ -0,0 +1,161 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""This script runs power measurements for browsers using Intel Power Gadget. + +This script only works on Windows with Intel CPU. Intel Power Gadget needs to +be installed on the machine before this script works. The software can be +downloaded from: + https://software.intel.com/en-us/articles/intel-power-gadget-20 + +Sample runs: + +python measure_power_win_intel.py --browser=canary --duration=10 --delay=5 + --verbose --url="https://www.youtube.com/watch?v=0XdS37Re1XQ" + --extra-browser-args="--no-sandbox --disable-features=UseSurfaceLayerForVideo" +""" + +import ipg_utils +import logging +import os +import shutil +import subprocess +import sys +import tempfile +import time +import optparse + +CHROME_STABLE_PATH = ( + "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe") +CHROME_BETA_PATH = ( + "C:\Program Files (x86)\Google\Chrome Beta\Application\chrome.exe") +CHROME_DEV_PATH = ( + "C:\Program Files (x86)\Google\Chrome Dev\Application\chrome.exe") +# The following two paths are relative to the LOCALAPPDATA +CHROME_CANARY_PATH = "Google\Chrome SxS\Application\chrome.exe" +CHROMIUM_PATH = "Chromium\Application\chrome.exe" + +SUPPORTED_BROWSERS = ['stable', 'beta', 'dev', 'canary', 'chromium'] + +def LocateBrowser(options_browser): + browser = None + if not options_browser or options_browser == 'stable': + browser = CHROME_STABLE_PATH + elif options_browser == 'beta': + browser = CHROME_BETA_PATH + elif options_browser == 'dev': + browser = CHROME_DEV_PATH + elif options_browser == 'canary': + browser = os.path.join(os.getenv('LOCALAPPDATA'), CHROME_CANARY_PATH) + elif options_browser == 'chromium': + browser = os.path.join(os.getenv('LOCALAPPDATA'), CHROMIUM_PATH) + elif options_browser.endswith(".exe"): + browser = options_browser + else: + logging.warning("Invalid value for --browser") + logging.warning( + "Supported values: %s, or a full path to a browser executable." % + ", ".join(SUPPORTED_BROWSERS)) + return None + if not os.path.exists(browser): + logging.warning("Can't locate browser at " + browser) + logging.warning("Please pass full path to the executable in --browser") + return None + return browser + +def LaunchBrowser(browser, user_data_dir, url, extra_browser_args): + args = [] + args.append(browser) + if url: + args.append(url) + if browser.endswith("chrome.exe"): + args.append('--user-data-dir=%s' % user_data_dir) + args.append('--no-first-run') + args.append('--no-default-browser-check') + args.append('--autoplay-policy=no-user-gesture-required') + if extra_browser_args: + args.extend(extra_browser_args.split(' ')) + logging.debug(" ".join(args)) + browser_proc = subprocess.Popen(args) + return browser_proc + +def MeasurePowerOnce(browser, logfile, duration, delay, resolution, url, + extra_browser_args): + logging.debug("Logging into " + logfile) + user_data_dir = tempfile.mkdtemp() + browser_proc = LaunchBrowser(browser, user_data_dir, url, extra_browser_args) + ipg_utils.RunIPG(duration + delay, resolution, logfile) + browser_proc.kill() + for _ in range(100): + if browser_proc.poll() is not None: + break + logging.debug("Waiting for browser to exit") + time.sleep(0.05) + try: + shutil.rmtree(user_data_dir) + except Exception as err: + logging.warning("Failed to remove temporary folder: " + user_data_dir) + logging.warning("Please kill browser and remove it manually to avoid leak") + results = ipg_utils.AnalyzeIPGLogFile(logfile, delay) + return results + + +def main(argv): + parser = optparse.OptionParser() + parser.add_option("--browser", + help=("select which browser to run. Options include: " + + ", ".join(SUPPORTED_BROWSERS) + + ", or a full path to a browser executable. " + + "By default, stable is selected.")) + parser.add_option("--duration", default=60, type="int", + help="specify how many seconds Intel Power Gadget " + "measures. By default, 60 seconds is selected.") + parser.add_option("--delay", default=10, type="int", + help="specify how many seconds we skip in the data " + "Intel Power Gadget collects. This time is for starting " + "video play, switching to fullscreen mode, etc. " + "By default, 10 seconds is selected.") + parser.add_option("--resolution", default=100, type="int", + help="specify how often Intel Power Gadget samples " + "data in milliseconds. By default, 100 ms is selected.") + parser.add_option("--logdir", + help="specify where Intel Power Gadget stores its log." + "By default, it is the current path.") + parser.add_option("--logname", + help="specify the prefix for Intel Power Gadget log " + "filename. By default, it is PowerLog.") + parser.add_option("-v", "--verbose", action="store_true", default=False, + help="print out debug information.") + parser.add_option("--repeat", default=1, type="int", + help="specify how many times to run the measurements.") + parser.add_option("--url", + help="specify the webpage URL the browser launches with.") + parser.add_option("--extra-browser-args", dest="extra_browser_args", + help="specify extra commandline switches for the browser " + "that are separated by ' '.") + # TODO(zmo): add an option --start-fullscreen + (options, _) = parser.parse_args(args=argv) + if options.verbose: + logging.basicConfig(level=logging.DEBUG) + + browser = LocateBrowser(options.browser) + if not browser: + return + + # TODO(zmo): Add code to disable a bunch of Windows services that might + # affect power consumption. + + log_prefix = options.logname or 'PowerLog' + + for run in range(0, options.repeat): + logfile = ipg_utils.GenerateIPGLogFilename(log_prefix, options.logdir, + run, options.repeat, True) + logging.info("Iteration #%d out of %d" % (run, options.repeat)) + results = MeasurePowerOnce(browser, logfile, options.duration, + options.delay, options.resolution, options.url, + options.extra_browser_args) + logging.info(results) + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:]))
diff --git a/content/test/proxy_service_mojo_unittest.cc b/content/test/proxy_service_mojo_unittest.cc index 490b63d7..ece1669f 100644 --- a/content/test/proxy_service_mojo_unittest.cc +++ b/content/test/proxy_service_mojo_unittest.cc
@@ -158,12 +158,11 @@ TEST_F(ProxyServiceMojoTest, Basic) { net::ProxyInfo info; net::TestCompletionCallback callback; + std::unique_ptr<net::ProxyResolutionService::Request> request; EXPECT_EQ(net::ERR_IO_PENDING, proxy_resolution_service_->ResolveProxy( - GURL("http://foo"), - std::string(), - &info, callback.callback(), nullptr, - nullptr, net::NetLogWithSource())); + GURL("http://foo"), std::string(), &info, callback.callback(), + &request, nullptr, net::NetLogWithSource())); // PAC file fetcher should have a fetch triggered by the first // |ResolveProxy()| request. @@ -181,11 +180,11 @@ net::ProxyInfo info; net::TestCompletionCallback callback; net::BoundTestNetLog test_net_log; + std::unique_ptr<net::ProxyResolutionService::Request> request; EXPECT_EQ(net::ERR_IO_PENDING, proxy_resolution_service_->ResolveProxy( - GURL("http://foo"), std::string(), - &info, callback.callback(), nullptr, - nullptr, test_net_log.bound())); + GURL("http://foo"), std::string(), &info, callback.callback(), + &request, nullptr, test_net_log.bound())); // PAC file fetcher should have a fetch triggered by the first // |ResolveProxy()| request. @@ -214,11 +213,11 @@ net::ProxyInfo info; net::TestCompletionCallback callback; net::BoundTestNetLog test_net_log; + std::unique_ptr<net::ProxyResolutionService::Request> request; EXPECT_EQ(net::ERR_IO_PENDING, proxy_resolution_service_->ResolveProxy( - GURL("http://foo"), std::string(), - &info, callback.callback(), nullptr, - nullptr, test_net_log.bound())); + GURL("http://foo"), std::string(), &info, callback.callback(), + &request, nullptr, test_net_log.bound())); // PAC file fetcher should have a fetch triggered by the first // |ResolveProxy()| request. @@ -244,11 +243,11 @@ TEST_F(ProxyServiceMojoTest, ErrorOnInitialization) { net::ProxyInfo info; net::TestCompletionCallback callback; + std::unique_ptr<net::ProxyResolutionService::Request> request; EXPECT_EQ(net::ERR_IO_PENDING, proxy_resolution_service_->ResolveProxy( - GURL("http://foo"), std::string(), - &info, callback.callback(), nullptr, - nullptr, net::NetLogWithSource())); + GURL("http://foo"), std::string(), &info, callback.callback(), + &request, nullptr, net::NetLogWithSource())); // PAC file fetcher should have a fetch triggered by the first // |ResolveProxy()| request.
diff --git a/device/fido/device_response_converter.cc b/device/fido/device_response_converter.cc index b5ba0f7..e39fa693 100644 --- a/device/fido/device_response_converter.cc +++ b/device/fido/device_response_converter.cc
@@ -169,8 +169,8 @@ auto protocol = ConvertStringToProtocolVersion(version.GetString()); if (protocol == ProtocolVersion::kUnknown) { - DLOG(ERROR) << "Unexpected protocol version received."; - return base::nullopt; + VLOG(2) << "Unexpected protocol version received."; + continue; } if (!protocol_versions.insert(protocol).second)
diff --git a/gpu/command_buffer/common/buffer.cc b/gpu/command_buffer/common/buffer.cc index 1aa3bffe..4682400 100644 --- a/gpu/command_buffer/common/buffer.cc +++ b/gpu/command_buffer/common/buffer.cc
@@ -24,6 +24,19 @@ return base::UnguessableToken(); } +MemoryBufferBacking::MemoryBufferBacking(size_t size) + : memory_(new char[size]), size_(size) {} + +MemoryBufferBacking::~MemoryBufferBacking() = default; + +void* MemoryBufferBacking::GetMemory() const { + return memory_.get(); +} + +size_t MemoryBufferBacking::GetSize() const { + return size_; +} + SharedMemoryBufferBacking::SharedMemoryBufferBacking( base::UnsafeSharedMemoryRegion shared_memory_region, base::WritableSharedMemoryMapping shared_memory_mapping)
diff --git a/gpu/command_buffer/common/buffer.h b/gpu/command_buffer/common/buffer.h index db89809..e7c3198 100644 --- a/gpu/command_buffer/common/buffer.h +++ b/gpu/command_buffer/common/buffer.h
@@ -27,6 +27,20 @@ virtual size_t GetSize() const = 0; }; +class GPU_EXPORT MemoryBufferBacking : public BufferBacking { + public: + explicit MemoryBufferBacking(size_t size); + ~MemoryBufferBacking() override; + void* GetMemory() const override; + size_t GetSize() const override; + + private: + std::unique_ptr<char[]> memory_; + size_t size_; + DISALLOW_COPY_AND_ASSIGN(MemoryBufferBacking); +}; + + class GPU_EXPORT SharedMemoryBufferBacking : public BufferBacking { public: SharedMemoryBufferBacking( @@ -82,10 +96,15 @@ static inline scoped_refptr<Buffer> MakeBufferFromSharedMemory( base::UnsafeSharedMemoryRegion shared_memory_region, base::WritableSharedMemoryMapping shared_memory_mapping) { - return new Buffer(MakeBackingFromSharedMemory( + return base::MakeRefCounted<Buffer>(MakeBackingFromSharedMemory( std::move(shared_memory_region), std::move(shared_memory_mapping))); } +static inline scoped_refptr<Buffer> MakeMemoryBuffer(size_t size) { + return base::MakeRefCounted<Buffer>( + std::make_unique<MemoryBufferBacking>(size)); +} + // Generates GUID which can be used to trace buffer using an Id. GPU_EXPORT base::trace_event::MemoryAllocatorDumpGuid GetBufferGUIDForTracing( uint64_t tracing_process_id,
diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc index 453e59d..04eaddd1 100644 --- a/gpu/command_buffer/service/command_buffer_service.cc +++ b/gpu/command_buffer/service/command_buffer_service.cc
@@ -18,24 +18,6 @@ namespace gpu { -namespace { - -class MemoryBufferBacking : public BufferBacking { - public: - explicit MemoryBufferBacking(size_t size) - : memory_(new char[size]), size_(size) {} - ~MemoryBufferBacking() override = default; - void* GetMemory() const override { return memory_.get(); } - size_t GetSize() const override { return size_; } - - private: - std::unique_ptr<char[]> memory_; - size_t size_; - DISALLOW_COPY_AND_ASSIGN(MemoryBufferBacking); -}; - -} // anonymous namespace - CommandBufferService::CommandBufferService( CommandBufferServiceClient* client, TransferBufferManager* transfer_buffer_manager) @@ -183,7 +165,7 @@ bool CommandBufferService::RegisterTransferBuffer( int32_t id, - std::unique_ptr<BufferBacking> buffer) { + scoped_refptr<Buffer> buffer) { return transfer_buffer_manager_->RegisterTransferBuffer(id, std::move(buffer)); } @@ -191,13 +173,13 @@ scoped_refptr<Buffer> CommandBufferService::CreateTransferBufferWithId( size_t size, int32_t id) { - if (!RegisterTransferBuffer(id, - std::make_unique<MemoryBufferBacking>(size))) { + scoped_refptr<Buffer> buffer = MakeMemoryBuffer(size); + if (!RegisterTransferBuffer(id, buffer)) { SetParseError(gpu::error::kOutOfBounds); return nullptr; } - return GetTransferBuffer(id); + return buffer; } void CommandBufferService::SetToken(int32_t token) {
diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h index 8028d0e..b6bfb5c 100644 --- a/gpu/command_buffer/service/command_buffer_service.h +++ b/gpu/command_buffer/service/command_buffer_service.h
@@ -97,10 +97,9 @@ // Sets the get buffer and call the GetBufferChangeCallback. void SetGetBuffer(int32_t transfer_buffer_id); - // Registers an existing shared memory object with a given ID that can be used - // to identify it in the command buffer. - bool RegisterTransferBuffer(int32_t id, - std::unique_ptr<BufferBacking> buffer); + // Registers an existing Buffer object with a given ID that can be used to + // identify it in the command buffer. + bool RegisterTransferBuffer(int32_t id, scoped_refptr<Buffer> buffer); // Unregisters and destroys the transfer buffer associated with the given id. void DestroyTransferBuffer(int32_t id);
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.cc b/gpu/command_buffer/service/transfer_buffer_manager.cc index 6f70b40..c4a3a45 100644 --- a/gpu/command_buffer/service/transfer_buffer_manager.cc +++ b/gpu/command_buffer/service/transfer_buffer_manager.cc
@@ -51,7 +51,7 @@ bool TransferBufferManager::RegisterTransferBuffer( int32_t id, - std::unique_ptr<BufferBacking> buffer_backing) { + scoped_refptr<Buffer> buffer) { if (id <= 0) { DVLOG(0) << "Cannot register transfer buffer with non-positive ID."; return false; @@ -63,16 +63,13 @@ return false; } - // Register the shared memory with the ID. - scoped_refptr<Buffer> buffer(new gpu::Buffer(std::move(buffer_backing))); - // Check buffer alignment is sane. DCHECK(!(reinterpret_cast<uintptr_t>(buffer->memory()) & (kCommandBufferEntrySize - 1))); shared_memory_bytes_allocated_ += buffer->size(); - registered_buffers_[id] = buffer; + registered_buffers_[id] = std::move(buffer); return true; }
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.h b/gpu/command_buffer/service/transfer_buffer_manager.h index efe7631..78ce317 100644 --- a/gpu/command_buffer/service/transfer_buffer_manager.h +++ b/gpu/command_buffer/service/transfer_buffer_manager.h
@@ -17,7 +17,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/trace_event/memory_dump_provider.h" -#include "gpu/command_buffer/common/command_buffer_shared.h" +#include "gpu/command_buffer/common/command_buffer.h" namespace gpu { namespace gles2 { @@ -34,8 +34,7 @@ bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) override; - bool RegisterTransferBuffer(int32_t id, - std::unique_ptr<BufferBacking> buffer_backing); + bool RegisterTransferBuffer(int32_t id, scoped_refptr<Buffer> buffer); void DestroyTransferBuffer(int32_t id); scoped_refptr<Buffer> GetTransferBuffer(int32_t id);
diff --git a/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc b/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc index 71047e82..08e3439d 100644 --- a/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc +++ b/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc
@@ -45,8 +45,8 @@ std::move(shm_region), std::move(shm_mapping)); SharedMemoryBufferBacking* backing_raw_ptr = backing.get(); - EXPECT_TRUE( - transfer_buffer_manager_->RegisterTransferBuffer(1, std::move(backing))); + EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer( + 1, base::MakeRefCounted<Buffer>(std::move(backing)))); scoped_refptr<Buffer> registered = transfer_buffer_manager_->GetTransferBuffer(1); @@ -55,20 +55,9 @@ EXPECT_EQ(shm_guid, backing_raw_ptr->GetGUID()); } -class FakeBufferBacking : public BufferBacking { - public: - void* GetMemory() const override { - return reinterpret_cast<void*>(0xBADF00D0); - } - size_t GetSize() const override { return 42; } - static std::unique_ptr<BufferBacking> Make() { - return std::unique_ptr<BufferBacking>(new FakeBufferBacking); - } -}; - TEST_F(TransferBufferManagerTest, CanDestroyTransferBuffer) { EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer( - 1, std::unique_ptr<BufferBacking>(new FakeBufferBacking))); + 1, MakeMemoryBuffer(42))); transfer_buffer_manager_->DestroyTransferBuffer(1); scoped_refptr<Buffer> registered = transfer_buffer_manager_->GetTransferBuffer(1); @@ -79,19 +68,19 @@ TEST_F(TransferBufferManagerTest, CannotRegregisterTransferBufferId) { EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer( - 1, FakeBufferBacking::Make())); + 1, MakeMemoryBuffer(42))); EXPECT_FALSE(transfer_buffer_manager_->RegisterTransferBuffer( - 1, FakeBufferBacking::Make())); + 1, MakeMemoryBuffer(42))); EXPECT_FALSE(transfer_buffer_manager_->RegisterTransferBuffer( - 1, FakeBufferBacking::Make())); + 1, MakeMemoryBuffer(42))); } TEST_F(TransferBufferManagerTest, CanReuseTransferBufferIdAfterDestroying) { EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer( - 1, FakeBufferBacking::Make())); + 1, MakeMemoryBuffer(42))); transfer_buffer_manager_->DestroyTransferBuffer(1); EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer( - 1, FakeBufferBacking::Make())); + 1, MakeMemoryBuffer(42))); } TEST_F(TransferBufferManagerTest, DestroyUnusedTransferBufferIdDoesNotCrash) { @@ -100,12 +89,12 @@ TEST_F(TransferBufferManagerTest, CannotRegisterNullTransferBuffer) { EXPECT_FALSE(transfer_buffer_manager_->RegisterTransferBuffer( - 0, FakeBufferBacking::Make())); + 0, MakeMemoryBuffer(42))); } TEST_F(TransferBufferManagerTest, CannotRegisterNegativeTransferBufferId) { EXPECT_FALSE(transfer_buffer_manager_->RegisterTransferBuffer( - -1, FakeBufferBacking::Make())); + -1, MakeMemoryBuffer(42))); } } // namespace gpu
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index bfd783e..0469214e 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc
@@ -206,7 +206,6 @@ bool InProcessCommandBuffer::MakeCurrent() { CheckSequencedThread(); - command_buffer_lock_.AssertAcquired(); if (error::IsError(command_buffer_->GetState().error)) { DLOG(ERROR) << "MakeCurrent failed because context lost."; @@ -691,7 +690,6 @@ void InProcessCommandBuffer::UpdateLastStateOnGpuThread() { CheckSequencedThread(); - command_buffer_lock_.AssertAcquired(); base::AutoLock lock(last_state_lock_); command_buffer_->UpdateState(); State state = command_buffer_->GetState(); @@ -702,7 +700,6 @@ void InProcessCommandBuffer::FlushOnGpuThread(int32_t put_offset) { CheckSequencedThread(); ScopedEvent handle_flush(&flush_event_); - base::AutoLock lock(command_buffer_lock_); if (!MakeCurrent()) return; @@ -727,7 +724,6 @@ void InProcessCommandBuffer::PerformDelayedWorkOnGpuThread() { CheckSequencedThread(); delayed_work_pending_ = false; - base::AutoLock lock(command_buffer_lock_); // TODO(sunnyps): Should this use ScopedCrashKey instead? crash_keys::gpu_gl_context_is_virtual.Set(use_virtualized_gl_context_ ? "1" : "0"); @@ -818,7 +814,6 @@ void InProcessCommandBuffer::SetGetBufferOnGpuThread( int32_t shm_id, base::WaitableEvent* completion) { - base::AutoLock lock(command_buffer_lock_); command_buffer_->SetGetBuffer(shm_id); UpdateLastStateOnGpuThread(); completion->Signal(); @@ -828,8 +823,20 @@ size_t size, int32_t* id) { CheckSequencedThread(); - base::AutoLock lock(command_buffer_lock_); - return command_buffer_->CreateTransferBuffer(size, id); + scoped_refptr<Buffer> buffer = MakeMemoryBuffer(size); + *id = ++next_transfer_buffer_id_; + base::OnceClosure task = + base::BindOnce(&InProcessCommandBuffer::RegisterTransferBufferOnGpuThread, + base::Unretained(this), *id, buffer); + + QueueOnceTask(false, std::move(task)); + return buffer; +} + +void InProcessCommandBuffer::RegisterTransferBufferOnGpuThread( + int32_t id, + scoped_refptr<Buffer> buffer) { + command_buffer_->RegisterTransferBuffer(id, std::move(buffer)); } void InProcessCommandBuffer::DestroyTransferBuffer(int32_t id) { @@ -842,7 +849,6 @@ } void InProcessCommandBuffer::DestroyTransferBufferOnGpuThread(int32_t id) { - base::AutoLock lock(command_buffer_lock_); command_buffer_->DestroyTransferBuffer(id); }
diff --git a/gpu/ipc/in_process_command_buffer.h b/gpu/ipc/in_process_command_buffer.h index d6ff473..aa1b3d4e 100644 --- a/gpu/ipc/in_process_command_buffer.h +++ b/gpu/ipc/in_process_command_buffer.h
@@ -246,6 +246,8 @@ void SignalSyncTokenOnGpuThread(const SyncToken& sync_token, base::OnceClosure callback); void SignalQueryOnGpuThread(unsigned query_id, base::OnceClosure callback); + void RegisterTransferBufferOnGpuThread(int32_t id, + scoped_refptr<Buffer> buffer); void DestroyTransferBufferOnGpuThread(int32_t id); void CreateImageOnGpuThread(int32_t id, gfx::GpuMemoryBufferHandle handle, @@ -278,6 +280,7 @@ scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; std::unique_ptr<TransferBufferManager> transfer_buffer_manager_; + std::unique_ptr<CommandBufferService> command_buffer_; std::unique_ptr<DecoderContext> decoder_; base::Optional<raster::GrCacheController> gr_cache_controller_; scoped_refptr<gl::GLContext> context_; @@ -299,12 +302,11 @@ int32_t last_put_offset_ = -1; Capabilities capabilities_; GpuMemoryBufferManager* gpu_memory_buffer_manager_ = nullptr; + int32_t next_transfer_buffer_id_ = 1; uint64_t next_fence_sync_release_ = 1; uint64_t flushed_fence_sync_release_ = 0; // Accessed on both threads: - std::unique_ptr<CommandBufferService> command_buffer_; - base::Lock command_buffer_lock_; base::WaitableEvent flush_event_; scoped_refptr<CommandBufferTaskExecutor> task_executor_;
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc index 9f05111..e91476a 100644 --- a/gpu/ipc/service/command_buffer_stub.cc +++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -644,8 +644,8 @@ if (command_buffer_) { command_buffer_->RegisterTransferBuffer( - id, MakeBackingFromSharedMemory(std::move(transfer_buffer), - std::move(mapping))); + id, MakeBufferFromSharedMemory(std::move(transfer_buffer), + std::move(mapping))); } }
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index ad0ee65..7ab88b7b 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -346,14 +346,10 @@ "public/internal/headless_devtools_client_impl.h", "public/internal/message_dispatcher.h", "public/internal/value_conversions.h", - "public/util/compositor_controller.cc", - "public/util/compositor_controller.h", "public/util/error_reporter.cc", "public/util/error_reporter.h", "public/util/user_agent.cc", "public/util/user_agent.h", - "public/util/virtual_time_controller.cc", - "public/util/virtual_time_controller.h", ] if (!is_fuchsia) { @@ -557,9 +553,7 @@ test("headless_unittests") { sources = [ "public/domains/types_unittest.cc", - "public/util/compositor_controller_unittest.cc", "public/util/error_reporter_unittest.cc", - "public/util/virtual_time_controller_test.cc", ] if (!is_component_build) { @@ -686,7 +680,6 @@ "lib/headless_browser_context_browsertest.cc", "lib/headless_devtools_client_browsertest.cc", "lib/headless_web_contents_browsertest.cc", - "public/util/compositor_controller_browsertest.cc", "test/headless_browser_test.cc", "test/headless_browser_test.h", "test/headless_client_browsertest.cc", @@ -745,12 +738,7 @@ if (is_linux) { # Only include this if we built the js_binary data += [ "$root_out_dir/headless_browser_tests.pak" ] - sources += [ - "test/headless_js_bindings_browsertest.cc", - "test/headless_render_browsertest.cc", - "test/headless_render_test.cc", - "test/headless_render_test.h", - ] + sources += [ "test/headless_js_bindings_browsertest.cc" ] deps += [ ":headless_browser_tests_pak", "//ui/gfx:geometry_skia",
diff --git a/headless/public/util/DEPS b/headless/public/util/DEPS index 5d54b89..e5ed6729 100644 --- a/headless/public/util/DEPS +++ b/headless/public/util/DEPS
@@ -1,9 +1,3 @@ specific_include_rules = { - "compositor_controller_browsertest.cc": [ - "+cc/base/switches.h", - "+components/viz/common/features.h", - "+components/viz/common/switches.h", - "+third_party/skia/include", - ] }
diff --git a/headless/public/util/compositor_controller.cc b/headless/public/util/compositor_controller.cc deleted file mode 100644 index 0cd424d..0000000 --- a/headless/public/util/compositor_controller.cc +++ /dev/null
@@ -1,261 +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. - -#include "headless/public/util/compositor_controller.h" - -#include <memory> - -#include "base/base64.h" -#include "base/bind.h" -#include "base/cancelable_callback.h" -#include "base/logging.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/trace_event/trace_event.h" -#include "headless/public/util/virtual_time_controller.h" - -namespace headless { - -// Sends BeginFrames to advance animations while virtual time advances in -// intervals. -class CompositorController::AnimationBeginFrameTask - : public VirtualTimeController::RepeatingTask, - public VirtualTimeController::ResumeDeferrer { - public: - explicit AnimationBeginFrameTask(CompositorController* compositor_controller) - : RepeatingTask(StartPolicy::START_IMMEDIATELY, -1), - compositor_controller_(compositor_controller), - weak_ptr_factory_(this) {} - - // VirtualTimeController::RepeatingTask implementation: - void IntervalElapsed( - base::TimeDelta virtual_time_offset, - base::OnceCallback<void(ContinuePolicy)> continue_callback) override { - needs_begin_frame_on_virtual_time_resume_ = true; - std::move(continue_callback).Run(ContinuePolicy::NOT_REQUIRED); - } - - // VirtualTimeController::ResumeDeferrer implementation: - void DeferResume(base::OnceClosure continue_callback) override { - // Run a BeginFrame if we scheduled one in the last interval and no other - // BeginFrame was sent while virtual time was paused. - if (needs_begin_frame_on_virtual_time_resume_) { - continue_callback_ = std::move(continue_callback); - IssueAnimationBeginFrame(); - return; - } - std::move(continue_callback).Run(); - } - - void CompositorControllerIssuingScreenshotBeginFrame() { - TRACE_EVENT0("headless", - "CompositorController::AnimationBeginFrameTask::" - "CompositorControllerIssuingScreenshotBeginFrame"); - // The screenshotting BeginFrame will replace our animation-only BeginFrame. - // We cancel any pending animation BeginFrame to avoid sending two - // BeginFrames within the same virtual time pause. - needs_begin_frame_on_virtual_time_resume_ = false; - } - - private: - void IssueAnimationBeginFrame() { - TRACE_EVENT0("headless", - "CompositorController::AnimationBeginFrameTask::" - "IssueAnimationBeginFrame"); - needs_begin_frame_on_virtual_time_resume_ = false; - - bool update_display = - compositor_controller_->update_display_for_animations_; - // Display needs to be updated for first BeginFrame. Otherwise, the - // RenderWidget's surface may not be created and the root surface may block - // waiting for it forever. - update_display |= - compositor_controller_->last_begin_frame_time_ == base::TimeTicks(); - - compositor_controller_->PostBeginFrame( - base::BindOnce(&AnimationBeginFrameTask::BeginFrameComplete, - weak_ptr_factory_.GetWeakPtr()), - !update_display); - } - - void BeginFrameComplete(std::unique_ptr<BeginFrameResult>) { - TRACE_EVENT0( - "headless", - "CompositorController::AnimationBeginFrameTask::BeginFrameComplete"); - DCHECK(continue_callback_); - std::move(continue_callback_).Run(); - } - - CompositorController* compositor_controller_; // NOT OWNED - bool needs_begin_frame_on_virtual_time_resume_ = true; - base::CancelableClosure begin_frame_task_; - - base::OnceClosure continue_callback_; - base::WeakPtrFactory<AnimationBeginFrameTask> weak_ptr_factory_; -}; - -CompositorController::CompositorController( - scoped_refptr<base::SequencedTaskRunner> task_runner, - HeadlessDevToolsClient* devtools_client, - VirtualTimeController* virtual_time_controller, - base::TimeDelta animation_begin_frame_interval, - bool update_display_for_animations) - : task_runner_(std::move(task_runner)), - devtools_client_(devtools_client), - virtual_time_controller_(virtual_time_controller), - animation_task_(std::make_unique<AnimationBeginFrameTask>(this)), - animation_begin_frame_interval_(animation_begin_frame_interval), - update_display_for_animations_(update_display_for_animations), - weak_ptr_factory_(this) { - devtools_client_->GetHeadlessExperimental()->GetExperimental()->AddObserver( - this); - // No need to wait for completion of this, since we are waiting for the - // setNeedsBeginFramesChanged event instead, which will be sent at some point - // after enabling the domain. - devtools_client_->GetHeadlessExperimental()->GetExperimental()->Enable( - headless_experimental::EnableParams::Builder().Build()); - virtual_time_controller_->ScheduleRepeatingTask( - animation_task_.get(), animation_begin_frame_interval_); - virtual_time_controller_->SetResumeDeferrer(animation_task_.get()); -} - -CompositorController::~CompositorController() { - virtual_time_controller_->CancelRepeatingTask(animation_task_.get()); - virtual_time_controller_->SetResumeDeferrer(nullptr); - devtools_client_->GetHeadlessExperimental() - ->GetExperimental() - ->RemoveObserver(this); -} - -void CompositorController::PostBeginFrame( - base::OnceCallback<void(std::unique_ptr<BeginFrameResult>)> - begin_frame_complete_callback, - bool no_display_updates, - std::unique_ptr<ScreenshotParams> screenshot) { - // In certain nesting situations, we should not issue a BeginFrame immediately - // - for example, issuing a new BeginFrame within a BeginFrameCompleted or - // NeedsBeginFramesChanged event can upset the compositor. We avoid these - // situations by issuing our BeginFrames from a separately posted task. - task_runner_->PostTask( - FROM_HERE, base::BindOnce(&CompositorController::BeginFrame, - weak_ptr_factory_.GetWeakPtr(), - std::move(begin_frame_complete_callback), - no_display_updates, std::move(screenshot))); -} - -void CompositorController::BeginFrame( - base::OnceCallback<void(std::unique_ptr<BeginFrameResult>)> - begin_frame_complete_callback, - bool no_display_updates, - std::unique_ptr<ScreenshotParams> screenshot) { - DCHECK(!begin_frame_complete_callback_); - begin_frame_complete_callback_ = std::move(begin_frame_complete_callback); - if (needs_begin_frames_ || screenshot) { - auto params_builder = headless_experimental::BeginFrameParams::Builder(); - - // Use virtual time for frame time, so that rendering of animations etc. is - // aligned with virtual time progression. - base::TimeTicks frame_time = - virtual_time_controller_->GetCurrentVirtualTime(); - if (frame_time <= last_begin_frame_time_) { - // Frame time cannot go backwards or stop, so we issue another BeginFrame - // with a small time offset from the last BeginFrame's time instead. - frame_time = - last_begin_frame_time_ + base::TimeDelta::FromMicroseconds(1); - } - params_builder.SetFrameTimeTicks( - (frame_time - base::TimeTicks()).InMillisecondsF()); - DCHECK_GT(frame_time, last_begin_frame_time_); - last_begin_frame_time_ = frame_time; - - params_builder.SetInterval( - animation_begin_frame_interval_.InMillisecondsF()); - - params_builder.SetNoDisplayUpdates(no_display_updates); - - if (screenshot) - params_builder.SetScreenshot(std::move(screenshot)); - - devtools_client_->GetHeadlessExperimental()->GetExperimental()->BeginFrame( - params_builder.Build(), - base::BindOnce(&CompositorController::BeginFrameComplete, - weak_ptr_factory_.GetWeakPtr())); - } else { - BeginFrameComplete(nullptr); - } -} - -void CompositorController::BeginFrameComplete( - std::unique_ptr<BeginFrameResult> result) { - std::move(begin_frame_complete_callback_).Run(std::move(result)); - if (idle_callback_) - std::move(idle_callback_).Run(); -} - -void CompositorController::OnNeedsBeginFramesChanged( - const NeedsBeginFramesChangedParams& params) { - needs_begin_frames_ = params.GetNeedsBeginFrames(); -} - -void CompositorController::WaitUntilIdle(base::OnceClosure idle_callback) { - TRACE_EVENT_INSTANT1("headless", "CompositorController::WaitUntilIdle", - TRACE_EVENT_SCOPE_THREAD, "begin_frame_in_flight", - !!begin_frame_complete_callback_); - DCHECK(!idle_callback_); - - if (!begin_frame_complete_callback_) { - std::move(idle_callback).Run(); - return; - } - - idle_callback_ = std::move(idle_callback); -} - -void CompositorController::CaptureScreenshot( - ScreenshotParamsFormat format, - int quality, - base::OnceCallback<void(const std::string&)> screenshot_captured_callback) { - TRACE_EVENT0("headless", "CompositorController::CaptureScreenshot"); - DCHECK(!begin_frame_complete_callback_); - DCHECK(!screenshot_captured_callback_); - - screenshot_captured_callback_ = std::move(screenshot_captured_callback); - - // Let AnimationBeginFrameTask know that it doesn't need to issue an - // animation BeginFrame for the current virtual time pause. - animation_task_->CompositorControllerIssuingScreenshotBeginFrame(); - - const bool no_display_updates = false; - PostBeginFrame( - base::BindOnce(&CompositorController::CaptureScreenshotBeginFrameComplete, - weak_ptr_factory_.GetWeakPtr()), - no_display_updates, - ScreenshotParams::Builder() - .SetFormat(format) - .SetQuality(quality) - .Build()); -} - -void CompositorController::CaptureScreenshotBeginFrameComplete( - std::unique_ptr<BeginFrameResult> result) { - TRACE_EVENT1( - "headless", "CompositorController::CaptureScreenshotBeginFrameComplete", - "hasScreenshotData", - result ? std::to_string(result->HasScreenshotData()) : "invalid"); - DCHECK(screenshot_captured_callback_); - if (result && result->HasScreenshotData()) { - // TODO(eseckler): Look into returning binary screenshot data via DevTools. - std::string decoded_data; - base::Base64Decode(result->GetScreenshotData(), &decoded_data); - std::move(screenshot_captured_callback_).Run(decoded_data); - } else { - LOG(ERROR) << "Screenshotting failed, BeginFrameResult has no data and " - "hasDamage is " - << (result ? std::to_string(result->HasScreenshotData()) - : "invalid"); - std::move(screenshot_captured_callback_).Run(std::string()); - } -} - -} // namespace headless
diff --git a/headless/public/util/compositor_controller.h b/headless/public/util/compositor_controller.h deleted file mode 100644 index 338a732..0000000 --- a/headless/public/util/compositor_controller.h +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef HEADLESS_PUBLIC_UTIL_COMPOSITOR_CONTROLLER_H_ -#define HEADLESS_PUBLIC_UTIL_COMPOSITOR_CONTROLLER_H_ - -#include "base/callback.h" -#include "base/cancelable_callback.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/sequenced_task_runner.h" -#include "base/time/time.h" -#include "headless/public/devtools/domains/headless_experimental.h" -#include "headless/public/headless_devtools_client.h" - -namespace headless { - -class VirtualTimeController; - -// Issues BeginFrames (Chromium's vsync signal) while virtual time advances and -// and takes screenshots. -class HEADLESS_EXPORT CompositorController - : public headless_experimental::ExperimentalObserver { - public: - using BeginFrameResult = headless_experimental::BeginFrameResult; - using NeedsBeginFramesChangedParams = - headless_experimental::NeedsBeginFramesChangedParams; - using ScreenshotParams = headless_experimental::ScreenshotParams; - using ScreenshotParamsFormat = headless_experimental::ScreenshotParamsFormat; - - // |animation_begin_frame_interval| specifies the virtual time between - // individual BeginFrames while virtual time advances. - // If |update_display_for_animations| is false, animation BeginFrames will not - // commit or draw visual updates to the display. This can be used to reduce - // the overhead of such BeginFrames in the common case that screenshots will - // be taken from separate BeginFrames. - CompositorController( - scoped_refptr<base::SequencedTaskRunner> task_runner, - HeadlessDevToolsClient* devtools_client, - VirtualTimeController* virtual_time_controller, - base::TimeDelta animation_begin_frame_interval, - bool update_display_for_animations = true); - ~CompositorController() override; - - // Executes |idle_callback| when no BeginFrames are in flight. - void WaitUntilIdle(base::OnceClosure idle_callback); - - // Captures a screenshot by issuing a BeginFrame. |quality| is only valid for - // jpeg format screenshots, in range 0..100. Should not be called again until - // |screenshot_captured_callback| was run. Should only be called while no - // other BeginFrame is in flight and after the compositor is ready. - void CaptureScreenshot(ScreenshotParamsFormat format, - int quality, - base::OnceCallback<void(const std::string&)> - screenshot_captured_callback); - - private: - class AnimationBeginFrameTask; - - // headless_experimental_::Observer implementation: - void OnNeedsBeginFramesChanged( - const NeedsBeginFramesChangedParams& params) override; - - // Posts a BeginFrame as a new task to avoid nesting it inside the current - // callstack, which can upset the compositor. - void PostBeginFrame( - base::OnceCallback<void(std::unique_ptr<BeginFrameResult>)> - begin_frame_complete_callback, - bool no_display_updates = false, - std::unique_ptr<ScreenshotParams> screenshot = nullptr); - // Issues a BeginFrame synchronously and runs |begin_frame_complete_callback| - // when done. Should not be called again until |begin_frame_complete_callback| - // was run. - void BeginFrame(base::OnceCallback<void(std::unique_ptr<BeginFrameResult>)> - begin_frame_complete_callback, - bool no_display_updates = false, - std::unique_ptr<ScreenshotParams> screenshot = nullptr); - // Runs the |begin_frame_complete_callback_| and the |idle_callback_| if set. - void BeginFrameComplete(std::unique_ptr<BeginFrameResult>); - - void CaptureScreenshotBeginFrameComplete( - std::unique_ptr<BeginFrameResult> result); - - scoped_refptr<base::SequencedTaskRunner> task_runner_; - HeadlessDevToolsClient* devtools_client_; // NOT OWNED - VirtualTimeController* virtual_time_controller_; // NOT OWNED - std::unique_ptr<AnimationBeginFrameTask> animation_task_; - base::OnceClosure idle_callback_; - base::OnceCallback<void(const std::string&)> screenshot_captured_callback_; - base::OnceCallback<void(std::unique_ptr<BeginFrameResult>)> - begin_frame_complete_callback_; - base::TimeDelta animation_begin_frame_interval_; - bool update_display_for_animations_; - bool needs_begin_frames_ = false; - base::TimeTicks last_begin_frame_time_; - base::WeakPtrFactory<CompositorController> weak_ptr_factory_; -}; - -} // namespace headless - -#endif // HEADLESS_PUBLIC_UTIL_COMPOSITOR_CONTROLLER_H_
diff --git a/headless/public/util/compositor_controller_browsertest.cc b/headless/public/util/compositor_controller_browsertest.cc deleted file mode 100644 index 994f73c..0000000 --- a/headless/public/util/compositor_controller_browsertest.cc +++ /dev/null
@@ -1,715 +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. - -#include "headless/public/util/compositor_controller.h" - -#include <memory> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/command_line.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "cc/base/switches.h" -#include "components/viz/common/features.h" -#include "components/viz/common/switches.h" -#include "content/public/common/content_switches.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/browser_test_utils.h" -#include "headless/lib/browser/headless_web_contents_impl.h" -#include "headless/public/devtools/domains/emulation.h" -#include "headless/public/devtools/domains/runtime.h" -#include "headless/public/headless_browser.h" -#include "headless/public/headless_devtools_client.h" -#include "headless/public/util/virtual_time_controller.h" -#include "headless/test/headless_browser_test.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/codec/png_codec.h" - -using testing::ElementsAre; - -#define EXPECT_SCOPED(statements) \ - { \ - SCOPED_TRACE(""); \ - statements; \ - } - -namespace headless { - -// BeginFrameControl is not supported on Mac. -#if !defined(OS_MACOSX) - -namespace { - -class BeginFrameCounter : HeadlessDevToolsClient::RawProtocolListener { - public: - BeginFrameCounter(HeadlessDevToolsClient* client) : client_(client) { - client_->SetRawProtocolListener(this); - } - - ~BeginFrameCounter() override { client_->SetRawProtocolListener(nullptr); } - - bool OnProtocolMessage(const std::string& json_message, - const base::DictionaryValue& parsed_message) override { - const base::Value* id_value = parsed_message.FindKey("id"); - if (!id_value) - return false; - - const base::DictionaryValue* result_dict; - if (parsed_message.GetDictionary("result", &result_dict)) { - bool has_damage; - if (result_dict->GetBoolean("hasDamage", &has_damage)) - ++begin_frame_count_; - } - return false; - } - - int begin_frame_count() const { return begin_frame_count_; } - - private: - HeadlessDevToolsClient* client_; // NOT OWNED. - int begin_frame_count_ = 0; -}; - -bool DecodePNG(std::string png_data, SkBitmap* bitmap) { - return gfx::PNGCodec::Decode( - reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(), - bitmap); -} - -} // namespace - -class CompositorControllerBrowserTest - : public HeadlessAsyncDevTooledBrowserTest, - public ::testing::WithParamInterface<bool> { - public: - class AdditionalVirtualTimeBudget - : public VirtualTimeController::RepeatingTask, - public VirtualTimeController::Observer { - public: - AdditionalVirtualTimeBudget( - VirtualTimeController* virtual_time_controller, - StartPolicy start_policy, - base::TimeDelta budget, - base::OnceClosure budget_expired_callback, - base::OnceClosure virtual_time_started_callback = base::OnceClosure()) - : RepeatingTask(start_policy, 0), - virtual_time_controller_(virtual_time_controller), - budget_expired_callback_(std::move(budget_expired_callback)), - virtual_time_started_callback_( - std::move(virtual_time_started_callback)) { - virtual_time_controller_->ScheduleRepeatingTask(this, budget); - virtual_time_controller_->AddObserver(this); - virtual_time_controller_->StartVirtualTime(); - } - - ~AdditionalVirtualTimeBudget() override { - virtual_time_controller_->RemoveObserver(this); - virtual_time_controller_->CancelRepeatingTask(this); - } - - // headless::VirtualTimeController::RepeatingTask implementation: - void IntervalElapsed( - base::TimeDelta virtual_time, - base::OnceCallback<void(ContinuePolicy)> continue_callback) override { - std::move(continue_callback).Run(ContinuePolicy::NOT_REQUIRED); - } - - // headless::VirtualTimeController::Observer: - void VirtualTimeStarted(base::TimeDelta virtual_time_offset) override { - if (virtual_time_started_callback_) - std::move(virtual_time_started_callback_).Run(); - } - - void VirtualTimeStopped(base::TimeDelta virtual_time_offset) override { - std::move(budget_expired_callback_).Run(); - delete this; - } - - private: - headless::VirtualTimeController* const virtual_time_controller_; - base::OnceClosure budget_expired_callback_; - base::OnceClosure virtual_time_started_callback_; - }; - - void SetUp() override { - EnablePixelOutput(); - if (GetParam()) { - UseSoftwareCompositing(); - SetUpWithoutGPU(); - } else { - HeadlessAsyncDevTooledBrowserTest::SetUp(); - } - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - HeadlessAsyncDevTooledBrowserTest::SetUpCommandLine(command_line); - // See bit.ly/headless-rendering for why we use these flags. - command_line->AppendSwitch(switches::kRunAllCompositorStagesBeforeDraw); - command_line->AppendSwitch(switches::kDisableNewContentRenderingTimeout); - command_line->AppendSwitch(cc::switches::kDisableCheckerImaging); - command_line->AppendSwitch(cc::switches::kDisableThreadedAnimation); - command_line->AppendSwitch(switches::kDisableImageAnimationResync); - command_line->AppendSwitch(switches::kDisableThreadedScrolling); - - scoped_feature_list_.InitAndEnableFeature( - features::kEnableSurfaceSynchronization); - } - - bool GetEnableBeginFrameControl() override { return true; } - - void RunDevTooledTest() override { - EXPECT_TRUE(embedded_test_server()->Start()); - - virtual_time_controller_ = - std::make_unique<VirtualTimeController>(devtools_client_.get()); - const bool update_display_for_animations = false; - compositor_controller_ = std::make_unique<CompositorController>( - browser()->BrowserMainThread(), devtools_client_.get(), - virtual_time_controller_.get(), GetAnimationFrameInterval(), - update_display_for_animations); - - // Initially pause virtual time. - devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( - emulation::SetVirtualTimePolicyParams::Builder() - .SetPolicy(emulation::VirtualTimePolicy::PAUSE) - .SetInitialVirtualTime(100) - .Build(), - base::BindRepeating( - &CompositorControllerBrowserTest::SetVirtualTimePolicyDone, - base::Unretained(this))); - } - - protected: - virtual base::TimeDelta GetAnimationFrameInterval() const { - return base::TimeDelta::FromMilliseconds(16); - } - - virtual std::string GetTestFile() const { return "/blank.html"; } - - void SetVirtualTimePolicyDone( - std::unique_ptr<emulation::SetVirtualTimePolicyResult>) { - // Run a first BeginFrame to initialize surface. Wait a while before doing - // so, since it takes a while before the compositor is ready for a - // RenderFrameSubmissionObserver. - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&CompositorControllerBrowserTest::RunFirstBeginFrame, - base::Unretained(this)), - base::TimeDelta::FromSeconds(1)); - } - - void RunFirstBeginFrame() { - begin_frame_counter_ = - std::make_unique<BeginFrameCounter>(devtools_client_.get()); - render_frame_submission_observer_ = - std::make_unique<content::RenderFrameSubmissionObserver>( - HeadlessWebContentsImpl::From(web_contents_)->web_contents()); - // AdditionalVirtualTimeBudget will self delete. - new AdditionalVirtualTimeBudget( - virtual_time_controller_.get(), - AdditionalVirtualTimeBudget::StartPolicy::WAIT_FOR_NAVIGATION, - GetAnimationFrameInterval(), - base::BindOnce( - &CompositorControllerBrowserTest::OnFirstBeginFrameComplete, - base::Unretained(this)), - base::BindOnce(&CompositorControllerBrowserTest::Navigate, - base::Unretained(this))); - } - - void Navigate() { - // Navigate (after the first BeginFrame) to start virtual time. - devtools_client_->GetPage()->Navigate( - embedded_test_server()->GetURL(GetTestFile()).spec()); - } - - virtual void OnFirstBeginFrameComplete() { - // With surface sync enabled, we should have waited for the renderer's - // CompositorFrame in the first BeginFrame. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(1, 1)); - } - - void FinishCompositorControllerTest() { - render_frame_submission_observer_.reset(); - FinishAsynchronousTest(); - } - - void ExpectAdditionalFrameCounts(int additional_begin_frame_count, - int additional_render_frame_count) { - expected_begin_frame_count_ += additional_begin_frame_count; - expected_render_frame_count_ += additional_render_frame_count; - EXPECT_EQ(expected_begin_frame_count_, - begin_frame_counter_->begin_frame_count()); - EXPECT_EQ(expected_render_frame_count_, - render_frame_submission_observer_->render_frame_count()); - } - - base::test::ScopedFeatureList scoped_feature_list_; - - std::unique_ptr<VirtualTimeController> virtual_time_controller_; - std::unique_ptr<CompositorController> compositor_controller_; - - std::unique_ptr<BeginFrameCounter> begin_frame_counter_; - std::unique_ptr<content::RenderFrameSubmissionObserver> - render_frame_submission_observer_; - - int expected_begin_frame_count_ = 0; - int expected_render_frame_count_ = 0; -}; - -// Runs requestAnimationFrame three times without updating display for -// animations and takes a screenshot. -class CompositorControllerRafBrowserTest - : public CompositorControllerBrowserTest, - public runtime::Observer { - private: - void OnFirstBeginFrameComplete() override { - CompositorControllerBrowserTest::OnFirstBeginFrameComplete(); - - devtools_client_->GetRuntime()->AddObserver(this); - devtools_client_->GetRuntime()->Enable( - base::BindRepeating(&CompositorControllerRafBrowserTest::RuntimeEnabled, - base::Unretained(this))); - } - - void RuntimeEnabled() { - // Request animation frames in the main frame. Each frame changes the body - // background color. - devtools_client_->GetRuntime()->Evaluate( - "window.rafCount = 0;" - "function onRaf(timestamp) {" - " console.log('rAF timestamp ' + timestamp + 'ms'); " - " window.rafCount++;" - " document.body.style.backgroundColor = '#' + window.rafCount * 100;" - " window.requestAnimationFrame(onRaf);" - "};" - "window.requestAnimationFrame(onRaf);", - base::BindRepeating(&CompositorControllerRafBrowserTest::OnRafReady, - base::Unretained(this))); - } - - // runtime::Observer implementation: - void OnConsoleAPICalled( - const runtime::ConsoleAPICalledParams& params) override { - // We expect the arguments always to be a single string. - const std::vector<std::unique_ptr<runtime::RemoteObject>>& args = - *params.GetArgs(); - if (args.size() == 1u && args[0]->HasValue()) - log_.push_back(args[0]->GetValue()->GetString()); - } - - void OnRafReady(std::unique_ptr<runtime::EvaluateResult> result) { - EXPECT_NE(nullptr, result); - EXPECT_FALSE(result->HasExceptionDetails()); - - // AdditionalVirtualTimeBudget will self delete. - new AdditionalVirtualTimeBudget( - virtual_time_controller_.get(), - AdditionalVirtualTimeBudget::StartPolicy::START_IMMEDIATELY, - kNumFrames * GetAnimationFrameInterval(), - base::BindOnce(&CompositorControllerRafBrowserTest::OnRafBudgetExpired, - base::Unretained(this))); - } - - void OnRafBudgetExpired() { - // Even though the rAF made a change to the frame's background color, no - // further CompositorFrames should have been produced for animations, - // because update_display_for_animations is false. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(kNumFrames, 0)); - - // Get animation frame count. - devtools_client_->GetRuntime()->Evaluate( - "window.rafCount", - base::BindRepeating(&CompositorControllerRafBrowserTest::OnGetRafCount, - base::Unretained(this))); - } - - void OnGetRafCount(std::unique_ptr<runtime::EvaluateResult> result) { - EXPECT_NE(nullptr, result); - EXPECT_FALSE(result->HasExceptionDetails()); - - EXPECT_EQ(kNumFrames, result->GetResult()->GetValue()->GetInt()); - - compositor_controller_->CaptureScreenshot( - headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::BindRepeating(&CompositorControllerRafBrowserTest::OnScreenshot, - base::Unretained(this))); - } - - void OnScreenshot(const std::string& screenshot_data) { - // Screenshot should have incurred a new CompositorFrame from renderer. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(1, 1)); - EXPECT_LT(0U, screenshot_data.length()); - - if (screenshot_data.length()) { - SkBitmap result_bitmap; - EXPECT_TRUE(DecodePNG(screenshot_data, &result_bitmap)); - - EXPECT_EQ(800, result_bitmap.width()); - EXPECT_EQ(600, result_bitmap.height()); - SkColor actual_color = result_bitmap.getColor(200, 200); - // Screenshot was the forth frame, so background color should be #400. - SkColor expected_color = SkColorSetRGB(0x44, 0x00, 0x00); - EXPECT_EQ(expected_color, actual_color); - } - - EXPECT_THAT(log_, ElementsAre("rAF timestamp 16ms", "rAF timestamp 32ms", - "rAF timestamp 48ms", "rAF timestamp 64ms")); - - FinishCompositorControllerTest(); - } - - static constexpr int kNumFrames = 3; - std::vector<std::string> log_; -}; - -/* static */ -constexpr int CompositorControllerRafBrowserTest::kNumFrames; - -HEADLESS_ASYNC_DEVTOOLED_TEST_P(CompositorControllerRafBrowserTest); - -// Instantiate test case for both software and gpu compositing modes. -INSTANTIATE_TEST_CASE_P(CompositorControllerRafBrowserTests, - CompositorControllerRafBrowserTest, - ::testing::Bool()); - -// Loads an animated GIF and verifies that: -// - animate_only BeginFrames don't produce CompositorFrames, -// - first screenshot starts the GIF animation, -// - animation is advanced according to virtual time. -// - the animation is not resynced after the first iteration. -class CompositorControllerImageAnimationBrowserTest - : public CompositorControllerBrowserTest { - private: - base::TimeDelta GetAnimationFrameInterval() const override { - return base::TimeDelta::FromMilliseconds(500); - } - - std::string GetTestFile() const override { - // GIF: 1 second blue, 1 second red, 1 second yellow (100x100px). - return "/animated_gif.html"; - } - - void OnFirstBeginFrameComplete() override { - CompositorControllerBrowserTest::OnFirstBeginFrameComplete(); - - // Post a task to grant more virtual time as we can't do this synchronously - // from within VirtualTimeStopped(). - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&CompositorControllerImageAnimationBrowserTest:: - GrantFirstIterationBudget, - base::Unretained(this))); - } - - void GrantFirstIterationBudget() { - // AdditionalVirtualTimeBudget will self delete. - new AdditionalVirtualTimeBudget( - virtual_time_controller_.get(), - AdditionalVirtualTimeBudget::StartPolicy::START_IMMEDIATELY, - kNumFramesFirstIteration * GetAnimationFrameInterval(), - base::BindOnce(&CompositorControllerImageAnimationBrowserTest:: - OnFirstBudgetExpired, - base::Unretained(this))); - } - - void OnFirstBudgetExpired() { - // The GIF should not have started animating yet, even though we advanced - // virtual time. It only starts animating when first painted, i.e. when the - // first screenshot is taken. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(kNumFramesFirstIteration, 0)); - - compositor_controller_->CaptureScreenshot( - headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::BindRepeating(&CompositorControllerImageAnimationBrowserTest:: - OnScreenshotAfterFirstIteration, - base::Unretained(this))); - } - - void OnScreenshotAfterFirstIteration(const std::string& screenshot_data) { - // Screenshot should have incurred a new CompositorFrame from renderer. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(1, 1)); - EXPECT_LT(0U, screenshot_data.length()); - - if (screenshot_data.length()) { - SkBitmap result_bitmap; - EXPECT_TRUE(DecodePNG(screenshot_data, &result_bitmap)); - - EXPECT_EQ(800, result_bitmap.width()); - EXPECT_EQ(600, result_bitmap.height()); - SkColor actual_color = result_bitmap.getColor(50, 50); - // Animation starts when first screenshot is taken, so should be blue. - SkColor expected_color = SkColorSetRGB(0x00, 0x00, 0xff); - EXPECT_EQ(expected_color, actual_color); - } - - // Advance another iteration and check again that no CompositorFrames are - // produced. AdditionalVirtualTimeBudget will self delete. - new AdditionalVirtualTimeBudget( - virtual_time_controller_.get(), - AdditionalVirtualTimeBudget::StartPolicy::START_IMMEDIATELY, - kNumFramesSecondIteration * GetAnimationFrameInterval(), - base::BindOnce(&CompositorControllerImageAnimationBrowserTest:: - OnSecondBudgetExpired, - base::Unretained(this))); - } - - void OnSecondBudgetExpired() { - // Even though the GIF animated, no further CompositorFrames should have - // been produced, because update_display_for_animations is false. The second - // iteration only produces kNumFramesSecondIteration - 1 BeginFrames since - // the first animation frame is skipped because of the prior screenshot. - EXPECT_SCOPED( - ExpectAdditionalFrameCounts(kNumFramesSecondIteration - 1, 0)); - - compositor_controller_->CaptureScreenshot( - headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::BindRepeating(&CompositorControllerImageAnimationBrowserTest:: - OnScreenshotAfterSecondIteration, - base::Unretained(this))); - } - - void OnScreenshotAfterSecondIteration(const std::string& screenshot_data) { - // Screenshot should have incurred a new CompositorFrame from renderer. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(1, 1)); - - EXPECT_LT(0U, screenshot_data.length()); - - if (screenshot_data.length()) { - SkBitmap result_bitmap; - EXPECT_TRUE(DecodePNG(screenshot_data, &result_bitmap)); - - EXPECT_EQ(800, result_bitmap.width()); - EXPECT_EQ(600, result_bitmap.height()); - SkColor actual_color = result_bitmap.getColor(50, 50); - // We advanced two animation frames, so animation should now be yellow. - SkColor expected_color = SkColorSetRGB(0xff, 0xff, 0x00); - EXPECT_EQ(expected_color, actual_color); - } - - // Advance a full animation iteration and check that animation doesn't reset - // to the beginning, because of kDisableImageAnimationResync. - new AdditionalVirtualTimeBudget( - virtual_time_controller_.get(), - AdditionalVirtualTimeBudget::StartPolicy::START_IMMEDIATELY, - kNumFramesThirdIteration * GetAnimationFrameInterval(), - base::BindOnce(&CompositorControllerImageAnimationBrowserTest:: - OnThirdBudgetExpired, - base::Unretained(this))); - } - - void OnThirdBudgetExpired() { - // Even though the GIF animated, no further CompositorFrames should have - // been produced, because update_display_for_animations is false. The third - // iteration only produces kNumFramesThirdIteration - 1 BeginFrames since - // the first animation frame is skipped because of the prior screenshot. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(kNumFramesThirdIteration - 1, 0)); - - compositor_controller_->CaptureScreenshot( - headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::BindRepeating(&CompositorControllerImageAnimationBrowserTest:: - OnScreenshotAfterThirdIteration, - base::Unretained(this))); - } - - void OnScreenshotAfterThirdIteration(const std::string& screenshot_data) { - // Screenshot should have incurred no new CompositorFrame from renderer - // since animation frame didn't change, but a new BeginFrame. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(1, 0)); - EXPECT_LT(0U, screenshot_data.length()); - - if (screenshot_data.length()) { - SkBitmap result_bitmap; - EXPECT_TRUE(DecodePNG(screenshot_data, &result_bitmap)); - - EXPECT_EQ(800, result_bitmap.width()); - EXPECT_EQ(600, result_bitmap.height()); - SkColor actual_color = result_bitmap.getColor(50, 50); - // We advanced a full iteration, so animation should be yellow again. - SkColor expected_color = SkColorSetRGB(0xff, 0xff, 0x00); - EXPECT_EQ(expected_color, actual_color); - } - - FinishCompositorControllerTest(); - } - - // Enough to cover a full animation iteration. - static constexpr int kNumFramesFirstIteration = 7; - // Advances two animation frames only. - static constexpr int kNumFramesSecondIteration = 5; - // Advances a full animation iteration. - static constexpr int kNumFramesThirdIteration = 6; -}; - -/* static */ -constexpr int - CompositorControllerImageAnimationBrowserTest::kNumFramesFirstIteration; -/* static */ -constexpr int - CompositorControllerImageAnimationBrowserTest::kNumFramesSecondIteration; -/* static */ -constexpr int - CompositorControllerImageAnimationBrowserTest::kNumFramesThirdIteration; - -HEADLESS_ASYNC_DEVTOOLED_TEST_P(CompositorControllerImageAnimationBrowserTest); - -// Instantiate test case for both software and gpu compositing modes. -INSTANTIATE_TEST_CASE_P(CompositorControllerImageAnimationBrowserTests, - CompositorControllerImageAnimationBrowserTest, - ::testing::Bool()); - -// Loads a CSS animation and verifies that: -// - animate_only BeginFrames don't produce CompositorFrames, -// - animate_only BeginFrames advance animations and trigger itersection events, -// - animation is advanced according to virtual time. -class CompositorControllerCssAnimationBrowserTest - : public CompositorControllerBrowserTest, - public runtime::Observer { - private: - base::TimeDelta GetAnimationFrameInterval() const override { - return base::TimeDelta::FromMilliseconds(500); - } - - std::string GetTestFile() const override { - // Animates opacity of a blue 100px square on red blackground over 4 - // seconds (100% -> 0% -> 100% four times). Logs events to console. - // - // Timeline: - // 0 ms: --- animation starts at 500ms --- - // 500 ms: 100% opacity -> blue background. - // 1000 ms: 0% opacity -> red background. - // 1500 ms: 100% opacity -> blue background. - // 2000 ms: 0% opacity -> red background. - // 2500 ms: 100% opacity -> blue background. - // 3000 ms: 0% opacity -> red background. - // 3500 ms: 100% opacity -> blue background. - // 4000 ms: 0% opacity -> red background. - // 4500 ms: 100% opacity -> blue background. - // - // The animation will start with the first BeginFrame after load. - return "/css_animation.html"; - } - - void OnFirstBeginFrameComplete() override { - CompositorControllerBrowserTest::OnFirstBeginFrameComplete(); - - // First frame advanced one BeginFrame interval. - elapsed_time_ += GetAnimationFrameInterval(); - - // First BeginFrame advanced by one interval. - devtools_client_->GetRuntime()->AddObserver(this); - devtools_client_->GetRuntime()->Enable(base::BindRepeating( - &CompositorControllerCssAnimationBrowserTest::RuntimeEnabled, - base::Unretained(this))); - } - - void RuntimeEnabled() { - // Animation starts with the first BeginFrame of this budget. Advance five - // frames to reach 3000ms, at which point the background should be red. - GrantBudget(GetAnimationFrameInterval() * 5); - } - - void GrantBudget(base::TimeDelta budget) { - // Grant the budget in two halves, with screenshots at the end of each. - // AdditionalVirtualTimeBudget will self delete. - new AdditionalVirtualTimeBudget( - virtual_time_controller_.get(), - AdditionalVirtualTimeBudget::StartPolicy::START_IMMEDIATELY, budget, - base::BindOnce( - &CompositorControllerCssAnimationBrowserTest::OnBudgetExpired, - base::Unretained(this), budget)); - } - - void OnBudgetExpired(base::TimeDelta budget) { - elapsed_time_ += budget; - - EXPECT_THAT( - elapsed_time_, - testing::AnyOf(testing::Eq(base::TimeDelta::FromMilliseconds(3000)), - testing::Eq(base::TimeDelta::FromMilliseconds(4500)))); - - if (elapsed_time_ == base::TimeDelta::FromMilliseconds(3000)) { - // We should have advanced five BeginFrames. No CompositorFrames from - // renderer because update_display_for_animations is false. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(5, 0)); - } else { - // We should have advanced two more BeginFrames since the second budget - // was preceded by a screenshot. No CompositorFrames from renderer - // because update_display_for_animations is false. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(2, 0)); - } - - compositor_controller_->CaptureScreenshot( - headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::BindRepeating( - &CompositorControllerCssAnimationBrowserTest::OnScreenshot, - base::Unretained(this))); - } - - void OnScreenshot(const std::string& screenshot_data) { - // Screenshot should have incurred a new CompositorFrame from renderer. - EXPECT_SCOPED(ExpectAdditionalFrameCounts(1, 1)); - EXPECT_LT(0U, screenshot_data.length()); - - if (screenshot_data.length()) { - SkBitmap result_bitmap; - EXPECT_TRUE(DecodePNG(screenshot_data, &result_bitmap)); - - EXPECT_EQ(800, result_bitmap.width()); - EXPECT_EQ(600, result_bitmap.height()); - SkColor actual_color = result_bitmap.getColor(50, 50); - - // First screenshot should be red, because box is not visible. - SkColor expected_color = SkColorSetRGB(0xff, 0x00, 0x00); - if (elapsed_time_ == base::TimeDelta::FromMilliseconds(4500)) { - // Box is visible in second screenshot, so it should be blue. - expected_color = SkColorSetRGB(0x00, 0x00, 0xff); - } - - EXPECT_EQ(expected_color, actual_color); - } - - if (elapsed_time_ == base::TimeDelta::FromMilliseconds(3000)) { - // Advance to the end of the animation. - GrantBudget(base::TimeDelta::FromMilliseconds(1500)); - } else { - EXPECT_THAT(log_, testing::ElementsAre( - // Animation actually started at 500ms, but the - // event is executed a BeginFrame later. - "event animationstart at 101000ms", - "event animationiteration at 101500ms", - "event animationiteration at 102500ms", - "event animationiteration at 103500ms", - "event animationend at 104500ms")); - FinishCompositorControllerTest(); - } - } - - // runtime::Observer implementation: - void OnConsoleAPICalled( - const runtime::ConsoleAPICalledParams& params) override { - // We expect the arguments always to be a single string. - const std::vector<std::unique_ptr<runtime::RemoteObject>>& args = - *params.GetArgs(); - if (args.size() == 1u && args[0]->HasValue()) - log_.push_back(args[0]->GetValue()->GetString()); - } - - base::TimeDelta elapsed_time_; - std::vector<std::string> log_; -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_P(CompositorControllerCssAnimationBrowserTest); - -// Instantiate test case for both software and gpu compositing modes. -INSTANTIATE_TEST_CASE_P(CompositorControllerCssAnimationBrowserTests, - CompositorControllerCssAnimationBrowserTest, - ::testing::Bool()); - -#endif // !defined(OS_MACOSX) - -} // namespace headless
diff --git a/headless/public/util/compositor_controller_unittest.cc b/headless/public/util/compositor_controller_unittest.cc deleted file mode 100644 index 016ee8f..0000000 --- a/headless/public/util/compositor_controller_unittest.cc +++ /dev/null
@@ -1,415 +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. - -#include "headless/public/util/compositor_controller.h" - -#include <memory> - -#include "base/base64.h" -#include "base/bind.h" -#include "base/json/json_writer.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "base/test/test_simple_task_runner.h" -#include "headless/public/internal/headless_devtools_client_impl.h" -#include "headless/public/util/virtual_time_controller.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace headless { - -namespace { -static constexpr base::TimeDelta kAnimationFrameInterval = - base::TimeDelta::FromMilliseconds(16); - -class MockChannel : public HeadlessDevToolsChannel { - public: - MockChannel() {} - ~MockChannel() override {} - MOCK_METHOD1(SetClient, void(HeadlessDevToolsChannel::Client*)); - MOCK_METHOD1(SendProtocolMessage, void(const std::string&)); -}; - -} // namespace - -using testing::_; -using testing::Return; - -class TestVirtualTimeController : public VirtualTimeController { - public: - TestVirtualTimeController(HeadlessDevToolsClient* devtools_client) - : VirtualTimeController(devtools_client) {} - ~TestVirtualTimeController() override = default; - - MOCK_METHOD0(StartVirtualTime, void()); - MOCK_METHOD2(ScheduleRepeatingTask, - void(RepeatingTask* task, base::TimeDelta interval)); - MOCK_METHOD1(CancelRepeatingTask, void(RepeatingTask* task)); - MOCK_METHOD1(AddObserver, void(Observer* observer)); - MOCK_METHOD1(RemoveObserver, void(Observer* observer)); - MOCK_METHOD1(SetResumeDeferrer, void(ResumeDeferrer* deferrer)); - - MOCK_CONST_METHOD0(GetVirtualTimeBase, base::TimeTicks()); - MOCK_CONST_METHOD0(GetCurrentVirtualTimeOffset, base::TimeDelta()); -}; - -class CompositorControllerTest : public ::testing::Test { - protected: - CompositorControllerTest(bool update_display_for_animations = true) { - task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>(); - auto channel = std::make_unique<MockChannel>(); - mock_channel_ = channel.get(); - client_.AttachToChannel(std::move(channel)); - client_.SetTaskRunnerForTests(task_runner_); - - virtual_time_controller_ = - std::make_unique<TestVirtualTimeController>(&client_); - EXPECT_CALL(*virtual_time_controller_, - ScheduleRepeatingTask(_, kAnimationFrameInterval)) - .WillOnce(testing::SaveArg<0>(&task_)); - EXPECT_CALL(*virtual_time_controller_, SetResumeDeferrer(_)) - .WillOnce(testing::SaveArg<0>(&deferrer_)); - ExpectHeadlessExperimentalEnable(); - controller_ = std::make_unique<CompositorController>( - task_runner_, &client_, virtual_time_controller_.get(), - kAnimationFrameInterval, update_display_for_animations); - EXPECT_NE(nullptr, task_); - } - - ~CompositorControllerTest() override { - EXPECT_CALL(*virtual_time_controller_, CancelRepeatingTask(_)); - EXPECT_CALL(*virtual_time_controller_, SetResumeDeferrer(_)); - } - - void ExpectHeadlessExperimentalEnable() { - last_command_id_ += 2; - EXPECT_CALL(*mock_channel_, - SendProtocolMessage(base::StringPrintf( - "{\"id\":%d,\"method\":\"HeadlessExperimental.enable\"," - "\"params\":{}}", - last_command_id_))); - } - - void ExpectVirtualTime(double base, double offset) { - auto base_time_ticks = - base::TimeTicks() + base::TimeDelta::FromMillisecondsD(base); - auto offset_delta = base::TimeDelta::FromMilliseconds(offset); - EXPECT_CALL(*virtual_time_controller_, GetVirtualTimeBase()) - .WillOnce(Return(base_time_ticks)); - EXPECT_CALL(*virtual_time_controller_, GetCurrentVirtualTimeOffset()) - .WillOnce(Return(offset_delta)); - - // Next BeginFrame's time should be the virtual time provided it has - // progressed. - base::TimeTicks virtual_time = base_time_ticks + offset_delta; - if (virtual_time > next_begin_frame_time_) - next_begin_frame_time_ = virtual_time; - } - - void ExpectBeginFrame(bool no_display_updates = false, - std::unique_ptr<headless_experimental::ScreenshotParams> - screenshot_params = nullptr) { - last_command_id_ += 2; - base::DictionaryValue params; - auto builder = std::move( - headless_experimental::BeginFrameParams::Builder() - .SetFrameTimeTicks( - (next_begin_frame_time_ - base::TimeTicks()).InMillisecondsF()) - .SetInterval(kAnimationFrameInterval.InMillisecondsF()) - .SetNoDisplayUpdates(no_display_updates)); - if (screenshot_params) - builder.SetScreenshot(std::move(screenshot_params)); - // Subsequent BeginFrames should have a later timestamp. - next_begin_frame_time_ += base::TimeDelta::FromMicroseconds(1); - - std::string params_json; - auto params_value = builder.Build()->Serialize(); - base::JSONWriter::Write(*params_value, ¶ms_json); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage(base::StringPrintf( - "{\"id\":%d,\"method\":\"HeadlessExperimental.beginFrame\"," - "\"params\":%s}", - last_command_id_, params_json.c_str()))); - } - - void SendBeginFrameReply(bool has_damage, - const std::string& screenshot_data) { - auto result = headless_experimental::BeginFrameResult::Builder() - .SetHasDamage(has_damage) - .Build(); - if (screenshot_data.length()) - result->SetScreenshotData(screenshot_data); - std::string result_json; - auto result_value = result->Serialize(); - base::JSONWriter::Write(*result_value, &result_json); - - client_.ReceiveProtocolMessage(base::StringPrintf( - "{\"id\":%d,\"result\":%s}", last_command_id_, result_json.c_str())); - task_runner_->RunPendingTasks(); - } - - void SendNeedsBeginFramesEvent(bool needs_begin_frames) { - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"method\":\"HeadlessExperimental." - "needsBeginFramesChanged\",\"params\":{" - "\"needsBeginFrames\":%s}}", - needs_begin_frames ? "true" : "false")); - // Events are dispatched asynchronously. - task_runner_->RunPendingTasks(); - } - - scoped_refptr<base::TestSimpleTaskRunner> task_runner_; - HeadlessDevToolsClientImpl client_; - MockChannel* mock_channel_ = nullptr; - std::unique_ptr<TestVirtualTimeController> virtual_time_controller_; - std::unique_ptr<CompositorController> controller_; - int last_command_id_ = -2; - TestVirtualTimeController::RepeatingTask* task_ = nullptr; - TestVirtualTimeController::Observer* observer_ = nullptr; - TestVirtualTimeController::ResumeDeferrer* deferrer_ = nullptr; - base::TimeTicks next_begin_frame_time_ = - base::TimeTicks() + base::TimeDelta::FromMicroseconds(1); -}; - -TEST_F(CompositorControllerTest, CaptureScreenshot) { - bool done = false; - controller_->CaptureScreenshot( - headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::BindRepeating( - [](bool* done, const std::string& screenshot_data) { - *done = true; - EXPECT_EQ("test", screenshot_data); - }, - &done)); - - EXPECT_TRUE(task_runner_->HasPendingTask()); - ExpectVirtualTime(0, 0); - ExpectBeginFrame( - false, headless_experimental::ScreenshotParams::Builder() - .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG) - .SetQuality(100) - .Build()); - task_runner_->RunPendingTasks(); - - std::string base64; - base::Base64Encode("test", &base64); - SendBeginFrameReply(true, base64); - EXPECT_FALSE(task_runner_->HasPendingTask()); - EXPECT_TRUE(done); -} - -TEST_F(CompositorControllerTest, SendsAnimationFrames) { - base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy> - continue_policy; - auto continue_callback = base::BindRepeating( - [](base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>* - continue_policy, - VirtualTimeController::RepeatingTask::ContinuePolicy policy) { - *continue_policy = policy; - }, - &continue_policy); - - // Doesn't send BeginFrames before virtual time started. - SendNeedsBeginFramesEvent(true); - EXPECT_FALSE(task_runner_->HasPendingTask()); - - bool can_continue = false; - auto defer_callback = base::BindRepeating( - [](bool* can_continue) { *can_continue = true; }, &can_continue); - - // Sends a BeginFrame at start of interval. - deferrer_->DeferResume(defer_callback); - EXPECT_TRUE(task_runner_->HasPendingTask()); - - ExpectVirtualTime(1000, 0); - ExpectBeginFrame(); - task_runner_->RunPendingTasks(); - EXPECT_FALSE(can_continue); - - // Lets virtual time continue after BeginFrame was completed. - SendBeginFrameReply(false, std::string()); - EXPECT_FALSE(task_runner_->HasPendingTask()); - EXPECT_TRUE(can_continue); - can_continue = false; - - // Sends a BeginFrame after interval elapsed, but only just before virtual - // time resumes. - task_->IntervalElapsed(kAnimationFrameInterval, continue_callback); - EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED, - *continue_policy); - continue_policy = base::nullopt; - EXPECT_FALSE(task_runner_->HasPendingTask()); - - deferrer_->DeferResume(defer_callback); - EXPECT_TRUE(task_runner_->HasPendingTask()); - - ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF()); - ExpectBeginFrame(); - task_runner_->RunPendingTasks(); - EXPECT_FALSE(can_continue); - - // Lets virtual time continue after BeginFrame was completed. - SendBeginFrameReply(false, std::string()); - EXPECT_FALSE(task_runner_->HasPendingTask()); - EXPECT_TRUE(can_continue); - can_continue = false; - - // Doesn't send a BeginFrame if another task pauses and resumes virtual time. - deferrer_->DeferResume(defer_callback); - EXPECT_FALSE(task_runner_->HasPendingTask()); - EXPECT_TRUE(can_continue); - can_continue = false; - - // Sends another BeginFrame after next animation interval elapsed. - task_->IntervalElapsed(kAnimationFrameInterval, continue_callback); - EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED, - *continue_policy); - continue_policy = base::nullopt; - EXPECT_FALSE(task_runner_->HasPendingTask()); - - deferrer_->DeferResume(defer_callback); - EXPECT_TRUE(task_runner_->HasPendingTask()); - - ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF() * 2); - ExpectBeginFrame(); - task_runner_->RunPendingTasks(); - EXPECT_FALSE(can_continue); - - // Lets virtual time continue after BeginFrame was completed. - SendBeginFrameReply(false, std::string()); - EXPECT_FALSE(task_runner_->HasPendingTask()); - EXPECT_TRUE(can_continue); - can_continue = false; -} - -TEST_F(CompositorControllerTest, WaitUntilIdle) { - bool idle = false; - auto idle_callback = - base::BindRepeating([](bool* idle) { *idle = true; }, &idle); - - SendNeedsBeginFramesEvent(true); - EXPECT_FALSE(task_runner_->HasPendingTask()); - - // WaitUntilIdle executes callback immediately if no BeginFrame is active. - controller_->WaitUntilIdle(idle_callback); - EXPECT_TRUE(idle); - idle = false; - - // Send a BeginFrame. - task_->IntervalElapsed( - kAnimationFrameInterval, - base::BindRepeating( - [](VirtualTimeController::RepeatingTask::ContinuePolicy) {})); - EXPECT_FALSE(task_runner_->HasPendingTask()); - - bool can_continue = false; - auto defer_callback = base::BindRepeating( - [](bool* can_continue) { *can_continue = true; }, &can_continue); - - deferrer_->DeferResume(defer_callback); - EXPECT_TRUE(task_runner_->HasPendingTask()); - - ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF()); - ExpectBeginFrame(); - task_runner_->RunPendingTasks(); - EXPECT_FALSE(can_continue); - - // WaitUntilIdle only executes callback after BeginFrame was completed. - controller_->WaitUntilIdle(idle_callback); - EXPECT_FALSE(idle); - - SendBeginFrameReply(false, std::string()); - EXPECT_FALSE(task_runner_->HasPendingTask()); - EXPECT_TRUE(idle); - idle = false; - EXPECT_TRUE(can_continue); - can_continue = false; -} - -class CompositorControllerNoDisplayUpdateTest - : public CompositorControllerTest { - protected: - CompositorControllerNoDisplayUpdateTest() : CompositorControllerTest(false) {} -}; - -TEST_F(CompositorControllerNoDisplayUpdateTest, - SkipsDisplayUpdateOnlyForAnimationFrames) { - base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy> - continue_policy; - auto continue_callback = base::BindRepeating( - [](base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>* - continue_policy, - VirtualTimeController::RepeatingTask::ContinuePolicy policy) { - *continue_policy = policy; - }, - &continue_policy); - - SendNeedsBeginFramesEvent(true); - EXPECT_FALSE(task_runner_->HasPendingTask()); - - bool can_continue = false; - auto defer_callback = base::BindRepeating( - [](bool* can_continue) { *can_continue = true; }, &can_continue); - - // Initial animation-BeginFrame always updates display (see comment in - // compositor_controller.cc). - deferrer_->DeferResume(defer_callback); - EXPECT_TRUE(task_runner_->HasPendingTask()); - - ExpectVirtualTime(1000, 0); - ExpectBeginFrame(); - task_runner_->RunPendingTasks(); - EXPECT_FALSE(can_continue); - - // Lets virtual time continue after BeginFrame was completed. - SendBeginFrameReply(false, std::string()); - EXPECT_FALSE(task_runner_->HasPendingTask()); - EXPECT_TRUE(can_continue); - can_continue = false; - - // Sends an animation BeginFrame without display update after interval - // elapsed. - task_->IntervalElapsed(kAnimationFrameInterval, continue_callback); - EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED, - *continue_policy); - continue_policy = base::nullopt; - EXPECT_FALSE(task_runner_->HasPendingTask()); - - deferrer_->DeferResume(defer_callback); - EXPECT_TRUE(task_runner_->HasPendingTask()); - - ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF()); - ExpectBeginFrame(true); - task_runner_->RunPendingTasks(); - EXPECT_FALSE(can_continue); - - // Lets virtual time continue after BeginFrame was completed. - SendBeginFrameReply(false, std::string()); - EXPECT_FALSE(task_runner_->HasPendingTask()); - EXPECT_TRUE(can_continue); - can_continue = false; - - // Screenshots update display. - task_->IntervalElapsed(kAnimationFrameInterval, continue_callback); - EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED, - *continue_policy); - continue_policy = base::nullopt; - EXPECT_FALSE(task_runner_->HasPendingTask()); - - controller_->CaptureScreenshot( - headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::BindRepeating([](const std::string&) {})); - - EXPECT_TRUE(task_runner_->HasPendingTask()); - ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF() * 2); - ExpectBeginFrame( - false, headless_experimental::ScreenshotParams::Builder() - .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG) - .SetQuality(100) - .Build()); - task_runner_->RunPendingTasks(); -} - -} // namespace headless
diff --git a/headless/public/util/virtual_time_controller.cc b/headless/public/util/virtual_time_controller.cc deleted file mode 100644 index 2a871bf7..0000000 --- a/headless/public/util/virtual_time_controller.cc +++ /dev/null
@@ -1,229 +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. - -#include "headless/public/util/virtual_time_controller.h" - -#include "base/auto_reset.h" -#include "base/bind.h" -#include "base/logging.h" - -namespace headless { - -using base::TimeDelta; - -VirtualTimeController::VirtualTimeController( - HeadlessDevToolsClient* devtools_client, - int max_task_starvation_count) - : devtools_client_(devtools_client), - max_task_starvation_count_(max_task_starvation_count), - weak_ptr_factory_(this) { - devtools_client_->GetEmulation()->GetExperimental()->AddObserver(this); -} - -VirtualTimeController::~VirtualTimeController() { - devtools_client_->GetEmulation()->GetExperimental()->RemoveObserver(this); -} - -void VirtualTimeController::StartVirtualTime() { - if (virtual_time_started_) - return; - - TimeDelta next_budget; - bool wait_for_navigation = false; - for (auto& entry_pair : tasks_) { - entry_pair.second.ready_to_advance = true; - if (entry_pair.first->start_policy() == - RepeatingTask::StartPolicy::WAIT_FOR_NAVIGATION) { - wait_for_navigation = true; - } - if (next_budget.is_zero()) { - next_budget = - entry_pair.second.next_execution_time - total_elapsed_time_offset_; - } else { - next_budget = - std::min(next_budget, entry_pair.second.next_execution_time - - total_elapsed_time_offset_); - } - } - - // If there's no budget, then don't do anything! - if (next_budget.is_zero()) - return; - - virtual_time_started_ = true; - should_send_start_notification_ = true; - - if (resume_deferrer_) { - resume_deferrer_->DeferResume(base::BindOnce( - &VirtualTimeController::SetVirtualTimePolicy, - weak_ptr_factory_.GetWeakPtr(), next_budget, wait_for_navigation)); - } else { - SetVirtualTimePolicy(next_budget, wait_for_navigation); - } -} - -void VirtualTimeController::NotifyTasksAndAdvance() { - // The task may call its continue callback synchronously. Prevent re-entrance. - if (in_notify_tasks_and_advance_) - return; - - base::AutoReset<bool> reset(&in_notify_tasks_and_advance_, true); - - for (auto iter = tasks_.begin(); iter != tasks_.end();) { - auto entry_pair = iter++; - if (entry_pair->second.next_execution_time <= total_elapsed_time_offset_) { - entry_pair->second.ready_to_advance = false; - entry_pair->second.next_execution_time = - total_elapsed_time_offset_ + entry_pair->second.interval; - - // This may delete itself. - entry_pair->first->IntervalElapsed( - total_elapsed_time_offset_, - base::BindOnce(&VirtualTimeController::TaskReadyToAdvance, - weak_ptr_factory_.GetWeakPtr(), - base::Unretained(&entry_pair->second))); - } - } - - // Give at most as much virtual time as available until the next callback. - bool advance_virtual_time = false; - bool stop_virtual_time = false; - bool ready_to_advance = true; - TimeDelta next_budget; - for (const auto& entry_pair : tasks_) { - ready_to_advance &= entry_pair.second.ready_to_advance; - if (next_budget.is_zero()) { - next_budget = - entry_pair.second.next_execution_time - total_elapsed_time_offset_; - } else { - next_budget = - std::min(next_budget, entry_pair.second.next_execution_time - - total_elapsed_time_offset_); - } - if (entry_pair.second.continue_policy == - RepeatingTask::ContinuePolicy::CONTINUE_MORE_TIME_NEEDED) { - advance_virtual_time = true; - } else if (entry_pair.second.continue_policy == - RepeatingTask::ContinuePolicy::STOP) { - stop_virtual_time = true; - } - } - - if (!ready_to_advance) - return; - - if (!advance_virtual_time || stop_virtual_time) { - for (auto& entry_pair : tasks_) { - entry_pair.second.ready_to_advance = false; - } - - for (auto iter = observers_.begin(); iter != observers_.end();) { - Observer* observer = *iter++; - // |observer| may delete itself. - observer->VirtualTimeStopped(total_elapsed_time_offset_); - } - virtual_time_started_ = false; - return; - } - - DCHECK(!next_budget.is_zero()); - if (resume_deferrer_) { - resume_deferrer_->DeferResume( - base::BindOnce(&VirtualTimeController::SetVirtualTimePolicy, - weak_ptr_factory_.GetWeakPtr(), next_budget, - false /* wait_for_navigation */)); - } else { - SetVirtualTimePolicy(next_budget, false /* wait_for_navigation */); - } -} - -void VirtualTimeController::TaskReadyToAdvance( - TaskEntry* entry, - RepeatingTask::ContinuePolicy continue_policy) { - entry->ready_to_advance = true; - entry->continue_policy = continue_policy; - NotifyTasksAndAdvance(); -} - -void VirtualTimeController::SetVirtualTimePolicy(base::TimeDelta next_budget, - bool wait_for_navigation) { - last_budget_ = next_budget; - devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( - emulation::SetVirtualTimePolicyParams::Builder() - .SetPolicy( - emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING) - .SetBudget(next_budget.InMillisecondsF()) - .SetMaxVirtualTimeTaskStarvationCount(max_task_starvation_count_) - .SetWaitForNavigation(wait_for_navigation) - .Build(), - base::BindOnce(&VirtualTimeController::SetVirtualTimePolicyDone, - weak_ptr_factory_.GetWeakPtr())); -} - -void VirtualTimeController::SetVirtualTimePolicyDone( - std::unique_ptr<emulation::SetVirtualTimePolicyResult> result) { - if (result) { - virtual_time_base_ = - base::TimeTicks() + - base::TimeDelta::FromMillisecondsD(result->GetVirtualTimeTicksBase()); - } else { - LOG(WARNING) << "SetVirtualTimePolicy did not succeed"; - } - - if (should_send_start_notification_) { - should_send_start_notification_ = false; - for (auto iter = observers_.begin(); iter != observers_.end();) { - Observer* observer = *iter++; - // |observer| may delete itself. - observer->VirtualTimeStarted(total_elapsed_time_offset_); - } - } -} - -void VirtualTimeController::OnVirtualTimeBudgetExpired( - const emulation::VirtualTimeBudgetExpiredParams& params) { - total_elapsed_time_offset_ += last_budget_; - virtual_time_paused_ = true; - NotifyTasksAndAdvance(); -} - -void VirtualTimeController::ScheduleRepeatingTask(RepeatingTask* task, - base::TimeDelta interval) { - if (!virtual_time_paused_) { - // We cannot accurately modify any previously granted virtual time budget. - LOG(WARNING) << "VirtualTimeController tasks should be added while " - "virtual time is paused."; - } - - TaskEntry entry; - entry.interval = interval; - entry.next_execution_time = total_elapsed_time_offset_ + entry.interval; - tasks_.insert(std::make_pair(task, entry)); -} - -void VirtualTimeController::CancelRepeatingTask(RepeatingTask* task) { - tasks_.erase(task); -} - -void VirtualTimeController::AddObserver(Observer* observer) { - observers_.insert(observer); -} - -void VirtualTimeController::RemoveObserver(Observer* observer) { - observers_.erase(observer); -} - -base::TimeTicks VirtualTimeController::GetVirtualTimeBase() const { - return virtual_time_base_; -} - -base::TimeDelta VirtualTimeController::GetCurrentVirtualTimeOffset() const { - return total_elapsed_time_offset_; -} - -void VirtualTimeController::SetResumeDeferrer(ResumeDeferrer* resume_deferrer) { - resume_deferrer_ = resume_deferrer; -} - -} // namespace headless
diff --git a/headless/public/util/virtual_time_controller.h b/headless/public/util/virtual_time_controller.h deleted file mode 100644 index 8df73ef6..0000000 --- a/headless/public/util/virtual_time_controller.h +++ /dev/null
@@ -1,182 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef HEADLESS_PUBLIC_UTIL_VIRTUAL_TIME_CONTROLLER_H_ -#define HEADLESS_PUBLIC_UTIL_VIRTUAL_TIME_CONTROLLER_H_ - -#include "base/callback.h" -#include "base/time/time.h" -#include "headless/public/devtools/domains/emulation.h" -#include "headless/public/headless_devtools_client.h" -#include "headless/public/headless_export.h" - -namespace headless { - -// Controls how virtual time progresses. RepeatingTasks can register their -// interest to be periodically notified about changes to the current virtual -// time. -class HEADLESS_EXPORT VirtualTimeController - : public emulation::ExperimentalObserver { - public: - VirtualTimeController(HeadlessDevToolsClient* devtools_client, - int max_task_starvation_count = 0); - ~VirtualTimeController() override; - - // Signals that virtual time should start advancing. If virtual time is - // already running, this does nothing. When virtual time is ready to start - // the observers will be notified. - virtual void StartVirtualTime(); - - class RepeatingTask { - public: - // This policy controls whether or not StartVirtualTime() should wait for a - // navigation first. - enum StartPolicy { - WAIT_FOR_NAVIGATION, - START_IMMEDIATELY, - }; - - explicit RepeatingTask(StartPolicy start_policy, int priority) - : start_policy_(start_policy), priority_(priority) {} - - virtual ~RepeatingTask() {} - - enum class ContinuePolicy { - CONTINUE_MORE_TIME_NEEDED, - NOT_REQUIRED, - STOP, // Note STOP trumps CONTINUE_MORE_TIME_NEEDED. - }; - - // Called when the tasks's requested virtual time interval has elapsed. - // |virtual_time_offset| is the virtual time duration that has advanced - // since the page started loading (millisecond granularity). When the task - // has completed it's perioodic work it should call |continue_callback| - // with CONTINUE_MORE_TIME_NEEDED if it wants virtual time to continue - // advancing, or NOT_REQUIRED otherwise. Virtual time will continue to - // advance until all RepeatingTasks want it to stop. - virtual void IntervalElapsed( - base::TimeDelta virtual_time_offset, - base::OnceCallback<void(ContinuePolicy policy)> continue_callback) = 0; - - StartPolicy start_policy() const { return start_policy_; } - - int priority() const { return priority_; } - - private: - const StartPolicy start_policy_; - - // If more than one RepeatingTask is scheduled to run at any instant they - // are run in order of ascending |priority_|. - const int priority_; - }; - - // An API used by the CompositorController to defer the start and resumption - // of virtual time until it's ready. - class ResumeDeferrer { - public: - virtual ~ResumeDeferrer() {} - - // Called before virtual time progression resumes after it was stopped or - // paused to execute repeating tasks. - virtual void DeferResume(base::OnceClosure ready_callback) = 0; - }; - - class Observer { - public: - virtual ~Observer() {} - - // Called when StartVirtualTime was called. May be delayed by a - // StartDeferrer. - virtual void VirtualTimeStarted(base::TimeDelta virtual_time_offset) = 0; - - // Called when all RepeatingTasks have either voted for virtual time to stop - // advancing, or all have been removed. - virtual void VirtualTimeStopped(base::TimeDelta virtual_time_offset) = 0; - }; - - // Interleaves execution of the provided |task| with progression of virtual - // time. The task will be notified whenever another |interval| of virtual time - // have elapsed, as well as when the last granted budget has been used up. - // - // To ensure that the task is notified of elapsed intervals accurately, it - // should be added while virtual time is paused. - virtual void ScheduleRepeatingTask(RepeatingTask* task, - base::TimeDelta interval); - virtual void CancelRepeatingTask(RepeatingTask* task); - - // Adds an observer which is notified when virtual time starts and stops. - virtual void AddObserver(Observer* observer); - virtual void RemoveObserver(Observer* observer); - - // Returns the time that virtual time offsets are relative to. - virtual base::TimeTicks GetVirtualTimeBase() const; - - // Returns the current virtual time offset. Only accurate while virtual time - // is paused. - virtual base::TimeDelta GetCurrentVirtualTimeOffset() const; - - // Returns the current virtual time stamp. Only accurate while virtual time - // is paused. - base::TimeTicks GetCurrentVirtualTime() const { - return GetVirtualTimeBase() + GetCurrentVirtualTimeOffset(); - } - - virtual void SetResumeDeferrer(ResumeDeferrer* resume_deferrer); - - private: - struct TaskEntry { - base::TimeDelta interval; - base::TimeDelta next_execution_time; - bool ready_to_advance = true; - RepeatingTask::ContinuePolicy continue_policy = - RepeatingTask::ContinuePolicy::CONTINUE_MORE_TIME_NEEDED; - }; - - void ObserverReadyToStart(); - - // emulation::Observer implementation: - void OnVirtualTimeBudgetExpired( - const emulation::VirtualTimeBudgetExpiredParams& params) override; - - void NotifyTasksAndAdvance(); - void NotifyTaskIntervalElapsed(TaskEntry* entry); - void NotifyTaskVirtualTimeStarted(TaskEntry* entry); - void TaskReadyToAdvance(TaskEntry* entry, - RepeatingTask::ContinuePolicy continue_policy); - - void SetVirtualTimePolicy(base::TimeDelta next_budget, - bool wait_for_navigation); - void SetVirtualTimePolicyDone( - std::unique_ptr<emulation::SetVirtualTimePolicyResult>); - - HeadlessDevToolsClient* const devtools_client_; // NOT OWNED - ResumeDeferrer* resume_deferrer_ = nullptr; // NOT OWNED - const int max_task_starvation_count_; - - base::TimeDelta total_elapsed_time_offset_; - base::TimeDelta last_budget_; - // Initial virtual time that virtual time offsets are relative to. - base::TimeTicks virtual_time_base_; - - struct RepeatingTaskOrdering { - bool operator()(RepeatingTask* a, RepeatingTask* b) const { - if (a->priority() == b->priority()) - return a < b; - return a->priority() < b->priority(); - }; - }; - - std::map<RepeatingTask*, TaskEntry, RepeatingTaskOrdering> tasks_; - std::set<Observer*> observers_; - bool in_notify_tasks_and_advance_ = false; - bool virtual_time_started_ = false; - bool virtual_time_paused_ = true; - bool should_send_start_notification_ = false; - - base::WeakPtrFactory<VirtualTimeController> weak_ptr_factory_; -}; - -} // namespace headless - -#endif // HEADLESS_PUBLIC_UTIL_VIRTUAL_TIME_CONTROLLER_H_
diff --git a/headless/public/util/virtual_time_controller_test.cc b/headless/public/util/virtual_time_controller_test.cc deleted file mode 100644 index 2f3b286..0000000 --- a/headless/public/util/virtual_time_controller_test.cc +++ /dev/null
@@ -1,858 +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. - -#include "headless/public/util/virtual_time_controller.h" - -#include <memory> -#include <tuple> - -#include "base/bind.h" -#include "base/memory/ref_counted.h" -#include "base/strings/stringprintf.h" -#include "base/test/test_simple_task_runner.h" -#include "headless/public/internal/headless_devtools_client_impl.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace headless { - -using testing::ElementsAre; -using testing::Mock; -using testing::Return; -using testing::_; - -namespace { - -class MockChannel : public HeadlessDevToolsChannel { - public: - MockChannel() {} - ~MockChannel() override {} - MOCK_METHOD1(SetClient, void(HeadlessDevToolsChannel::Client*)); - MOCK_METHOD1(SendProtocolMessage, void(const std::string&)); -}; - -} // namespace - -class VirtualTimeControllerTest : public ::testing::Test { - protected: - VirtualTimeControllerTest() { - task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>(); - auto channel = std::make_unique<MockChannel>(); - mock_channel_ = channel.get(); - client_.AttachToChannel(std::move(channel)); - client_.SetTaskRunnerForTests(task_runner_); - controller_ = std::make_unique<VirtualTimeController>(&client_, 0); - } - - ~VirtualTimeControllerTest() override = default; - - // TODO(alexclarke): This is a common pattern add a helper. - class AdditionalVirtualTimeBudget - : public VirtualTimeController::RepeatingTask, - public VirtualTimeController::Observer { - public: - AdditionalVirtualTimeBudget(VirtualTimeController* virtual_time_controller, - VirtualTimeControllerTest* test, - base::TimeDelta budget) - : RepeatingTask(StartPolicy::START_IMMEDIATELY, 0), - virtual_time_controller_(virtual_time_controller), - test_(test) { - virtual_time_controller_->ScheduleRepeatingTask(this, budget); - virtual_time_controller_->AddObserver(this); - virtual_time_controller_->StartVirtualTime(); - } - - ~AdditionalVirtualTimeBudget() override { - virtual_time_controller_->RemoveObserver(this); - virtual_time_controller_->CancelRepeatingTask(this); - } - - // headless::VirtualTimeController::RepeatingTask implementation: - void IntervalElapsed( - base::TimeDelta virtual_time, - base::OnceCallback<void(ContinuePolicy)> continue_callback) override { - std::move(continue_callback).Run(ContinuePolicy::NOT_REQUIRED); - } - - // headless::VirtualTimeController::Observer: - void VirtualTimeStarted(base::TimeDelta virtual_time_offset) override { - EXPECT_FALSE(test_->set_up_complete_); - test_->set_up_complete_ = true; - } - - void VirtualTimeStopped(base::TimeDelta virtual_time_offset) override { - EXPECT_FALSE(test_->budget_expired_); - test_->budget_expired_ = true; - delete this; - } - - private: - headless::VirtualTimeController* const virtual_time_controller_; - VirtualTimeControllerTest* test_; - }; - - void GrantVirtualTimeBudget(int budget_ms) { - ASSERT_FALSE(set_up_complete_); - ASSERT_FALSE(budget_expired_); - - // AdditionalVirtualTimeBudget will self delete - new AdditionalVirtualTimeBudget( - controller_.get(), this, base::TimeDelta::FromMilliseconds(budget_ms)); - - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - } - - void SendVirtualTimeBudgetExpiredEvent() { - client_.ReceiveProtocolMessage( - "{\"method\":\"Emulation.virtualTimeBudgetExpired\",\"params\":{}}"); - // Events are dispatched asynchronously. - task_runner_->RunPendingTasks(); - } - - scoped_refptr<base::TestSimpleTaskRunner> task_runner_; - HeadlessDevToolsClientImpl client_; - MockChannel* mock_channel_ = nullptr; - std::unique_ptr<VirtualTimeController> controller_; - - bool set_up_complete_ = false; - bool budget_expired_ = false; -}; - -TEST_F(VirtualTimeControllerTest, DoesNotAdvanceTimeWithoutTasks) { - controller_ = std::make_unique<VirtualTimeController>(&client_, 1000); - - EXPECT_CALL(*mock_channel_, SendProtocolMessage(_)).Times(0); - - controller_->StartVirtualTime(); -} - -TEST_F(VirtualTimeControllerTest, MaxVirtualTimeTaskStarvationCount) { - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":5000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - GrantVirtualTimeBudget(5000); - - client_.ReceiveProtocolMessage( - "{\"id\":0,\"result\":{\"virtualTimeBase\":1." - "0,\"virtualTimeTicksBase\":1.0}}"); - task_runner_->RunPendingTasks(); - - EXPECT_TRUE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - SendVirtualTimeBudgetExpiredEvent(); - - EXPECT_TRUE(budget_expired_); -} - -namespace { -class MockTask : public VirtualTimeController::RepeatingTask { - public: - MockTask() : RepeatingTask(StartPolicy::START_IMMEDIATELY, 0) {} - - MockTask(StartPolicy start_policy, int priority) - : RepeatingTask(start_policy, priority) {} - - ~MockTask() override { EXPECT_TRUE(!expected_virtual_time_offset_); } - - // GMock doesn't support move only types - void IntervalElapsed( - base::TimeDelta virtual_time_offset, - base::OnceCallback<void(ContinuePolicy)> continue_callback) override { - EXPECT_EQ(*expected_virtual_time_offset_, virtual_time_offset); - expected_virtual_time_offset_ = base::nullopt; - std::move(continue_callback).Run(policy_); - interval_elapsed_ = true; - } - - void ExpectCallOnceWithOffsetAndReturn(base::TimeDelta virtual_time_offset, - ContinuePolicy policy) { - expected_virtual_time_offset_ = virtual_time_offset; - policy_ = policy; - } - - private: - base::Optional<base::TimeDelta> expected_virtual_time_offset_; - ContinuePolicy policy_ = ContinuePolicy::NOT_REQUIRED; - bool interval_elapsed_ = false; -}; - -class MockDeferrer : public VirtualTimeController::ResumeDeferrer { - public: - // GMock doesn't support move only types - void DeferResume(base::OnceCallback<void()> continue_callback) override { - continue_callback_ = std::move(continue_callback); - } - - base::OnceCallback<void()> continue_callback_; -}; - -class MockObserver : public VirtualTimeController::Observer { - public: - MOCK_METHOD1(VirtualTimeStarted, void(base::TimeDelta virtual_time_offset)); - - MOCK_METHOD1(VirtualTimeStopped, void(base::TimeDelta virtual_time_offset)); -}; - -ACTION_TEMPLATE(RunClosure, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_0_VALUE_PARAMS()) { - std::get<k>(args).Run(); -} - -ACTION_P(RunClosure, closure) { - closure.Run(); -}; -} // namespace - -TEST_F(VirtualTimeControllerTest, InterleavesTasksWithVirtualTime) { - MockTask task; - MockObserver observer; - controller_->AddObserver(&observer); - controller_->ScheduleRepeatingTask(&task, - base::TimeDelta::FromMilliseconds(1000)); - - EXPECT_CALL(observer, - VirtualTimeStarted(base::TimeDelta::FromMilliseconds(0))); - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - GrantVirtualTimeBudget(3000); - - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - client_.ReceiveProtocolMessage( - "{\"id\":0,\"result\":{\"virtualTimeBase\":1." - "0,\"virtualTimeTicksBase\":1.0}}"); - task_runner_->RunPendingTasks(); - - EXPECT_TRUE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - // We check that set_up_complete_callback is only run once, so reset it here. - set_up_complete_ = false; - - for (int i = 1; i < 3; i++) { - task.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(1000 * i), - MockTask::ContinuePolicy::NOT_REQUIRED); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage(base::StringPrintf( - "{\"id\":%d,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}", - i * 2))); - - SendVirtualTimeBudgetExpiredEvent(); - - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":%d,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}", - i * 2)); - - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - } - - task.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(3000), - MockTask::ContinuePolicy::NOT_REQUIRED); - EXPECT_CALL(observer, - VirtualTimeStopped(base::TimeDelta::FromMilliseconds(3000))); - SendVirtualTimeBudgetExpiredEvent(); - - EXPECT_FALSE(set_up_complete_); - EXPECT_TRUE(budget_expired_); -} - -TEST_F(VirtualTimeControllerTest, CanceledTask) { - MockTask task; - controller_->ScheduleRepeatingTask(&task, - base::TimeDelta::FromMilliseconds(1000)); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - GrantVirtualTimeBudget(5000); - - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - client_.ReceiveProtocolMessage( - "{\"id\":0,\"result\":{\"virtualTimeBase\":1." - "0,\"virtualTimeTicksBase\":1.0}}"); - task_runner_->RunPendingTasks(); - - EXPECT_TRUE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - // We check that set_up_complete_callback is only run once, so reset it here. - set_up_complete_ = false; - - task.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(1000), - MockTask::ContinuePolicy::NOT_REQUIRED); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":2,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - SendVirtualTimeBudgetExpiredEvent(); - - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":2,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}")); - - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - controller_->CancelRepeatingTask(&task); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":4,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":3000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - SendVirtualTimeBudgetExpiredEvent(); - - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":4,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}")); - - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - SendVirtualTimeBudgetExpiredEvent(); - - EXPECT_FALSE(set_up_complete_); - EXPECT_TRUE(budget_expired_); -} - -TEST_F(VirtualTimeControllerTest, MultipleTasks) { - MockTask task1; - MockTask task2; - controller_->ScheduleRepeatingTask(&task1, - base::TimeDelta::FromMilliseconds(1000)); - controller_->ScheduleRepeatingTask(&task2, - base::TimeDelta::FromMilliseconds(1000)); - - // We should only get one call to Emulation.setVirtualTimePolicy despite - // having two tasks. - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - GrantVirtualTimeBudget(2000); - EXPECT_FALSE(set_up_complete_); - EXPECT_FALSE(budget_expired_); - - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":0,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}")); - - task_runner_->RunPendingTasks(); - EXPECT_TRUE(set_up_complete_); - EXPECT_FALSE(budget_expired_); -} - -TEST_F(VirtualTimeControllerTest, StartPolicy) { - MockTask task1(MockTask::StartPolicy::START_IMMEDIATELY, 0); - MockTask task2(MockTask::StartPolicy::START_IMMEDIATELY, 0); - MockTask task3(MockTask::StartPolicy::WAIT_FOR_NAVIGATION, 0); - controller_->ScheduleRepeatingTask(&task1, - base::TimeDelta::FromMilliseconds(1000)); - controller_->ScheduleRepeatingTask(&task2, - base::TimeDelta::FromMilliseconds(1000)); - controller_->ScheduleRepeatingTask(&task3, - base::TimeDelta::FromMilliseconds(1000)); - - // Despite only one task asking for it we should get waitForNavigation:true - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":true}}")); - - GrantVirtualTimeBudget(2000); -} - -TEST_F(VirtualTimeControllerTest, DeferStartAndResume) { - MockDeferrer deferrer; - controller_->SetResumeDeferrer(&deferrer); - - MockTask task1(MockTask::StartPolicy::START_IMMEDIATELY, 0); - controller_->ScheduleRepeatingTask(&task1, - base::TimeDelta::FromMilliseconds(1000)); - EXPECT_FALSE(deferrer.continue_callback_); - - // Shouldn't see the devtools command until the deferrer's callback has run. - EXPECT_CALL(*mock_channel_, SendProtocolMessage(_)).Times(0); - GrantVirtualTimeBudget(2000); - EXPECT_TRUE(deferrer.continue_callback_); - - Mock::VerifyAndClearExpectations(mock_channel_); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - std::move(deferrer.continue_callback_).Run(); - - client_.ReceiveProtocolMessage( - "{\"id\":0,\"result\":{\"virtualTimeBase\":1." - "0,\"virtualTimeTicksBase\":1.0}}"); - EXPECT_FALSE(deferrer.continue_callback_); - - task1.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(1000), - MockTask::ContinuePolicy::NOT_REQUIRED); - - // Even after executing task1, virtual time shouldn't resume until the - // deferrer's callback has run. - EXPECT_CALL(*mock_channel_, SendProtocolMessage(_)).Times(0); - - SendVirtualTimeBudgetExpiredEvent(); - EXPECT_TRUE(deferrer.continue_callback_); - - Mock::VerifyAndClearExpectations(mock_channel_); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":2,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - std::move(deferrer.continue_callback_).Run(); -} - -class VirtualTimeTask : public VirtualTimeController::RepeatingTask, - public VirtualTimeController::Observer { - public: - using Task = base::RepeatingCallback<void(base::TimeDelta virtual_time)>; - - VirtualTimeTask(VirtualTimeController* controller, - Task virtual_time_started_task, - Task interval_elapsed_task, - Task virtual_time_stopped_task, - int priority = 0) - : RepeatingTask(StartPolicy::START_IMMEDIATELY, priority), - controller_(controller), - virtual_time_started_task_(virtual_time_started_task), - interval_elapsed_task_(interval_elapsed_task), - virtual_time_stopped_task_(virtual_time_stopped_task) { - controller_->AddObserver(this); - } - - ~VirtualTimeTask() override { controller_->RemoveObserver(this); } - - // VirtualTimeController::RepeatingTask: - void IntervalElapsed( - base::TimeDelta virtual_time, - base::OnceCallback<void(ContinuePolicy)> continue_callback) override { - std::move(continue_callback).Run(ContinuePolicy::NOT_REQUIRED); - interval_elapsed_task_.Run(virtual_time); - } - - // VirtualTimeController::Observer: - void VirtualTimeStarted(base::TimeDelta virtual_time) override { - virtual_time_started_task_.Run(virtual_time); - } - - void VirtualTimeStopped(base::TimeDelta virtual_time) override { - virtual_time_stopped_task_.Run(virtual_time); - }; - - VirtualTimeController* controller_; // NOT OWNED - Task virtual_time_started_task_; - Task interval_elapsed_task_; - Task virtual_time_stopped_task_; -}; - -TEST_F(VirtualTimeControllerTest, ReentrantTask) { -#if defined(__clang__) - std::vector<std::string> log; - VirtualTimeTask task_b( - controller_.get(), - base::BindRepeating([](base::TimeDelta virtual_time) {}), - base::BindRepeating( - [](std::vector<std::string>* log, VirtualTimeController* controller, - VirtualTimeTask* task_b, base::TimeDelta virtual_time) { - log->push_back(base::StringPrintf( - "B: interval elapsed @ %d", - static_cast<int>(virtual_time.InMilliseconds()))); - controller->CancelRepeatingTask(task_b); - }, - &log, controller_.get(), &task_b), - base::BindRepeating( - [](std::vector<std::string>* log, base::TimeDelta virtual_time) { - log->push_back(base::StringPrintf( - "B: virtual time stopped @ %d", - static_cast<int>(virtual_time.InMilliseconds()))); - }, - &log)); - - VirtualTimeTask task_a( - controller_.get(), - base::BindRepeating( - [](std::vector<std::string>* log, base::TimeDelta virtual_time) { - log->push_back(base::StringPrintf( - "Virtual time started @ %d", - static_cast<int>(virtual_time.InMilliseconds()))); - }, - &log), - base::BindRepeating( - [](std::vector<std::string>* log, VirtualTimeController* controller, - VirtualTimeTask* task_a, VirtualTimeTask* task_b, - base::TimeDelta virtual_time) { - log->push_back(base::StringPrintf( - "A: interval elapsed @ %d", - static_cast<int>(virtual_time.InMilliseconds()))); - controller->CancelRepeatingTask(task_a); - controller->ScheduleRepeatingTask( - task_b, base::TimeDelta::FromMilliseconds(1500)); - }, - &log, controller_.get(), &task_a, &task_b), - base::BindRepeating( - [](std::vector<std::string>* log, base::TimeDelta virtual_time) { - log->push_back(base::StringPrintf( - "A: virtual time stopped @ %d", - static_cast<int>(virtual_time.InMilliseconds()))); - }, - &log)); - - controller_->ScheduleRepeatingTask(&task_a, - base::TimeDelta::FromMilliseconds(1000)); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - GrantVirtualTimeBudget(6000); - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":0,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}")); - - Mock::VerifyAndClearExpectations(mock_channel_); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":2,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1500.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - SendVirtualTimeBudgetExpiredEvent(); - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":2,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}")); - Mock::VerifyAndClearExpectations(mock_channel_); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":4,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":3500.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - SendVirtualTimeBudgetExpiredEvent(); - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":4,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}")); - - EXPECT_THAT( - log, ElementsAre("Virtual time started @ 0", "A: interval elapsed @ 1000", - "B: interval elapsed @ 2500")); -#endif -} - -TEST_F(VirtualTimeControllerTest, Priority) { - std::vector<std::string> log; - VirtualTimeTask task_a( - controller_.get(), - base::BindRepeating([](base::TimeDelta virtual_time) {}), - base::BindRepeating( - [](std::vector<std::string>* log, base::TimeDelta virtual_time) { - log->push_back(base::StringPrintf( - "A: interval elapsed @ %d", - static_cast<int>(virtual_time.InMilliseconds()))); - }, - &log), - base::BindRepeating([](base::TimeDelta virtual_time) {}), 30); - - VirtualTimeTask task_b( - controller_.get(), - base::BindRepeating([](base::TimeDelta virtual_time) {}), - base::BindRepeating( - [](std::vector<std::string>* log, base::TimeDelta virtual_time) { - log->push_back(base::StringPrintf( - "B: interval elapsed @ %d", - static_cast<int>(virtual_time.InMilliseconds()))); - }, - &log), - base::BindRepeating([](base::TimeDelta virtual_time) {}), 20); - - VirtualTimeTask task_c( - controller_.get(), - base::BindRepeating([](base::TimeDelta virtual_time) {}), - base::BindRepeating( - [](std::vector<std::string>* log, base::TimeDelta virtual_time) { - log->push_back(base::StringPrintf( - "C: interval elapsed @ %d", - static_cast<int>(virtual_time.InMilliseconds()))); - }, - &log), - base::BindRepeating([](base::TimeDelta virtual_time) {}), 10); - - controller_->ScheduleRepeatingTask(&task_a, - base::TimeDelta::FromMilliseconds(1000)); - - controller_->ScheduleRepeatingTask(&task_b, - base::TimeDelta::FromMilliseconds(1000)); - - controller_->ScheduleRepeatingTask(&task_c, - base::TimeDelta::FromMilliseconds(1000)); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - GrantVirtualTimeBudget(2000); - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":0,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}")); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":2,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - SendVirtualTimeBudgetExpiredEvent(); - - EXPECT_THAT(log, ElementsAre("C: interval elapsed @ 1000", - "B: interval elapsed @ 1000", - "A: interval elapsed @ 1000")); -} - -TEST_F(VirtualTimeControllerTest, ContinuePolicyContinueMoreTimeNeeded) { - MockTask task; - MockObserver observer; - controller_->AddObserver(&observer); - controller_->ScheduleRepeatingTask(&task, - base::TimeDelta::FromMilliseconds(1000)); - - EXPECT_CALL(observer, - VirtualTimeStarted(base::TimeDelta::FromMilliseconds(0))); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - controller_->StartVirtualTime(); - - client_.ReceiveProtocolMessage( - "{\"id\":0,\"result\":{\"virtualTimeBase\":1." - "0,\"virtualTimeTicksBase\":1.0}}"); - - for (int i = 1; i < 4; i++) { - task.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(1000 * i), - MockTask::ContinuePolicy::CONTINUE_MORE_TIME_NEEDED); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage(base::StringPrintf( - "{\"id\":%d,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}", - i * 2))); - - SendVirtualTimeBudgetExpiredEvent(); - - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":%d,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}", - i * 2)); - } - - task.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(4000), - MockTask::ContinuePolicy::NOT_REQUIRED); - - EXPECT_CALL(observer, - VirtualTimeStopped(base::TimeDelta::FromMilliseconds(4000))); - - SendVirtualTimeBudgetExpiredEvent(); -} - -TEST_F(VirtualTimeControllerTest, ContinuePolicyStopAndRestart) { - MockTask task1; - MockTask task2; - MockTask task3; - MockObserver observer; - controller_->AddObserver(&observer); - controller_->ScheduleRepeatingTask(&task1, - base::TimeDelta::FromMilliseconds(1000)); - controller_->ScheduleRepeatingTask(&task2, - base::TimeDelta::FromMilliseconds(1000)); - controller_->ScheduleRepeatingTask(&task3, - base::TimeDelta::FromMilliseconds(4000)); - - EXPECT_CALL(observer, - VirtualTimeStarted(base::TimeDelta::FromMilliseconds(0))); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":0,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - controller_->StartVirtualTime(); - - client_.ReceiveProtocolMessage( - "{\"id\":0,\"result\":{\"virtualTimeBase\":1." - "0,\"virtualTimeTicksBase\":1.0}}"); - - for (int i = 1; i < 4; i++) { - task1.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(1000 * i), - MockTask::ContinuePolicy::CONTINUE_MORE_TIME_NEEDED); - task2.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(1000 * i), - MockTask::ContinuePolicy::CONTINUE_MORE_TIME_NEEDED); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage(base::StringPrintf( - "{\"id\":%d,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}", - i * 2))); - - SendVirtualTimeBudgetExpiredEvent(); - - client_.ReceiveProtocolMessage( - base::StringPrintf("{\"id\":%d,\"result\":{\"virtualTimeBase\":1.0," - "\"virtualTimeTicksBase\":1.0}}", - i * 2)); - } - - task1.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(4000), - MockTask::ContinuePolicy::CONTINUE_MORE_TIME_NEEDED); - // STOP should take precedence over CONTINUE_MORE_TIME_NEEDED. - task2.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(4000), MockTask::ContinuePolicy::STOP); - task3.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(4000), - MockTask::ContinuePolicy::CONTINUE_MORE_TIME_NEEDED); - - EXPECT_CALL(observer, - VirtualTimeStopped(base::TimeDelta::FromMilliseconds(4000))); - - SendVirtualTimeBudgetExpiredEvent(); - - // If we start again, no task should block initially. - EXPECT_CALL(observer, - VirtualTimeStarted(base::TimeDelta::FromMilliseconds(4000))); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":8,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - controller_->StartVirtualTime(); - - client_.ReceiveProtocolMessage( - "{\"id\":8,\"result\":{\"virtualTimeBase\":1." - "0,\"virtualTimeTicksBase\":1.0}}"); - - task1.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(5000), - MockTask::ContinuePolicy::CONTINUE_MORE_TIME_NEEDED); - task2.ExpectCallOnceWithOffsetAndReturn( - base::TimeDelta::FromMilliseconds(5000), - MockTask::ContinuePolicy::CONTINUE_MORE_TIME_NEEDED); - - EXPECT_CALL(*mock_channel_, - SendProtocolMessage( - "{\"id\":10,\"method\":\"Emulation.setVirtualTimePolicy\"," - "\"params\":{\"budget\":1000.0," - "\"maxVirtualTimeTaskStarvationCount\":0,\"policy\":" - "\"pauseIfNetworkFetchesPending\"," - "\"waitForNavigation\":false}}")); - - SendVirtualTimeBudgetExpiredEvent(); -} -} // namespace headless
diff --git a/headless/test/DEPS b/headless/test/DEPS index cb553ed..518ed48 100644 --- a/headless/test/DEPS +++ b/headless/test/DEPS
@@ -1,10 +1,4 @@ specific_include_rules = { - "headless_render_test.cc": [ - "+cc/base/switches.h", - "+components/viz/common/features.h", - "+components/viz/common/switches.h", - "+third_party/skia/include", - ], "headless_protocol_browsertest.cc": [ "+cc/base/switches.h", "+components/viz/common/features.h",
diff --git a/headless/test/data/protocol/emulation/compositor-basic-raf.js b/headless/test/data/protocol/emulation/compositor-basic-raf.js index bc7c8e53..7433842 100644 --- a/headless/test/data/protocol/emulation/compositor-basic-raf.js +++ b/headless/test/data/protocol/emulation/compositor-basic-raf.js
@@ -3,113 +3,103 @@ // found in the LICENSE file. (async function(testRunner) { - var {page, session, dp} = await testRunner.startBlank( + var {page, session, dp} = await testRunner.startWithFrameControl( 'Tests compositor basic rAF operation.'); - await dp.Target.enable(); - // Open the test page in a new tab with BeginFrameControl enabled. - await testTargetPage(await session.createTargetInNewContext( - 800, 600, 'about:blank', true)); + await dp.Runtime.enable(); + await dp.HeadlessExperimental.enable(); - // This runs requestAnimationFrame five times without updating display then - // takes a screenshotin in a newly created tab with BeginFrame control. - async function testTargetPage(session) { - dp = session.protocol; - await dp.Runtime.enable(); - await dp.HeadlessExperimental.enable(); + dp.Runtime.onConsoleAPICalled(data => { + const text = data.params.args[0].value; + testRunner.log(text); + }); - dp.Runtime.onConsoleAPICalled(data => { - const text = data.params.args[0].value; - testRunner.log(text); - }); + dp.Emulation.onVirtualTimeAdvanced(data => { + // Debug chrome schedules stray tasks that break this test. + // Our numbers are round, so we prevent this flake 999 times of 1000. + const time = data.params.virtualTimeElapsed; + if (time !== Math.round(time)) + return; + testRunner.log(`Advanced to ${time}ms`); + }); - dp.Emulation.onVirtualTimeAdvanced(data => { - // Debug chrome schedules stray tasks that break this test. - // Our numbers are round, so we prevent this flake 999 times of 1000. - const time = data.params.virtualTimeElapsed; - if (time !== Math.round(time)) - return; - testRunner.log(`Advanced to ${time}ms`); - }); + let virtualTimeBase = 0; + let totalElapsedTime = 0; + let frameTimeTicks = 0; + let lastGrantedChunk = 0; - let virtualTimeBase = 0; - let totalElapsedTime = 0; - let frameTimeTicks = 0; - let lastGrantedChunk = 0; + dp.Emulation.onVirtualTimePaused(data => { + // Remember the base time for frame time calculation. + virtualTimeBase = data.params.virtualTimeElapsed; + }); - dp.Emulation.onVirtualTimePaused(data => { - // Remember the base time for frame time calculation. - virtualTimeBase = data.params.virtualTimeElapsed; - }); + await dp.Emulation.setVirtualTimePolicy({policy: 'pause'}); + lastGrantedChunk = 1000; + await dp.Emulation.setVirtualTimePolicy({ + policy: 'pauseIfNetworkFetchesPending', + budget: lastGrantedChunk, waitForNavigation: true}); - await dp.Emulation.setVirtualTimePolicy({policy: 'pause'}); - lastGrantedChunk = 1000; - await dp.Emulation.setVirtualTimePolicy({ - policy: 'pauseIfNetworkFetchesPending', - budget: lastGrantedChunk, waitForNavigation: true}); + dp.Page.navigate( + {url: testRunner.url('/resources/compositor-basic-raf.html')}); - dp.Page.navigate( - {url: testRunner.url('/resources/compositor-basic-raf.html')}); + // Renderer wants the very first frame to be fully updated. + await AdvanceTime(); + await session.evaluate('startRAF()'); + await dp.HeadlessExperimental.beginFrame({frameTimeTicks}); + await GrantMoreTime(100); - // Renderer wants the very first frame to be fully updated. + // Send 3 updateless frames. + for (var n = 0; n < 3; ++n) { await AdvanceTime(); - await session.evaluate('startRAF()'); - await dp.HeadlessExperimental.beginFrame({frameTimeTicks}); + await dp.HeadlessExperimental.beginFrame({frameTimeTicks, + noDisplayUpdates: true}); await GrantMoreTime(100); + } - // Send 3 updateless frames. - for (var n = 0; n < 3; ++n) { - await AdvanceTime(); - await dp.HeadlessExperimental.beginFrame({frameTimeTicks, - noDisplayUpdates: true}); - await GrantMoreTime(100); + // Grab screenshot, expected size 800x600, rgba: 0,0,50,255. + await AdvanceTime(); + testRunner.log(await session.evaluate('displayRAFCount();')); + const screenshotData = + (await dp.HeadlessExperimental.beginFrame( + {frameTimeTicks, screenshot: {format: 'png'}})) + .result.screenshotData; + await logScreenShotInfo(screenshotData); + + testRunner.completeTest(); + + async function AdvanceTime() { + await dp.Emulation.onceVirtualTimeBudgetExpired(); + totalElapsedTime += lastGrantedChunk; + testRunner.log(`Elasped time: ${totalElapsedTime}`); + frameTimeTicks = virtualTimeBase + totalElapsedTime; + } + + async function GrantMoreTime(budget) { + lastGrantedChunk = budget; + await dp.Emulation.setVirtualTimePolicy({ + policy: 'pauseIfNetworkFetchesPending', budget}); + } + + function logScreenShotInfo(pngBase64) { + const image = new Image(); + + let callback; + let promise = new Promise(fulfill => callback = fulfill); + image.onload = function() { + testRunner.log(`Screenshot size: ` + + `${image.naturalWidth} x ${image.naturalHeight}`); + const canvas = document.createElement('canvas'); + canvas.width = image.naturalWidth; + canvas.height = image.naturalHeight; + const ctx = canvas.getContext('2d'); + ctx.drawImage(image, 0, 0); + const rgba = ctx.getImageData(0, 0, 1, 1).data; + testRunner.log(`Screenshot rgba: ${rgba}`); + callback(); } - // Grab screenshot, expected size 800x600, rgba: 0,0,50,255. - await AdvanceTime(); - testRunner.log(await session.evaluate('displayRAFCount();')); - const screenshotData = - (await dp.HeadlessExperimental.beginFrame( - {frameTimeTicks, screenshot: {format: 'png'}})) - .result.screenshotData; - await logScreenShotInfo(screenshotData); + image.src = `data:image/png;base64,${pngBase64}`; - testRunner.completeTest(); - - async function AdvanceTime() { - await dp.Emulation.onceVirtualTimeBudgetExpired(); - totalElapsedTime += lastGrantedChunk; - testRunner.log(`Elasped time: ${totalElapsedTime}`); - frameTimeTicks = virtualTimeBase + totalElapsedTime; - } - - async function GrantMoreTime(budget) { - lastGrantedChunk = budget; - await dp.Emulation.setVirtualTimePolicy({ - policy: 'pauseIfNetworkFetchesPending', budget}); - } - - function logScreenShotInfo(pngBase64) { - const image = new Image(); - - let callback; - let promise = new Promise(fulfill => callback = fulfill); - image.onload = function() { - testRunner.log(`Screenshot size: ` - + `${image.naturalWidth} x ${image.naturalHeight}`); - const canvas = document.createElement('canvas'); - canvas.width = image.naturalWidth; - canvas.height = image.naturalHeight; - const ctx = canvas.getContext('2d'); - ctx.drawImage(image, 0, 0); - const rgba = ctx.getImageData(0, 0, 1, 1).data; - testRunner.log(`Screenshot rgba: ${rgba}`); - callback(); - } - - image.src = `data:image/png;base64,${pngBase64}`; - - return promise; - } + return promise; } })
diff --git a/headless/test/data/protocol/emulation/compositor-css-animation-test.js b/headless/test/data/protocol/emulation/compositor-css-animation-test.js index d5aa302..812fdc5f 100644 --- a/headless/test/data/protocol/emulation/compositor-css-animation-test.js +++ b/headless/test/data/protocol/emulation/compositor-css-animation-test.js
@@ -3,116 +3,106 @@ // found in the LICENSE file. (async function(testRunner) { - var {page, session, dp} = await testRunner.startBlank( + var {page, session, dp} = await testRunner.startWithFrameControl( 'Tests compositor animated css handling.'); - await dp.Target.enable(); - // Open the test page in a new tab with BeginFrameControl enabled. - await testTargetPage(await session.createTargetInNewContext( - 800, 600, 'about:blank', true)); + await dp.Runtime.enable(); + await dp.HeadlessExperimental.enable(); - // Loads a page with css animation into a a newly created tab with BeginFrame - // control and verifies that animation is advanced according to virtual time. - async function testTargetPage(session) { - dp = session.protocol; - await dp.Runtime.enable(); - await dp.HeadlessExperimental.enable(); + dp.Runtime.onConsoleAPICalled(data => { + const text = data.params.args[0].value; + testRunner.log(text); + }); - dp.Runtime.onConsoleAPICalled(data => { - const text = data.params.args[0].value; - testRunner.log(text); - }); + let virtualTimeBase = 0; + let totalElapsedTime = 0; + let lastGrantedChunk = 0; + let expiredCount = 0; - let virtualTimeBase = 0; - let totalElapsedTime = 0; - let lastGrantedChunk = 0; - let expiredCount = 0; + dp.Emulation.onVirtualTimeBudgetExpired(async data => { + ++expiredCount; + totalElapsedTime += lastGrantedChunk; + testRunner.log(`Expired count: ${expiredCount}` + + `, elaspedTime: ${totalElapsedTime}`); - dp.Emulation.onVirtualTimeBudgetExpired(async data => { - ++expiredCount; - totalElapsedTime += lastGrantedChunk; - testRunner.log(`Expired count: ${expiredCount}` - + `, elaspedTime: ${totalElapsedTime}`); + let grantVirtualTime = 500; + let frameTimeTicks = virtualTimeBase + totalElapsedTime; - let grantVirtualTime = 500; - let frameTimeTicks = virtualTimeBase + totalElapsedTime; - - if (expiredCount == 1) { - // Renderer wants the very first frame to be fully updated. - await dp.HeadlessExperimental.beginFrame({frameTimeTicks}); + if (expiredCount == 1) { + // Renderer wants the very first frame to be fully updated. + await dp.HeadlessExperimental.beginFrame({frameTimeTicks}); + } else { + if (expiredCount >= 4 && expiredCount <= 6) { + // Issue updateless frames. + await dp.HeadlessExperimental.beginFrame( + {frameTimeTicks, noDisplayUpdates: true}); } else { - if (expiredCount >= 4 && expiredCount <= 6) { - // Issue updateless frames. - await dp.HeadlessExperimental.beginFrame( - {frameTimeTicks, noDisplayUpdates: true}); - } else { - // Update frame and grab a screenshot, logging background color. - const {result: {screenshotData}} = - await dp.HeadlessExperimental.beginFrame( - {frameTimeTicks, screenshot: {format: 'png'}}); - await logScreenShotInfo(screenshotData); - } + // Update frame and grab a screenshot, logging background color. + const {result: {screenshotData}} = + await dp.HeadlessExperimental.beginFrame( + {frameTimeTicks, screenshot: {format: 'png'}}); + await logScreenShotInfo(screenshotData); } - - // Grant more time or quit test. - if (expiredCount < 10) { - await dp.Emulation.setVirtualTimePolicy({ - policy: 'pauseIfNetworkFetchesPending', - budget: grantVirtualTime}); - lastGrantedChunk = grantVirtualTime; - } else { - testRunner.completeTest(); - } - }); - - // Pause for the first time and remember base virtual time. - const {result: {virtualTimeTicksBase}} = - await dp.Emulation.setVirtualTimePolicy({policy: 'pause'}); - virtualTimeBase = virtualTimeTicksBase; - - lastGrantedChunk = 500; - await dp.Emulation.setVirtualTimePolicy({ - policy: 'pauseIfNetworkFetchesPending', - budget: lastGrantedChunk, waitForNavigation: true}); - - // Animates opacity of a blue 100px square on red blackground over 4 - // seconds (1.0 -> 0 -> 1.0 four times). Logs events to console. - // - // Timeline: - // 0 ms: --- animation starts at 500ms --- - // 500 ms: 1.0 opacity -> blue background. - // 1000 ms: 0 opacity -> red background. - // 1500 ms: 1.0 opacity -> blue background. - // 2000 ms: 0 opacity -> red background. - // 2500 ms: 1.0 opacity -> blue background. - // 3000 ms: 0 opacity -> red background. - // 3500 ms: 1.0 opacity -> blue background. - // 4000 ms: 0 opacity -> red background. - // 4500 ms: 1.0 opacity -> blue background. - // - // The animation will start with the first BeginFrame after load. - dp.Page.navigate( - {url: testRunner.url('/resources/compositor-css-animation.html')}); - - function logScreenShotInfo(pngBase64) { - const image = new Image(); - - let callback; - let promise = new Promise(fulfill => callback = fulfill); - image.onload = function() { - const canvas = document.createElement('canvas'); - canvas.width = image.naturalWidth; - canvas.height = image.naturalHeight; - const ctx = canvas.getContext('2d'); - ctx.drawImage(image, 0, 0); - const rgba = ctx.getImageData(0, 0, 1, 1).data; - testRunner.log(`Screenshot rgba: ${rgba}`); - callback(); - } - - image.src = `data:image/png;base64,${pngBase64}`; - - return promise; } + + // Grant more time or quit test. + if (expiredCount < 10) { + await dp.Emulation.setVirtualTimePolicy({ + policy: 'pauseIfNetworkFetchesPending', + budget: grantVirtualTime}); + lastGrantedChunk = grantVirtualTime; + } else { + testRunner.completeTest(); + } + }); + + // Pause for the first time and remember base virtual time. + const {result: {virtualTimeTicksBase}} = + await dp.Emulation.setVirtualTimePolicy({policy: 'pause'}); + virtualTimeBase = virtualTimeTicksBase; + + lastGrantedChunk = 500; + await dp.Emulation.setVirtualTimePolicy({ + policy: 'pauseIfNetworkFetchesPending', + budget: lastGrantedChunk, waitForNavigation: true}); + + // Animates opacity of a blue 100px square on red blackground over 4 + // seconds (1.0 -> 0 -> 1.0 four times). Logs events to console. + // + // Timeline: + // 0 ms: --- animation starts at 500ms --- + // 500 ms: 1.0 opacity -> blue background. + // 1000 ms: 0 opacity -> red background. + // 1500 ms: 1.0 opacity -> blue background. + // 2000 ms: 0 opacity -> red background. + // 2500 ms: 1.0 opacity -> blue background. + // 3000 ms: 0 opacity -> red background. + // 3500 ms: 1.0 opacity -> blue background. + // 4000 ms: 0 opacity -> red background. + // 4500 ms: 1.0 opacity -> blue background. + // + // The animation will start with the first BeginFrame after load. + dp.Page.navigate( + {url: testRunner.url('/resources/compositor-css-animation.html')}); + + function logScreenShotInfo(pngBase64) { + const image = new Image(); + + let callback; + let promise = new Promise(fulfill => callback = fulfill); + image.onload = function() { + const canvas = document.createElement('canvas'); + canvas.width = image.naturalWidth; + canvas.height = image.naturalHeight; + const ctx = canvas.getContext('2d'); + ctx.drawImage(image, 0, 0); + const rgba = ctx.getImageData(0, 0, 1, 1).data; + testRunner.log(`Screenshot rgba: ${rgba}`); + callback(); + } + + image.src = `data:image/png;base64,${pngBase64}`; + + return promise; } })
diff --git a/headless/test/data/protocol/emulation/compositor-image-animation-test.js b/headless/test/data/protocol/emulation/compositor-image-animation-test.js index 1793457..712e219 100644 --- a/headless/test/data/protocol/emulation/compositor-image-animation-test.js +++ b/headless/test/data/protocol/emulation/compositor-image-animation-test.js
@@ -3,13 +3,8 @@ // found in the LICENSE file. (async function(testRunner) { - var {page, session, dp} = await testRunner.startBlank( + var {page, session, dp} = await testRunner.startWithFrameControl( 'Tests compositor animated image handling.'); - await dp.Target.enable(); - - // Open the test page in a new tab with BeginFrameControl enabled. - await testTargetPage(await session.createTargetInNewContext( - 800, 600, 'about:blank', true)); // Loads an animated GIF into a a newly created tab with BeginFrame control // and verifies that: @@ -17,114 +12,106 @@ // - first screenshot starts the GIF animation, // - animation is advanced according to virtual time. // - the animation is not resynced after the first iteration. - async function testTargetPage(session) { - dp = session.protocol; - await dp.Runtime.enable(); - await dp.HeadlessExperimental.enable(); + await dp.Runtime.enable(); + await dp.HeadlessExperimental.enable(); - dp.Runtime.onConsoleAPICalled(data => { - const text = data.params.args[0].value; - testRunner.log(text); - }); + dp.Runtime.onConsoleAPICalled(data => { + const text = data.params.args[0].value; + testRunner.log(text); + }); - let virtualTimeBase = 0; - let totalElapsedTime = 0; - let lastGrantedChunk = 0; - let expiredCount = 0; + let virtualTimeBase = 0; + let totalElapsedTime = 0; + let lastGrantedChunk = 0; + let expiredCount = 0; - dp.Emulation.onVirtualTimeBudgetExpired(async data => { - ++expiredCount; - totalElapsedTime += lastGrantedChunk; - testRunner.log(`Expired count: ${expiredCount}, ` - + `elaspedTime: ${totalElapsedTime}`); + dp.Emulation.onVirtualTimeBudgetExpired(async data => { + ++expiredCount; + totalElapsedTime += lastGrantedChunk; + testRunner.log(`Expired count: ${expiredCount}, ` + + `elaspedTime: ${totalElapsedTime}`); - let grantVirtualTime = 500; - let frameTimeTicks = virtualTimeBase + totalElapsedTime; + let grantVirtualTime = 500; + let frameTimeTicks = virtualTimeBase + totalElapsedTime; - if (expiredCount === 1 + 7 - || expiredCount === 1 + 7 + 5 - || expiredCount === 1 + 7 + 5 + 6) { - // Animation starts when first screenshot is taken, so the first - // screenshot should be blue. Screenshot #2 is taken on the third second - // of the animation, so it should be yellow. Screenshot #3 is taken two - // animation cycles later, so it should be yelloe again. - const {result: {screenshotData}} = - await dp.HeadlessExperimental.beginFrame( - {frameTimeTicks, screenshot: {format: 'png'}}); - await logScreenShotInfo(screenshotData); - } else { - await dp.HeadlessExperimental.beginFrame( - {frameTimeTicks, noDisplayUpdates: true}); - } - - // Grant more time or quit test. - if (expiredCount < 20) { - await dp.Emulation.setVirtualTimePolicy({ - policy: 'pauseIfNetworkFetchesPending', - budget: grantVirtualTime}); - lastGrantedChunk = grantVirtualTime; - } else { - testRunner.completeTest(); - } - }); - - // Pause for the first time and remember base virtual time. - const {result: {virtualTimeTicksBase}} = - await dp.Emulation.setVirtualTimePolicy( - {initialVirtualTime: 100, policy: 'pause'}); - virtualTimeBase = virtualTimeTicksBase; - - // Renderer wants the very first frame to be fully updated. - await dp.HeadlessExperimental.beginFrame({noDisplayUpdates: false}); - - // Grant initial time. - lastGrantedChunk = 500; - await dp.Emulation.setVirtualTimePolicy({ - policy: 'pauseIfNetworkFetchesPending', - budget: lastGrantedChunk, waitForNavigation: true}); - - // The loaded GIF is 100x100px and has 1 second of blue, 1 second of red and - // 1 second of yellow. - dp.Page.navigate( - {url: testRunner.url('/resources/compositor-image-animation.html')}); - - async function AdvanceTime() { - await dp.Emulation.onceVirtualTimeBudgetExpired(); - totalElapsedTime += lastGrantedChunk; - testRunner.log(`Elasped time: ${totalElapsedTime}`); - frameTimeTicks = virtualTimeBase + totalElapsedTime; + if (expiredCount === 1 + 7 + || expiredCount === 1 + 7 + 5 + || expiredCount === 1 + 7 + 5 + 6) { + // Animation starts when first screenshot is taken, so the first + // screenshot should be blue. Screenshot #2 is taken on the third second + // of the animation, so it should be yellow. Screenshot #3 is taken two + // animation cycles later, so it should be yelloe again. + const {result: {screenshotData}} = + await dp.HeadlessExperimental.beginFrame( + {frameTimeTicks, screenshot: {format: 'png'}}); + await logScreenShotInfo(screenshotData); + } else { + await dp.HeadlessExperimental.beginFrame( + {frameTimeTicks, noDisplayUpdates: true}); } - async function GrantMoreTime(budget) { - lastGrantedChunk = budget; + // Grant more time or quit test. + if (expiredCount < 20) { await dp.Emulation.setVirtualTimePolicy({ - policy: 'pauseIfNetworkFetchesPending', budget}); - } - - function logScreenShotInfo(pngBase64) { - const image = new Image(); - - let callback; - let promise = new Promise(fulfill => callback = fulfill); - image.onload = function() { - const canvas = document.createElement('canvas'); - canvas.width = image.naturalWidth; - canvas.height = image.naturalHeight; - const ctx = canvas.getContext('2d'); - ctx.drawImage(image, 0, 0); - const rgba = ctx.getImageData(0, 0, 1, 1).data; - testRunner.log(`Screenshot rgba: ${rgba}`); - callback(); - } - - image.src = `data:image/png;base64,${pngBase64}`; - - return promise; - } - - setTimeout(() => { - testRunner.log('Forced test termination'); + policy: 'pauseIfNetworkFetchesPending', + budget: grantVirtualTime}); + lastGrantedChunk = grantVirtualTime; + } else { testRunner.completeTest(); - }, 10 * 1000); + } + }); + + // Pause for the first time and remember base virtual time. + const {result: {virtualTimeTicksBase}} = + await dp.Emulation.setVirtualTimePolicy( + {initialVirtualTime: 100, policy: 'pause'}); + virtualTimeBase = virtualTimeTicksBase; + + // Renderer wants the very first frame to be fully updated. + await dp.HeadlessExperimental.beginFrame({noDisplayUpdates: false}); + + // Grant initial time. + lastGrantedChunk = 500; + await dp.Emulation.setVirtualTimePolicy({ + policy: 'pauseIfNetworkFetchesPending', + budget: lastGrantedChunk, waitForNavigation: true}); + + // The loaded GIF is 100x100px and has 1 second of blue, 1 second of red and + // 1 second of yellow. + dp.Page.navigate( + {url: testRunner.url('/resources/compositor-image-animation.html')}); + + async function AdvanceTime() { + await dp.Emulation.onceVirtualTimeBudgetExpired(); + totalElapsedTime += lastGrantedChunk; + testRunner.log(`Elasped time: ${totalElapsedTime}`); + frameTimeTicks = virtualTimeBase + totalElapsedTime; + } + + async function GrantMoreTime(budget) { + lastGrantedChunk = budget; + await dp.Emulation.setVirtualTimePolicy({ + policy: 'pauseIfNetworkFetchesPending', budget}); + } + + function logScreenShotInfo(pngBase64) { + const image = new Image(); + + let callback; + let promise = new Promise(fulfill => callback = fulfill); + image.onload = function() { + const canvas = document.createElement('canvas'); + canvas.width = image.naturalWidth; + canvas.height = image.naturalHeight; + const ctx = canvas.getContext('2d'); + ctx.drawImage(image, 0, 0); + const rgba = ctx.getImageData(0, 0, 1, 1).data; + testRunner.log(`Screenshot rgba: ${rgba}`); + callback(); + } + + image.src = `data:image/png;base64,${pngBase64}`; + + return promise; } })
diff --git a/headless/test/data/protocol/helpers/virtual-time-controller-test.js b/headless/test/data/protocol/helpers/virtual-time-controller-test.js index a15b82e01..4ed49a71 100644 --- a/headless/test/data/protocol/helpers/virtual-time-controller-test.js +++ b/headless/test/data/protocol/helpers/virtual-time-controller-test.js
@@ -3,48 +3,40 @@ // found in the LICENSE file. (async function(testRunner) { - let {page, session, dp} = await testRunner.startBlank( - `Tests virtual time controller operation.`); - await dp.Target.enable(); - let VirtualTimeController = await testRunner.loadScript('virtual-time-controller.js'); - // Open the test page in a new tab with BeginFrameControl enabled. - await testTargetPage( - await session.createTargetInNewContext(800, 600, 'about:blank', true)); + let {page, session, dp} = await testRunner.startWithFrameControl( + `Tests virtual time controller operation.`); - async function testTargetPage(session) { - const dp = session.protocol; - await dp.Runtime.enable(); - await dp.HeadlessExperimental.enable(); + await dp.Runtime.enable(); + await dp.HeadlessExperimental.enable(); - dp.Runtime.onConsoleAPICalled(data => { - const text = data.params.args[0].value; - testRunner.log(text); - }); + dp.Runtime.onConsoleAPICalled(data => { + const text = data.params.args[0].value; + testRunner.log(text); + }); - let expirationCount = 0; - const vtc = new VirtualTimeController(testRunner, dp, 25); - await vtc.grantInitialTime(100, 1000, onInstalled, onExpired); + let expirationCount = 0; + const vtc = new VirtualTimeController(testRunner, dp, 25); + await vtc.grantInitialTime(100, 1000, onInstalled, onExpired); - async function onInstalled(virtualTimeBase){ - testRunner.log(`onInstalled:`); - } - - async function onExpired(totalElapsedTime) { - testRunner.log(`onExpired: ${totalElapsedTime}`); - if (expirationCount === 0) - await session.evaluate('startRAF()'); - - if (++expirationCount < 3) { - await vtc.grantTime(50, onExpired); - } else { - testRunner.completeTest(); - } - } - - dp.Page.navigate({url: testRunner.url( - 'resources/virtual-time-controller-test.html')}); + async function onInstalled(virtualTimeBase){ + testRunner.log(`onInstalled:`); } + + async function onExpired(totalElapsedTime) { + testRunner.log(`onExpired: ${totalElapsedTime}`); + if (expirationCount === 0) + await session.evaluate('startRAF()'); + + if (++expirationCount < 3) { + await vtc.grantTime(50, onExpired); + } else { + testRunner.completeTest(); + } + } + + dp.Page.navigate({url: testRunner.url( + 'resources/virtual-time-controller-test.html')}); })
diff --git a/headless/test/data/protocol/inspector-protocol-test.html b/headless/test/data/protocol/inspector-protocol-test.html index e0c46263..0a11866 100644 --- a/headless/test/data/protocol/inspector-protocol-test.html +++ b/headless/test/data/protocol/inspector-protocol-test.html
@@ -12,12 +12,12 @@ testRunner.waitUntilDone = () => {}; testRunner.setCanOpenWindows = () => {}; testRunner.notifyDone = () => { - console.debug(JSON.stringify({id: 0, method: 'DONE', params: {}, result: output.join('\n')})); + sendProtocolMessage(JSON.stringify({id: 0, method: 'DONE', params: {}, result: output.join('\n')})); }; DevToolsHost = {}; DevToolsHost.sendMessageToEmbedder = (message) => { const object = JSON.parse(message); - console.debug(object.params[0]); + sendProtocolMessage(object.params[0]); } DevToolsHost.dummyPageURL = `http://127.0.0.1:${window.location.port}/protocol/inspector-protocol-page.html`;
diff --git a/headless/test/data/protocol/sanity/renderer-canvas.js b/headless/test/data/protocol/sanity/renderer-canvas.js index 3f6d5145..dfcea27 100644 --- a/headless/test/data/protocol/sanity/renderer-canvas.js +++ b/headless/test/data/protocol/sanity/renderer-canvas.js
@@ -3,80 +3,72 @@ // found in the LICENSE file. (async function(testRunner) { - let {page, session, dp} = await testRunner.startBlank( + let {page, session, dp} = await testRunner.startWithFrameControl( 'Tests renderer: canvas.'); - // Open the test page in a new tab with BeginFrameControl enabled. - await testTargetPage(await session.createTargetInNewContext( - 800, 600, 'about:blank', true)); + await dp.Runtime.enable(); + await dp.HeadlessExperimental.enable(); - async function testTargetPage(session) { - dp = session.protocol; - await dp.Runtime.enable(); - await dp.HeadlessExperimental.enable(); + let RendererTestHelper = + await testRunner.loadScript('../helpers/renderer-test-helper.js'); + let {httpInterceptor, frameNavigationHelper, virtualTimeController} = + await (new RendererTestHelper(testRunner, dp, page)).init(); - let RendererTestHelper = - await testRunner.loadScript('../helpers/renderer-test-helper.js'); - let {httpInterceptor, frameNavigationHelper, virtualTimeController} = - await (new RendererTestHelper(testRunner, dp, page)).init(); + httpInterceptor.addResponse( + `http://example.com/`, + `<html> + <body> + <canvas id="test_canvas" width="100" height="100" + style="position:absolute;left:0px;top:0px"> + Oops! Canvas not supported! + </canvas> + <script> + var context = document.getElementById("test_canvas"). + getContext("2d"); + context.fillStyle = "rgb(255,0,0)"; + context.fillRect(25, 25, 50, 50); + </script> + </body> + </html>`); - httpInterceptor.addResponse( - `http://example.com/`, - `<html> - <body> - <canvas id="test_canvas" width="100" height="100" - style="position:absolute;left:0px;top:0px"> - Oops! Canvas not supported! - </canvas> - <script> - var context = document.getElementById("test_canvas"). - getContext("2d"); - context.fillStyle = "rgb(255,0,0)"; - context.fillRect(25, 25, 50, 50); - </script> - </body> - </html>`); + await virtualTimeController.grantInitialTime(500, 1000, + null, + async () => { + const frameTimeTicks = virtualTimeController.currentFrameTime(); + const screenshotData = + (await dp.HeadlessExperimental.beginFrame( + {frameTimeTicks, screenshot: {format: 'png'}})) + .result.screenshotData; + await logScreenShotData(screenshotData); + testRunner.completeTest(); + } + ); - await virtualTimeController.grantInitialTime(500, 1000, - null, - async () => { - const frameTimeTicks = virtualTimeController.currentFrameTime(); - const screenshotData = - (await dp.HeadlessExperimental.beginFrame( - {frameTimeTicks, screenshot: {format: 'png'}})) - .result.screenshotData; - await logScreenShotData(screenshotData); - testRunner.completeTest(); - } - ); + function logScreenShotData(pngBase64) { + const image = new Image(); - function logScreenShotData(pngBase64) { - const image = new Image(); - - let callback; - let promise = new Promise(fulfill => callback = fulfill); - image.onload = function() { - testRunner.log(`Screenshot size: ` - + `${image.naturalWidth} x ${image.naturalHeight}`); - const canvas = document.createElement('canvas'); - canvas.width = image.naturalWidth; - canvas.height = image.naturalHeight; - const ctx = canvas.getContext('2d'); - ctx.drawImage(image, 0, 0); - // Expected rgba @(0,0): 255,255,255,255 - const rgba = ctx.getImageData(0, 0, 1, 1).data; - testRunner.log(`rgba @(0,0): ${rgba}`); - // Expected rgba @(25,25): 255,0,0,255 - const rgba2 = ctx.getImageData(25, 25, 1, 1).data; - testRunner.log(`rgba @(25,25): ${rgba2}`); - callback(); - } - - image.src = `data:image/png;base64,${pngBase64}`; - - return promise; + let callback; + let promise = new Promise(fulfill => callback = fulfill); + image.onload = function() { + testRunner.log(`Screenshot size: ` + + `${image.naturalWidth} x ${image.naturalHeight}`); + const canvas = document.createElement('canvas'); + canvas.width = image.naturalWidth; + canvas.height = image.naturalHeight; + const ctx = canvas.getContext('2d'); + ctx.drawImage(image, 0, 0); + // Expected rgba @(0,0): 255,255,255,255 + const rgba = ctx.getImageData(0, 0, 1, 1).data; + testRunner.log(`rgba @(0,0): ${rgba}`); + // Expected rgba @(25,25): 255,0,0,255 + const rgba2 = ctx.getImageData(25, 25, 1, 1).data; + testRunner.log(`rgba @(25,25): ${rgba2}`); + callback(); } - await frameNavigationHelper.navigate('http://example.com/'); + image.src = `data:image/png;base64,${pngBase64}`; + + return promise; } + await frameNavigationHelper.navigate('http://example.com/'); })
diff --git a/headless/test/data/protocol/sanity/renderer-css-url-filter.js b/headless/test/data/protocol/sanity/renderer-css-url-filter.js index 4f690c2e..d338d47 100644 --- a/headless/test/data/protocol/sanity/renderer-css-url-filter.js +++ b/headless/test/data/protocol/sanity/renderer-css-url-filter.js
@@ -3,97 +3,90 @@ // found in the LICENSE file. (async function(testRunner) { - let {page, session, dp} = await testRunner.startBlank( - 'Tests renderer: canvas.'); - - // Open the test page in a new tab with BeginFrameControl enabled. - await testTargetPage(await session.createTargetInNewContext( - 100, 100, 'about:blank', true)); + let {page, session, dp} = await testRunner.startWithFrameControl( + 'Tests renderer: canvas.', {width: 100, height: 100}); // Ensures that "filter: url(...)" does not get into an infinite style update // loop. - async function testTargetPage(session) { - dp = session.protocol; - await dp.Runtime.enable(); - await dp.HeadlessExperimental.enable(); + await dp.Runtime.enable(); + await dp.HeadlessExperimental.enable(); - let RendererTestHelper = - await testRunner.loadScript('../helpers/renderer-test-helper.js'); - let {httpInterceptor, frameNavigationHelper, virtualTimeController} = - await (new RendererTestHelper(testRunner, dp, page)).init(); + let RendererTestHelper = + await testRunner.loadScript('../helpers/renderer-test-helper.js'); + let {httpInterceptor, frameNavigationHelper, virtualTimeController} = + await (new RendererTestHelper(testRunner, dp, page)).init(); - // The image from circle.svg will be drawn with the blur from blur.svg. - httpInterceptor.addResponse( - `http://www.example.com/`, - `<!DOCTYPE html> - <style> - body { margin: 0; } - img { - -webkit-filter: url(blur.svg#blur); - filter: url(blur.svg#blur); - } - </style> - <img src="circle.svg">`); - - // Just a normal image. - httpInterceptor.addResponse( - `http://www.example.com/circle.svg`, - `<svg width="100" height="100" version="1.1" - xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink"> - <circle cx="50" cy="50" r="50" fill="green" /> - </svg>`); - - // A blur filter stored inside an svg file. - httpInterceptor.addResponse( - `http://www.example.com/blur.svg#blur`, - `<svg width="100" height="100" version="1.1" - xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink"> - <filter id="blur"> - <feGaussianBlur in="SourceGraphic" stdDeviation="5"/> - </filter> - </svg>`); - - await virtualTimeController.grantInitialTime(500, 1000, - null, - async () => { - const frameTimeTicks = virtualTimeController.currentFrameTime(); - const screenshotData = - (await dp.HeadlessExperimental.beginFrame( - {frameTimeTicks, screenshot: {format: 'png'}})) - .result.screenshotData; - await logScreenShotData(screenshotData); - testRunner.completeTest(); - } - ); - - function logScreenShotData(pngBase64) { - const image = new Image(); - - let callback; - let promise = new Promise(fulfill => callback = fulfill); - image.onload = function() { - testRunner.log(`Screenshot size: ` - + `${image.naturalWidth} x ${image.naturalHeight}`); - const canvas = document.createElement('canvas'); - canvas.width = image.naturalWidth; - canvas.height = image.naturalHeight; - const ctx = canvas.getContext('2d'); - ctx.drawImage(image, 0, 0); - for (let n = 0; n < 25; ++n) { - const rgba = ctx.getImageData(n, n, 1, 1).data; - testRunner.log(`rgba @(${n},${n}): ${rgba}`); + // The image from circle.svg will be drawn with the blur from blur.svg. + httpInterceptor.addResponse( + `http://www.example.com/`, + `<!DOCTYPE html> + <style> + body { margin: 0; } + img { + -webkit-filter: url(blur.svg#blur); + filter: url(blur.svg#blur); } + </style> + <img src="circle.svg">`); - callback(); + // Just a normal image. + httpInterceptor.addResponse( + `http://www.example.com/circle.svg`, + `<svg width="100" height="100" version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <circle cx="50" cy="50" r="50" fill="green" /> + </svg>`); + + // A blur filter stored inside an svg file. + httpInterceptor.addResponse( + `http://www.example.com/blur.svg#blur`, + `<svg width="100" height="100" version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <filter id="blur"> + <feGaussianBlur in="SourceGraphic" stdDeviation="5"/> + </filter> + </svg>`); + + await virtualTimeController.grantInitialTime(500, 1000, + null, + async () => { + const frameTimeTicks = virtualTimeController.currentFrameTime(); + const screenshotData = + (await dp.HeadlessExperimental.beginFrame( + {frameTimeTicks, screenshot: {format: 'png'}})) + .result.screenshotData; + await logScreenShotData(screenshotData); + testRunner.completeTest(); + } + ); + + function logScreenShotData(pngBase64) { + const image = new Image(); + + let callback; + let promise = new Promise(fulfill => callback = fulfill); + image.onload = function() { + testRunner.log(`Screenshot size: ` + + `${image.naturalWidth} x ${image.naturalHeight}`); + const canvas = document.createElement('canvas'); + canvas.width = image.naturalWidth; + canvas.height = image.naturalHeight; + const ctx = canvas.getContext('2d'); + ctx.drawImage(image, 0, 0); + for (let n = 0; n < 25; ++n) { + const rgba = ctx.getImageData(n, n, 1, 1).data; + testRunner.log(`rgba @(${n},${n}): ${rgba}`); } - image.src = `data:image/png;base64,${pngBase64}`; - - return promise; + callback(); } - await frameNavigationHelper.navigate('http://www.example.com/'); + image.src = `data:image/png;base64,${pngBase64}`; + + return promise; } + + await frameNavigationHelper.navigate('http://www.example.com/'); })
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc index bd0227c..2439bd4 100644 --- a/headless/test/headless_protocol_browsertest.cc +++ b/headless/test/headless_protocol_browsertest.cc
@@ -39,7 +39,7 @@ class HeadlessProtocolBrowserTest : public HeadlessAsyncDevTooledBrowserTest, public HeadlessDevToolsClient::RawProtocolListener, - public runtime::Observer { + public runtime::ExperimentalObserver { public: HeadlessProtocolBrowserTest() { embedded_test_server()->ServeFilesFromSourceDirectory( @@ -51,8 +51,12 @@ // HeadlessWebContentsObserver implementation. void DevToolsTargetReady() override { HeadlessAsyncDevTooledBrowserTest::DevToolsTargetReady(); - devtools_client_->GetRuntime()->AddObserver(this); + devtools_client_->GetRuntime()->GetExperimental()->AddObserver(this); devtools_client_->GetRuntime()->Enable(); + devtools_client_->GetRuntime()->GetExperimental()->AddBinding( + headless::runtime::AddBindingParams::Builder() + .SetName("sendProtocolMessage") + .Build()); browser_devtools_client_->SetRawProtocolListener(this); } @@ -81,23 +85,8 @@ } // runtime::Observer implementation. - void OnConsoleAPICalled( - const runtime::ConsoleAPICalledParams& params) override { - const std::vector<std::unique_ptr<runtime::RemoteObject>>& args = - *params.GetArgs(); - if (args.empty()) - return; - if (params.GetType() != runtime::ConsoleAPICalledType::DEBUG) - return; - - runtime::RemoteObject* object = args[0].get(); - if (object->GetType() != runtime::RemoteObjectType::STRING) - return; - - DispatchMessageFromJS(object->GetValue()->GetString()); - } - - void DispatchMessageFromJS(const std::string& json_message) { + void OnBindingCalled(const runtime::BindingCalledParams& params) override { + std::string json_message = params.GetPayload(); std::unique_ptr<base::Value> message = base::JSONReader::Read(json_message); const base::DictionaryValue* message_dict; const base::DictionaryValue* params_dict;
diff --git a/headless/test/headless_render_browsertest.cc b/headless/test/headless_render_browsertest.cc deleted file mode 100644 index fb26cd0..0000000 --- a/headless/test/headless_render_browsertest.cc +++ /dev/null
@@ -1,1488 +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. - -#include <functional> - -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/threading/thread_restrictions.h" -#include "build/build_config.h" -#include "content/public/test/browser_test.h" -#include "headless/public/devtools/domains/dom_snapshot.h" -#include "headless/public/devtools/domains/page.h" -#include "headless/public/devtools/domains/runtime.h" -#include "headless/public/headless_devtools_client.h" -#include "headless/test/headless_render_test.h" -#include "net/test/embedded_test_server/http_response.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -#define HEADLESS_RENDER_BROWSERTEST(clazz) \ - class HeadlessRenderBrowserTest##clazz : public clazz {}; \ - HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessRenderBrowserTest##clazz) - -#define DISABLED_HEADLESS_RENDER_BROWSERTEST(clazz) \ - class HeadlessRenderBrowserTest##clazz : public clazz {}; \ - DISABLED_HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessRenderBrowserTest##clazz) - -// TODO(dats): For some reason we are missing all HTTP redirects. -// crbug.com/789298 -#define DISABLE_HTTP_REDIRECTS_CHECKS - -namespace headless { - -namespace { - -constexpr char kSomeUrl[] = "http://example.com/foobar"; -constexpr char kTextHtml[] = "text/html"; -constexpr char kApplicationOctetStream[] = "application/octet-stream"; -constexpr char kImagePng[] = "image/png"; -constexpr char kImageSvgXml[] = "image/svg+xml"; - -using dom_snapshot::GetSnapshotResult; -using dom_snapshot::DOMNode; -using dom_snapshot::LayoutTreeNode; -using net::test_server::HttpRequest; -using net::test_server::HttpResponse; -using net::test_server::BasicHttpResponse; -using net::test_server::RawHttpResponse; -using page::FrameScheduledNavigationReason; -using testing::ElementsAre; -using testing::UnorderedElementsAre; -using testing::Eq; -using testing::Ne; -using testing::StartsWith; - -template <typename T, typename V> -std::vector<T> ElementsView(const std::vector<std::unique_ptr<V>>& elements, - std::function<bool(const V&)> filter, - std::function<T(const V&)> transform) { - std::vector<T> result; - for (const auto& element : elements) { - if (filter(*element)) - result.push_back(transform(*element)); - } - return result; -} - -bool HasType(int type, const DOMNode& node) { - return node.GetNodeType() == type; -} -bool HasName(const char* name, const DOMNode& node) { - return node.GetNodeName() == name; -} -bool IsTag(const DOMNode& node) { - return HasType(1, node); -} -bool IsText(const DOMNode& node) { - return HasType(3, node); -} - -std::vector<std::string> TextLayout(const GetSnapshotResult* snapshot) { - return ElementsView<std::string, LayoutTreeNode>( - *snapshot->GetLayoutTreeNodes(), - [](const auto& node) { return node.HasLayoutText(); }, - [](const auto& node) { return node.GetLayoutText(); }); -} - -std::vector<const DOMNode*> FilterDOM( - const GetSnapshotResult* snapshot, - std::function<bool(const DOMNode&)> filter) { - return ElementsView<const DOMNode*, DOMNode>( - *snapshot->GetDomNodes(), filter, [](const auto& n) { return &n; }); -} - -std::vector<const DOMNode*> FindTags(const GetSnapshotResult* snapshot, - const char* name = nullptr) { - return FilterDOM(snapshot, [name](const auto& n) { - return IsTag(n) && (!name || HasName(name, n)); - }); -} - -size_t IndexInDOM(const GetSnapshotResult* snapshot, const DOMNode* node) { - for (size_t i = 0; i < snapshot->GetDomNodes()->size(); ++i) { - if (snapshot->GetDomNodes()->at(i).get() == node) - return i; - } - CHECK(false); - return static_cast<size_t>(-1); -} - -const DOMNode* GetAt(const GetSnapshotResult* snapshot, size_t index) { - CHECK_LE(index, snapshot->GetDomNodes()->size()); - return snapshot->GetDomNodes()->at(index).get(); -} - -const DOMNode* NextNode(const GetSnapshotResult* snapshot, - const DOMNode* node) { - return GetAt(snapshot, IndexInDOM(snapshot, node) + 1); -} - -MATCHER_P(NodeName, expected, "") { - return arg->GetNodeName() == expected; -} -MATCHER_P(NodeValue, expected, "") { - return arg->GetNodeValue() == expected; -} -MATCHER_P(NodeType, expected, 0) { - return arg->GetNodeType() == expected; -} - -MATCHER_P(RemoteString, expected, "") { - return arg->GetType() == runtime::RemoteObjectType::STRING && - arg->GetValue()->GetString() == expected; -} - -MATCHER_P(RequestPath, expected, "") { - return arg.relative_url == expected; -} - -MATCHER_P(Reason, expected, "") { - return arg.reason == expected; -} - -MATCHER_P(CookieValue, expected, "") { - return arg->GetValue() == expected; -} - -const DOMNode* FindTag(const GetSnapshotResult* snapshot, const char* name) { - auto tags = FindTags(snapshot, name); - if (tags.empty()) - return nullptr; - EXPECT_THAT(tags, ElementsAre(NodeName(name))); - return tags[0]; -} - -TestNetworkInterceptor::Response HttpRedirect( - int code, - const std::string& url, - const std::string& status = "Moved") { - CHECK(code >= 300 && code < 400); - std::stringstream str; - str << "HTTP/1.1 " << code << " " << status << "\r\nLocation: " << url - << "\r\n\r\n"; - return TestNetworkInterceptor::Response(str.str()); -} - -TestNetworkInterceptor::Response HttpOk( - const std::string& html, - const std::string& mime_type = kTextHtml) { - return TestNetworkInterceptor::Response(html, mime_type); -} - -TestNetworkInterceptor::Response ResponseFromFile( - const std::string& file_name, - const std::string& mime_type) { - static const base::FilePath kTestDataDirectory( - FILE_PATH_LITERAL("headless/test/data")); - - base::ScopedAllowBlockingForTesting allow_blocking; - - base::FilePath src_dir; - CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_dir)); - base::FilePath file_path = - src_dir.Append(kTestDataDirectory).Append(file_name); - std::string contents; - CHECK(base::ReadFileToString(file_path, &contents)); - - return TestNetworkInterceptor::Response(contents, mime_type); -} - -} // namespace - -class HelloWorldTest : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse(kSomeUrl, HttpOk(R"|(<!doctype html> -<h1>Hello headless world!</h1> -)|")); - return GURL(kSomeUrl); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(FindTags(dom_snapshot), - ElementsAre(NodeName("HTML"), NodeName("HEAD"), - NodeName("BODY"), NodeName("H1"))); - EXPECT_THAT( - FilterDOM(dom_snapshot, IsText), - ElementsAre(NodeValue("Hello headless world!"), NodeValue("\n"))); - EXPECT_THAT(TextLayout(dom_snapshot), ElementsAre("Hello headless world!")); - EXPECT_THAT(interceptor_->urls_requested(), ElementsAre(kSomeUrl)); - EXPECT_FALSE(main_frame_.empty()); - EXPECT_TRUE(scheduled_navigations_.empty()); - EXPECT_THAT(frames_[main_frame_].size(), Eq(1u)); - const auto& frame = frames_[main_frame_][0]; - EXPECT_THAT(frame->GetUrl(), Eq(kSomeUrl)); - } -}; -HEADLESS_RENDER_BROWSERTEST(HelloWorldTest); - -class TimeoutTest : public HelloWorldTest { - private: - void OnPageRenderCompleted() override { - // Never complete. - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - FAIL() << "Should not reach here"; - } - - void OnTimeout() override { SetTestCompleted(); } -}; -HEADLESS_RENDER_BROWSERTEST(TimeoutTest); - -class JavaScriptOverrideTitle_JsEnabled : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse(kSomeUrl, HttpOk(R"|( -<html> - <head> - <title>JavaScript is off</title> - <script language="JavaScript"> - <!-- Begin - document.title = 'JavaScript is on'; - // End --> - </script> - </head> - <body onload="settitle()"> - Hello, World! - </body> -</html> -)|")); - return GURL(kSomeUrl); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - const DOMNode* value = - NextNode(dom_snapshot, FindTag(dom_snapshot, "TITLE")); - EXPECT_THAT(value, NodeValue("JavaScript is on")); - } -}; -HEADLESS_RENDER_BROWSERTEST(JavaScriptOverrideTitle_JsEnabled); - -class JavaScriptOverrideTitle_JsDisabled - : public JavaScriptOverrideTitle_JsEnabled { - private: - void OverrideWebPreferences(WebPreferences* preferences) override { - JavaScriptOverrideTitle_JsEnabled::OverrideWebPreferences(preferences); - preferences->javascript_enabled = false; - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - const DOMNode* value = - NextNode(dom_snapshot, FindTag(dom_snapshot, "TITLE")); - EXPECT_THAT(value, NodeValue("JavaScript is off")); - } -}; -HEADLESS_RENDER_BROWSERTEST(JavaScriptOverrideTitle_JsDisabled); - -class JavaScriptConsoleErrors : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse(kSomeUrl, HttpOk(R"|( -<html> - <head> - <script language="JavaScript"> - <![CDATA[ - function image() { - window.open('<xsl:value-of select="/IMAGE/@href" />'); - } - ]]> - </script> - </head> - <body onload="func3()"> - <script type="text/javascript"> - func1() - </script> - <script type="text/javascript"> - func2(); - </script> - <script type="text/javascript"> - console.log("Hello, Script!"); - </script> - </body> -</html> -)|")); - return GURL(kSomeUrl); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(console_log_, ElementsAre("L Hello, Script!")); - EXPECT_THAT(js_exceptions_, - ElementsAre(StartsWith("Uncaught SyntaxError:"), - StartsWith("Uncaught ReferenceError: func1"), - StartsWith("Uncaught ReferenceError: func2"), - StartsWith("Uncaught ReferenceError: func3"))); - } -}; -HEADLESS_RENDER_BROWSERTEST(JavaScriptConsoleErrors); - -class DelayedCompletion : public HeadlessRenderTest { - private: - base::TimeTicks start_; - - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse(kSomeUrl, HttpOk(R"|( -<html> - <body> - <script type="text/javascript"> - setTimeout(() => { - var div = document.getElementById('content'); - var p = document.createElement('p'); - p.textContent = 'delayed text'; - div.appendChild(p); - }, 3000); - </script> - <div id="content"/> - </body> -</html> -)|")); - start_ = base::TimeTicks::Now(); - return GURL(kSomeUrl); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - base::TimeTicks end = base::TimeTicks::Now(); - EXPECT_THAT( - FindTags(dom_snapshot), - ElementsAre(NodeName("HTML"), NodeName("HEAD"), NodeName("BODY"), - NodeName("SCRIPT"), NodeName("DIV"), NodeName("P"))); - const DOMNode* value = NextNode(dom_snapshot, FindTag(dom_snapshot, "P")); - EXPECT_THAT(value, NodeValue("delayed text")); - // The page delays output for 3 seconds. Due to virtual time this should - // take significantly less actual time. - base::TimeDelta passed = end - start_; - EXPECT_THAT(passed.InSecondsF(), testing::Le(2.9f)); - } -}; -HEADLESS_RENDER_BROWSERTEST(DelayedCompletion); - -class ClientRedirectChain : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html> - <head> - <meta http-equiv="refresh" content="0; url=http://www.example.com/1"/> - <title>Hello, World 0</title> - </head> - <body>http://www.example.com/</body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/1", HttpOk(R"|( -<html> - <head> - <title>Hello, World 1</title> - <script> - document.location='http://www.example.com/2'; - </script> - </head> - <body>http://www.example.com/1</body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/2", HttpOk(R"|( -<html> - <head> - <title>Hello, World 2</title> - <script> - setTimeout("document.location='http://www.example.com/3'", 1000); - </script> - </head> - <body>http://www.example.com/2</body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/3", HttpOk(R"|( -<html> - <head> - <title>Pass</title> - </head> - <body> - http://www.example.com/3 - <img src="pass"> - </body> -</html> -)|")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1", - "http://www.example.com/2", "http://www.example.com/3", - "http://www.example.com/pass")); - const DOMNode* value = - NextNode(dom_snapshot, FindTag(dom_snapshot, "TITLE")); - EXPECT_THAT(value, NodeValue("Pass")); - EXPECT_THAT( - scheduled_navigations_[main_frame_], - ElementsAre(Reason(FrameScheduledNavigationReason::META_TAG_REFRESH), - Reason(FrameScheduledNavigationReason::SCRIPT_INITIATED), - Reason(FrameScheduledNavigationReason::SCRIPT_INITIATED))); - EXPECT_THAT(frames_[main_frame_].size(), Eq(4u)); - } -}; -HEADLESS_RENDER_BROWSERTEST(ClientRedirectChain); - -class ClientRedirectChain_NoJs : public ClientRedirectChain { - private: - void OverrideWebPreferences(WebPreferences* preferences) override { - ClientRedirectChain::OverrideWebPreferences(preferences); - preferences->javascript_enabled = false; - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1")); - const DOMNode* value = - NextNode(dom_snapshot, FindTag(dom_snapshot, "TITLE")); - EXPECT_THAT(value, NodeValue("Hello, World 1")); - EXPECT_THAT( - scheduled_navigations_[main_frame_], - ElementsAre(Reason(FrameScheduledNavigationReason::META_TAG_REFRESH))); - EXPECT_THAT(frames_[main_frame_].size(), Eq(2u)); - } -}; -HEADLESS_RENDER_BROWSERTEST(ClientRedirectChain_NoJs); - -class ServerRedirectChain : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", - HttpRedirect(302, "http://www.example.com/1")); - interceptor_->InsertResponse("http://www.example.com/1", - HttpRedirect(301, "http://www.example.com/2")); - interceptor_->InsertResponse("http://www.example.com/2", - HttpRedirect(302, "http://www.example.com/3")); - interceptor_->InsertResponse("http://www.example.com/3", - HttpOk("<p>Pass</p>")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1", - "http://www.example.com/2", "http://www.example.com/3")); - const DOMNode* value = NextNode(dom_snapshot, FindTag(dom_snapshot, "P")); - EXPECT_THAT(value, NodeValue("Pass")); -#ifndef DISABLE_HTTP_REDIRECTS_CHECKS - EXPECT_THAT( - scheduled_navigations_[main_frame_], - ElementsAre( - Reason(FrameScheduledNavigationReason::HTTP_HEADER_REFRESH), - Reason(FrameScheduledNavigationReason::HTTP_HEADER_REFRESH), - Reason(FrameScheduledNavigationReason::HTTP_HEADER_REFRESH))); - EXPECT_THAT(frames_[main_frame_].size(), Eq(4u)); -#endif // #ifndef DISABLE_HTTP_REDIRECTS_CHECKS - } -}; -HEADLESS_RENDER_BROWSERTEST(ServerRedirectChain); - -class ServerRedirectToFailure : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", - HttpRedirect(302, "http://www.example.com/1")); - interceptor_->InsertResponse( - "http://www.example.com/1", - HttpRedirect(301, "http://www.example.com/FAIL")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1", - "http://www.example.com/FAIL")); - } -}; -// TODO(crbug.com/861548): re-implement as DevTools protocol test. -DISABLED_HEADLESS_RENDER_BROWSERTEST(ServerRedirectToFailure); - -class ServerRedirectRelativeChain : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", - HttpRedirect(302, "http://www.mysite.com/1")); - interceptor_->InsertResponse("http://www.mysite.com/1", - HttpRedirect(301, "/2")); - interceptor_->InsertResponse("http://www.mysite.com/2", - HttpOk("<p>Pass</p>")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.mysite.com/1", - "http://www.mysite.com/2")); - const DOMNode* value = NextNode(dom_snapshot, FindTag(dom_snapshot, "P")); - EXPECT_THAT(value, NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(ServerRedirectRelativeChain); - -class MixedRedirectChain : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( - <html> - <head> - <meta http-equiv="refresh" content="0; url=http://www.example.com/1"/> - <title>Hello, World 0</title> - </head> - <body>http://www.example.com/</body> - </html> - )|")); - interceptor_->InsertResponse("http://www.example.com/1", HttpOk(R"|( - <html> - <head> - <title>Hello, World 1</title> - <script> - document.location='http://www.example.com/2'; - </script> - </head> - <body>http://www.example.com/1</body> - </html> - )|")); - interceptor_->InsertResponse("http://www.example.com/2", - HttpRedirect(302, "3")); - interceptor_->InsertResponse("http://www.example.com/3", - HttpRedirect(301, "http://www.example.com/4")); - interceptor_->InsertResponse("http://www.example.com/4", - HttpOk("<p>Pass</p>")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1", - "http://www.example.com/2", "http://www.example.com/3", - "http://www.example.com/4")); - const DOMNode* value = NextNode(dom_snapshot, FindTag(dom_snapshot, "P")); - EXPECT_THAT(value, NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(MixedRedirectChain); - -class FramesRedirectChain : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", - HttpRedirect(302, "http://www.example.com/1")); - interceptor_->InsertResponse("http://www.example.com/1", HttpOk(R"|( -<html> - <frameset> - <frame src="http://www.example.com/frameA/"> - <frame src="http://www.example.com/frameB/"> - </frameset> -</html> -)|")); - - // Frame A - interceptor_->InsertResponse("http://www.example.com/frameA/", HttpOk(R"|( -<html> - <head> - <script>document.location='http://www.example.com/frameA/1'</script> - </head> - <body>HELLO WORLD 1</body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/frameA/1", - HttpRedirect(301, "/frameA/2")); - interceptor_->InsertResponse("http://www.example.com/frameA/2", - HttpOk("<p>FRAME A</p>")); - - // Frame B - interceptor_->InsertResponse("http://www.example.com/frameB/", HttpOk(R"|( -<html> - <head><title>HELLO WORLD 2</title></head> - <body> - <iframe src="http://www.example.com/iframe/"></iframe> - </body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/iframe/", HttpOk(R"|( -<html> - <head> - <script>document.location='http://www.example.com/iframe/1'</script> - </head> - <body>HELLO WORLD 1</body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/iframe/1", - HttpRedirect(302, "/iframe/2")); - interceptor_->InsertResponse("http://www.example.com/iframe/2", - HttpRedirect(301, "3")); - interceptor_->InsertResponse("http://www.example.com/iframe/3", - HttpOk("<p>IFRAME B</p>")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - UnorderedElementsAre( - "http://www.example.com/", "http://www.example.com/1", - "http://www.example.com/frameA/", "http://www.example.com/frameA/1", - "http://www.example.com/frameA/2", "http://www.example.com/frameB/", - "http://www.example.com/iframe/", "http://www.example.com/iframe/1", - "http://www.example.com/iframe/2", - "http://www.example.com/iframe/3")); - auto dom = FindTags(dom_snapshot, "P"); - EXPECT_THAT(dom, ElementsAre(NodeName("P"), NodeName("P"))); - EXPECT_THAT(NextNode(dom_snapshot, dom[0]), NodeValue("FRAME A")); - EXPECT_THAT(NextNode(dom_snapshot, dom[1]), NodeValue("IFRAME B")); - - const page::Frame* main_frame = nullptr; - const page::Frame* a_frame = nullptr; - const page::Frame* b_frame = nullptr; - const page::Frame* i_frame = nullptr; - EXPECT_THAT(frames_.size(), Eq(4u)); - for (const auto& it : frames_) { - if (it.second.back()->GetUrl() == "http://www.example.com/1") - main_frame = it.second.back().get(); - else if (it.second.back()->GetUrl() == "http://www.example.com/frameA/2") - a_frame = it.second.back().get(); - else if (it.second.back()->GetUrl() == "http://www.example.com/frameB/") - b_frame = it.second.back().get(); - else if (it.second.back()->GetUrl() == "http://www.example.com/iframe/3") - i_frame = it.second.back().get(); - else - ADD_FAILURE() << "Unexpected frame URL: " << it.second.back()->GetUrl(); - } - -#ifndef DISABLE_HTTP_REDIRECTS_CHECKS - EXPECT_THAT(frames_[main_frame->GetId()].size(), Eq(2u)); - EXPECT_THAT(frames_[a_frame->GetId()].size(), Eq(3u)); - EXPECT_THAT(frames_[b_frame->GetId()].size(), Eq(1u)); - EXPECT_THAT(frames_[i_frame->GetId()].size(), Eq(4u)); - EXPECT_THAT(scheduled_navigations_[main_frame->GetId()], - ElementsAre(Reason( - FrameScheduledNavigationReason::HTTP_HEADER_REFRESH))); - EXPECT_THAT( - scheduled_navigations_[a_frame->GetId()], - ElementsAre( - Reason(FrameScheduledNavigationReason::SCRIPT_INITIATED), - Reason(FrameScheduledNavigationReason::HTTP_HEADER_REFRESH))); - EXPECT_THAT( - scheduled_navigations_[i_frame->GetId()], - ElementsAre( - Reason(FrameScheduledNavigationReason::SCRIPT_INITIATED), - Reason(FrameScheduledNavigationReason::HTTP_HEADER_REFRESH), - Reason(FrameScheduledNavigationReason::HTTP_HEADER_REFRESH))); -#endif // #ifndef DISABLE_HTTP_REDIRECTS_CHECKS - } -}; -HEADLESS_RENDER_BROWSERTEST(FramesRedirectChain); - -class DoubleRedirect : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html> - <head> - <title>Hello, World 1</title> - <script> - document.location='http://www.example.com/1'; - document.location='http://www.example.com/2'; - </script> - </head> - <body>http://www.example.com/1</body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/2", - HttpOk("<p>Pass</p>")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - // Two navigations have been scheduled while the document was loading... - EXPECT_THAT( - scheduled_navigations_[main_frame_], - ElementsAre(Reason(FrameScheduledNavigationReason::SCRIPT_INITIATED), - Reason(FrameScheduledNavigationReason::SCRIPT_INITIATED))); - // ..., but only the second one was started. It canceled the first one. - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/2")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - EXPECT_THAT(frames_[main_frame_].size(), Eq(2u)); - } -}; -HEADLESS_RENDER_BROWSERTEST(DoubleRedirect); - -class RedirectAfterCompletion : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html> - <head> - <meta http-equiv='refresh' content='120; url=http://www.example.com/1'> - </head> - <body><p>Pass</p></body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/1", - HttpOk("<p>Fail</p>")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - // While the document was loading, one navigation has been scheduled... - EXPECT_THAT( - scheduled_navigations_[main_frame_], - ElementsAre(Reason(FrameScheduledNavigationReason::META_TAG_REFRESH))); - // ..., but because of the timeout, it has not been started yet. - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://www.example.com/")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - EXPECT_THAT(frames_[main_frame_].size(), Eq(1u)); - } -}; -HEADLESS_RENDER_BROWSERTEST(RedirectAfterCompletion); - -class Redirect307PostMethod : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html> - <body onload='document.forms[0].submit();'> - <form action='1' method='post'> - <input name='foo' value='bar'> - </form> - </body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/1", - HttpRedirect(307, "/2")); - interceptor_->InsertResponse("http://www.example.com/2", - HttpOk("<p>Pass</p>")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1", - "http://www.example.com/2")); - EXPECT_THAT(interceptor_->methods_requested(), - ElementsAre("GET", "POST", "POST")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(Redirect307PostMethod); - -class RedirectPostChain : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html> - <body onload='document.forms[0].submit();'> - <form action='1' method='post'> - <input name='foo' value='bar'> - </form> - </body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/1", - HttpRedirect(307, "/2")); - interceptor_->InsertResponse("http://www.example.com/2", HttpOk(R"|( -<html> - <body onload='document.forms[0].submit();'> - <form action='3' method='post'> - </form> - </body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/3", - HttpRedirect(307, "/4")); - interceptor_->InsertResponse("http://www.example.com/4", - HttpOk("<p>Pass</p>")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1", - "http://www.example.com/2", "http://www.example.com/3", - "http://www.example.com/4")); - EXPECT_THAT(interceptor_->methods_requested(), - ElementsAre("GET", "POST", "POST", "POST", "POST")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(RedirectPostChain); - -class Redirect307PutMethod : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( - <html> - <head> - <script> - function doPut() { - var xhr = new XMLHttpRequest(); - xhr.open('PUT', 'http://www.example.com/1'); - xhr.setRequestHeader('Content-Type', 'text/plain'); - xhr.addEventListener('load', function() { - document.getElementById('content').textContent = this.responseText; - }); - xhr.send('some data'); - } - </script> - </head> - <body onload='doPut();'> - <p id="content"></p> - </body> - </html> - )|")); - interceptor_->InsertResponse("http://www.example.com/1", - HttpRedirect(307, "/2")); - interceptor_->InsertResponse("http://www.example.com/2", - {"Pass", "text/plain"}); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1", - "http://www.example.com/2")); - EXPECT_THAT(interceptor_->methods_requested(), - ElementsAre("GET", "PUT", "PUT")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(Redirect307PutMethod); - -class Redirect303PutGet : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html> - <head> - <script> - function doPut() { - var xhr = new XMLHttpRequest(); - xhr.open('PUT', 'http://www.example.com/1'); - xhr.setRequestHeader('Content-Type', 'text/plain'); - xhr.addEventListener('load', function() { - document.getElementById('content').textContent = this.responseText; - }); - xhr.send('some data'); - } - </script> - </head> - <body onload='doPut();'> - <p id="content"></p> - </body> -</html> -)|")); - interceptor_->InsertResponse("http://www.example.com/1", - HttpRedirect(303, "/2")); - interceptor_->InsertResponse("http://www.example.com/2", - {"Pass", "text/plain"}); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1", - "http://www.example.com/2")); - EXPECT_THAT(interceptor_->methods_requested(), - ElementsAre("GET", "PUT", "GET")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(Redirect303PutGet); - -class RedirectBaseUrl : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://foo.com/", - HttpRedirect(302, "http://bar.com/")); - interceptor_->InsertResponse("http://bar.com/", - HttpOk("<img src=\"pass\">")); - return GURL("http://foo.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://foo.com/", "http://bar.com/", - "http://bar.com/pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(RedirectBaseUrl); - -class RedirectNonAsciiUrl : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - // "䏿–‡" is 0xE4 0xB8 0xAD, 0xE6 0x96 0x87 - interceptor_->InsertResponse( - "http://www.example.com/", - HttpRedirect(302, "http://www.example.com/䏿–‡")); - interceptor_->InsertResponse( - "http://www.example.com/%E4%B8%AD%E6%96%87", - HttpRedirect(303, "http://www.example.com/pass#䏿–‡")); - interceptor_->InsertResponse( - "http://www.example.com/pass#%E4%B8%AD%E6%96%87", - HttpOk("<p>Pass</p>")); - interceptor_->InsertResponse( - "http://www.example.com/%C3%A4%C2%B8%C2%AD%C3%A6%C2%96%C2%87", - {"HTTP/1.1 500 Bad Response\r\nContent-Type: text/html\r\n\r\nFail"}); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", - "http://www.example.com/%E4%B8%AD%E6%96%87", - "http://www.example.com/pass#%E4%B8%AD%E6%96%87")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(RedirectNonAsciiUrl); - -class RedirectEmptyUrl : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse( - "http://www.example.com/", - {"HTTP/1.1 302 Found\r\nLocation: \r\nContent-Type: " - "text/html\r\n\r\n<!DOCTYPE html><p>Pass</p>"}); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://www.example.com/")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(RedirectEmptyUrl); - -class RedirectInvalidUrl : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse( - "http://www.example.com/", - {"HTTP/1.1 302 Found\r\nLocation: http://\r\n\r\n" - "<!DOCTYPE html><p>Pass</p>"}); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://www.example.com/")); - } -}; -// TODO(crbug.com/861548): re-implement as DevTools protocol test. -DISABLED_HEADLESS_RENDER_BROWSERTEST(RedirectInvalidUrl); - -class RedirectKeepsFragment : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/#foo", - HttpRedirect(302, "/1")); - interceptor_->InsertResponse("http://www.example.com/1#foo", - HttpRedirect(302, "/2")); - interceptor_->InsertResponse("http://www.example.com/2#foo", HttpOk(R"|( -<body> - <p id="content"></p> - <script> - document.getElementById('content').textContent = window.location.href; - </script> -</body> -)|")); - return GURL("http://www.example.com/#foo"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://www.example.com/#foo", - "http://www.example.com/1#foo", - "http://www.example.com/2#foo")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("http://www.example.com/2#foo")); - } -}; -HEADLESS_RENDER_BROWSERTEST(RedirectKeepsFragment); - -class RedirectReplacesFragment : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/#foo", - HttpRedirect(302, "/1#bar")); - interceptor_->InsertResponse("http://www.example.com/1#bar", - HttpRedirect(302, "/2")); - interceptor_->InsertResponse("http://www.example.com/2#bar", HttpOk(R"|( -<body> - <p id="content"></p> - <script> - document.getElementById('content').textContent = window.location.href; - </script> -</body> -)|")); - return GURL("http://www.example.com/#foo"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://www.example.com/#foo", - "http://www.example.com/1#bar", - "http://www.example.com/2#bar")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("http://www.example.com/2#bar")); - } -}; -// TODO(crbug.com/861548): re-implement as DevTools protocol test. -DISABLED_HEADLESS_RENDER_BROWSERTEST(RedirectReplacesFragment); - -class RedirectNewFragment : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", - HttpRedirect(302, "/1#foo")); - interceptor_->InsertResponse("http://www.example.com/1#foo", - HttpRedirect(302, "/2")); - interceptor_->InsertResponse("http://www.example.com/2#foo", HttpOk(R"|( -<body> - <p id="content"></p> - <script> - document.getElementById('content').textContent = window.location.href; - </script> -</body> -)|")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT( - interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", "http://www.example.com/1#foo", - "http://www.example.com/2#foo")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("http://www.example.com/2#foo")); - } -}; -// TODO(https://crbug.com/839747): Re-implement as DevTools protocol test. -DISABLED_HEADLESS_RENDER_BROWSERTEST(RedirectNewFragment); - -class WindowLocationFragments : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/#fragment1", - HttpOk(R"|( - <script> - if (window.location.hash == '#fragment1') { - document.write('<iframe src="iframe#fragment2"></iframe>'); - } - </script>)|")); - interceptor_->InsertResponse("http://www.example.com/iframe#fragment2", - HttpOk(R"|( - <script> - if (window.location.hash == '#fragment2') { - document.location = 'http://www.example.com/pass'; - } - </script>)|")); - interceptor_->InsertResponse("http://www.example.com/pass", - HttpOk("<p>Pass</p>")); - return GURL("http://www.example.com/#fragment1"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://www.example.com/#fragment1", - "http://www.example.com/iframe#fragment2", - "http://www.example.com/pass")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(WindowLocationFragments); - -class CookieSetFromJs : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html><head><script> -document.cookie = 'SessionID=123'; -n = document.cookie.indexOf('SessionID'); -if (n < 0) { - top.location = '/epicfail'; -} -</script></head><body>Pass</body></html>)|")); - return GURL("http://www.example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://www.example.com/")); - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "BODY")), - NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(CookieSetFromJs); - -class CookieSetFromJs_NoCookies : public CookieSetFromJs { - private: - void OverrideWebPreferences(WebPreferences* preferences) override { - HeadlessRenderTest::OverrideWebPreferences(preferences); - preferences->cookie_enabled = false; - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(interceptor_->urls_requested(), - ElementsAre("http://www.example.com/", - "http://www.example.com/epicfail")); - } -}; - -// Flaky on Linux. https://crbug.com/839747 -#if defined(OS_LINUX) -DISABLED_HEADLESS_RENDER_BROWSERTEST(CookieSetFromJs_NoCookies); -#else -HEADLESS_RENDER_BROWSERTEST(CookieSetFromJs_NoCookies); -#endif - -class CookieUpdatedFromJs : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - client->GetNetwork()->SetCookie(network::SetCookieParams::Builder() - .SetUrl("http://www.example.com/") - .SetName("foo") - .SetValue("bar") - .Build()); - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html><head><script> -var x = document.cookie; -document.cookie = x + 'baz'; -</script></head><body>Pass</body></html>)|")); - return GURL("http://www.example.com/"); - } - - void OnPageRenderCompleted() override { - devtools_client_->GetNetwork()->GetCookies( - network::GetCookiesParams::Builder() - .SetUrls({"http://www.example.com/"}) - .Build(), - base::BindOnce(&CookieUpdatedFromJs::OnGetCookies, - base::Unretained(this))); - } - - void OnGetCookies(std::unique_ptr<network::GetCookiesResult> result) { - const auto& cookies = *result->GetCookies(); - EXPECT_THAT(cookies, ElementsAre(CookieValue("barbaz"))); - HeadlessRenderTest::OnPageRenderCompleted(); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "BODY")), - NodeValue("Pass")); - } -}; -HEADLESS_RENDER_BROWSERTEST(CookieUpdatedFromJs); - -class InCrossOriginObject : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://foo.com/", HttpOk(R"|( - <html><body> - <iframe id='myframe' src='http://bar.com/'></iframe> - <script> - window.onload = function() { - try { - var a = 0 in document.getElementById('myframe').contentWindow; - } catch (e) { - console.log(e.message); - } - }; - </script><p>Pass</p></body></html>)|")); - interceptor_->InsertResponse("http://bar.com/", - HttpOk(R"|(<html></html>)|")); - return GURL("http://foo.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")), - NodeValue("Pass")); - EXPECT_THAT(console_log_, - ElementsAre(StartsWith("L Blocked a frame with origin " - "\"http://foo.com\" from accessing"))); - } -}; -HEADLESS_RENDER_BROWSERTEST(InCrossOriginObject); - -class ContentSecurityPolicy : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - // Only first 3 scripts of 4 on the page are whitelisted for execution. - // Therefore only 3 lines in the log are expected. - interceptor_->InsertResponse( - "http://example.com/", - {"HTTP/1.1 200 OK\r\n" - "Content-Type: text/html\r\n" - "Content-Security-Policy: script-src" - " 'sha256-INSsCHXoo4K3+jDRF8FSvl13GP22I9vcqcJjkq35Y20='" - " 'sha384-77lSn5Q6V979pJ8W2TXc6Lrj98LughR0ofkFwa+" - "qOEtlcofEdLPkOPtpJF8QQMev'" - " 'sha512-" - "2cS3KZwfnxFo6lvBvAl113f5N3QCRgtRJBbtFaQHKOhk36sdYYKFvhCqGTvbN7pBKUfsj" - "fCQgFF4MSbCQuvT8A=='\r\n\r\n" - "<!DOCTYPE html>\n" - "<script>console.log('pass256');</script>\n" - "<script>console.log('pass384');</script>\n" - "<script>console.log('pass512');</script>\n" - "<script>console.log('fail');</script>"}); - // For example, regenerate sha256 hash with: - // echo -n "console.log('pass256');" \ - // | openssl sha256 -binary \ - // | openssl base64 - return GURL("http://example.com/"); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - EXPECT_THAT(console_log_, - ElementsAre("L pass256", "L pass384", "L pass512")); - } -}; -HEADLESS_RENDER_BROWSERTEST(ContentSecurityPolicy); - -class FrameLoadEvents : public HeadlessRenderTest { - private: - std::map<std::string, std::string> frame_navigated_; - std::map<std::string, std::string> frame_scheduled_; - - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://example.com/", - HttpRedirect(302, "http://example.com/1")); - - interceptor_->InsertResponse("http://example.com/1", HttpOk(R"|( -<html><frameset> - <frame src="http://example.com/frameA/" id="frameA"> - <frame src="http://example.com/frameB/" id="frameB"> -</frameset></html> -)|")); - - interceptor_->InsertResponse("http://example.com/frameA/", HttpOk(R"|( -<html><head><script> - document.location="http://example.com/frameA/1" -</script></head></html> -)|")); - - interceptor_->InsertResponse("http://example.com/frameB/", HttpOk(R"|( -<html><head><script> - document.location="http://example.com/frameB/1" -</script></head></html> -)|")); - - interceptor_->InsertResponse("http://example.com/frameA/1", - HttpOk("<html><body>FRAME A 1</body></html>")); - - interceptor_->InsertResponse("http://example.com/frameB/1", HttpOk(R"|( -<html><body>FRAME B 1 - <iframe src="http://example.com/frameB/1/iframe/" id="iframe"></iframe> -</body></html> -)|")); - - interceptor_->InsertResponse("http://example.com/frameB/1/iframe/", - HttpOk(R"|( -<html><head><script> - document.location="http://example.com/frameB/1/iframe/1" -</script></head></html> -)|")); - - interceptor_->InsertResponse("http://example.com/frameB/1/iframe/1", - HttpOk("<html><body>IFRAME 1</body><html>")); - - return GURL("http://example.com/"); - } - - void OnFrameNavigated(const page::FrameNavigatedParams& params) override { - frame_navigated_.insert(std::make_pair(params.GetFrame()->GetId(), - params.GetFrame()->GetUrl())); - HeadlessRenderTest::OnFrameNavigated(params); - } - - void OnFrameScheduledNavigation( - const page::FrameScheduledNavigationParams& params) override { - frame_scheduled_.insert( - std::make_pair(params.GetFrameId(), params.GetUrl())); - HeadlessRenderTest::OnFrameScheduledNavigation(params); - } - - void VerifyDom(GetSnapshotResult* dom_snapshot) override { - std::vector<std::string> urls; - for (const auto& kv : frame_navigated_) { - urls.push_back(kv.second); - } - EXPECT_THAT(urls, UnorderedElementsAre( - "http://example.com/1", "http://example.com/frameA/", - "http://example.com/frameB/", - "http://example.com/frameB/1/iframe/")); - urls.clear(); - for (const auto& kv : frame_scheduled_) { - urls.push_back(kv.second); - } - EXPECT_THAT(urls, - UnorderedElementsAre("http://example.com/frameA/1", - "http://example.com/frameB/1", - "http://example.com/frameB/1/iframe/1")); - } -}; -HEADLESS_RENDER_BROWSERTEST(FrameLoadEvents); - -class CustomFont : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html> - <head> - <style> - @font-face { - font-family: testfont; - src: url("font.ttf"); - } - span.test { - font-family: testfont; - font-size: 200px; - } - </style> - </head> - <body> - <span class="test">Hello</span> - </body> -</html> -)|")); - interceptor_->InsertResponse( - "http://www.example.com/font.ttf", - ResponseFromFile("font.ttf", kApplicationOctetStream)); - return GURL("http://www.example.com/"); - } - - base::Optional<ScreenshotOptions> GetScreenshotOptions() override { - return ScreenshotOptions("custom_font.png", 0, 0, 500, 250, 1); - } -}; -HEADLESS_RENDER_BROWSERTEST(CustomFont); - -// Ensures that "filter: url(...)" does not get into an infinite style update -// loop. -class CssUrlFilter : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - // The image from circle.svg will be drawn with the blur from blur.svg. - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<!DOCTYPE html> -<style> -body { margin: 0; } -img { - -webkit-filter: url(blur.svg#blur); - filter: url(blur.svg#blur); -} -</style> -<img src="circle.svg"> -)|")); - - // Just a normal image. - interceptor_->InsertResponse("http://www.example.com/circle.svg", - HttpOk(R"|( -<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink"> -<circle cx="50" cy="50" r="50" fill="green" /> -</svg> -)|", - kImageSvgXml)); - - // A blur filter stored inside an svg file. - interceptor_->InsertResponse("http://www.example.com/blur.svg#blur", - HttpOk(R"|( -<svg version="1.1" xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink"> - <filter id="blur"> - <feGaussianBlur in="SourceGraphic" stdDeviation="5"/> - </filter> -</svg> -)|", - kImageSvgXml)); - - return GURL("http://www.example.com/"); - } - - base::Optional<ScreenshotOptions> GetScreenshotOptions() override { - return ScreenshotOptions("css_url_filter.png", 0, 0, 100, 100, 1); - } -}; -HEADLESS_RENDER_BROWSERTEST(CssUrlFilter); - -// Ensures that a number of SVGs features render correctly. -class SvgExamples : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse( - "http://www.example.com/", - ResponseFromFile("svg_examples.svg", kImageSvgXml)); - interceptor_->InsertResponse( - "http://www.example.com/svg_example_image.png", - ResponseFromFile("svg_example_image.png", kImagePng)); - - return GURL("http://www.example.com/"); - } - - base::Optional<ScreenshotOptions> GetScreenshotOptions() override { - return ScreenshotOptions("svg_examples.png", 0, 0, 400, 600, 1); - } -}; -#if defined(OS_LINUX) && defined(ARCH_CPU_X86) && !defined(NDEBUG) -// https://crbug.com/859325 -DISABLED_HEADLESS_RENDER_BROWSERTEST(SvgExamples); -#else -HEADLESS_RENDER_BROWSERTEST(SvgExamples); -#endif - -// Ensures that basic <canvas> painting is supported. -class Canvas : public HeadlessRenderTest { - private: - GURL GetPageUrl(HeadlessDevToolsClient* client) override { - interceptor_->InsertResponse("http://www.example.com/", HttpOk(R"|( -<html> - <body> - <canvas id="test_canvas" width="200" height="200" - style="position:absolute;left:0px;top:0px"> - Oops! Canvas not supported! - </canvas> - <script> - var context = document.getElementById("test_canvas"). - getContext("2d"); - context.fillStyle = "rgb(255,0,0)"; - context.fillRect(30, 30, 50, 50); - </script> - </body> -</html> -)|")); - - return GURL("http://www.example.com/"); - } - - base::Optional<ScreenshotOptions> GetScreenshotOptions() override { - return ScreenshotOptions("canvas.png", 0, 0, 200, 200, 1); - } -}; -HEADLESS_RENDER_BROWSERTEST(Canvas); - -} // namespace headless
diff --git a/headless/test/headless_render_test.cc b/headless/test/headless_render_test.cc deleted file mode 100644 index 171f6f1b..0000000 --- a/headless/test/headless_render_test.cc +++ /dev/null
@@ -1,514 +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. - -#include "headless/test/headless_render_test.h" - -#include "base/base_paths.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "base/threading/thread_restrictions.h" -#include "cc/base/switches.h" -#include "components/viz/common/features.h" -#include "components/viz/common/switches.h" -#include "content/public/common/content_switches.h" -#include "headless/public/devtools/domains/dom_snapshot.h" -#include "headless/public/headless_devtools_client.h" -#include "headless/public/util/compositor_controller.h" -#include "headless/public/util/virtual_time_controller.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/codec/png_codec.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/skia_util.h" - -namespace headless { - -namespace { - -static constexpr int kAnimationIntervalMs = 100; -static constexpr bool kUpdateDisplayForAnimations = false; -static const char kUpdateGoldens[] = "update-goldens"; - -void SetVirtualTimePolicyDoneCallback( - base::RunLoop* run_loop, - std::unique_ptr<emulation::SetVirtualTimePolicyResult>) { - run_loop->Quit(); -} - -bool DecodePNG(const std::string& data, SkBitmap* bitmap) { - return gfx::PNGCodec::Decode( - reinterpret_cast<unsigned const char*>(data.data()), data.size(), bitmap); -} - -bool ColorsMatchWithinLimit(SkColor color1, SkColor color2, int error_limit) { - auto a_diff = static_cast<int>(SkColorGetA(color1)) - - static_cast<int>(SkColorGetA(color2)); - auto r_diff = static_cast<int>(SkColorGetR(color1)) - - static_cast<int>(SkColorGetR(color2)); - auto g_diff = static_cast<int>(SkColorGetG(color1)) - - static_cast<int>(SkColorGetG(color2)); - auto b_diff = static_cast<int>(SkColorGetB(color1)) - - static_cast<int>(SkColorGetB(color2)); - return a_diff * a_diff + r_diff * r_diff + g_diff * g_diff + - b_diff * b_diff <= - error_limit * error_limit; -} - -bool MatchesBitmap(const SkBitmap& expected_bmp, - const SkBitmap& actual_bmp, - int error_limit) { - // Number of pixels with an error - int error_pixels_count = 0; - gfx::Rect error_bounding_rect = gfx::Rect(); - - // Check that bitmaps have identical dimensions. - EXPECT_EQ(expected_bmp.width(), actual_bmp.width()); - EXPECT_EQ(expected_bmp.height(), actual_bmp.height()); - if (expected_bmp.width() != actual_bmp.width() || - expected_bmp.height() != actual_bmp.height()) { - LOG(ERROR) << "To update goldens, use --update-goldens."; - return false; - } - - for (int y = 0; y < actual_bmp.height(); ++y) { - for (int x = 0; x < actual_bmp.width(); ++x) { - SkColor actual_color = actual_bmp.getColor(x, y); - SkColor expected_color = expected_bmp.getColor(x, y); - if (!ColorsMatchWithinLimit(actual_color, expected_color, error_limit)) { - if (error_pixels_count < 10) { - LOG(ERROR) << "Pixel (" << x << "," << y << "): expected " << std::hex - << expected_color << " actual " << actual_color; - } - error_pixels_count++; - error_bounding_rect.Union(gfx::Rect(x, y, 1, 1)); - } - } - } - - if (error_pixels_count != 0) { - LOG(ERROR) << "Number of pixel with an error: " << error_pixels_count; - LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString(); - LOG(ERROR) << "To update goldens, use --update-goldens."; - return false; - } - - return true; -} - -bool WriteStringToFile(const base::FilePath& file_path, - const std::string& content) { - int result = base::WriteFile(file_path, content.data(), - static_cast<int>(content.size())); - return content.size() == static_cast<size_t>(result); -} - -bool ScreenshotMatchesGolden(const std::string& screenshot_data, - const std::string& golden_file_name) { - static const base::FilePath kGoldenDirectory( - FILE_PATH_LITERAL("headless/test/data/golden")); - - SkBitmap actual_bitmap; - EXPECT_TRUE(DecodePNG(screenshot_data, &actual_bitmap)); - if (actual_bitmap.empty()) - return false; - - base::ScopedAllowBlockingForTesting allow_blocking; - - base::FilePath src_dir; - CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_dir)); - base::FilePath golden_path = - src_dir.Append(kGoldenDirectory).Append(golden_file_name); - - if (base::CommandLine::ForCurrentProcess()->HasSwitch(kUpdateGoldens)) { - LOG(INFO) << "Updating golden file at " << golden_path; - CHECK(WriteStringToFile(golden_path, screenshot_data)); - } - - std::string golden_data; - CHECK(base::ReadFileToString(golden_path, &golden_data)); - - SkBitmap expected_bitmap; - EXPECT_TRUE(DecodePNG(golden_data, &expected_bitmap)); - if (expected_bitmap.empty()) - return false; - - return MatchesBitmap(expected_bitmap, actual_bitmap, 5); -} - -} // namespace - -HeadlessRenderTest::HeadlessRenderTest() : weak_ptr_factory_(this) {} - -HeadlessRenderTest::~HeadlessRenderTest() = default; - -void HeadlessRenderTest::PostRunAsynchronousTest() { - // Make sure the test did complete. - EXPECT_EQ(FINISHED, state_) << "The test did not finish."; -} - -class HeadlessRenderTest::AdditionalVirtualTimeBudget - : public VirtualTimeController::RepeatingTask, - public VirtualTimeController::Observer { - public: - AdditionalVirtualTimeBudget(VirtualTimeController* virtual_time_controller, - HeadlessRenderTest* test, - base::RunLoop* run_loop, - int budget_ms) - : RepeatingTask(StartPolicy::WAIT_FOR_NAVIGATION, 0), - virtual_time_controller_(virtual_time_controller), - test_(test), - run_loop_(run_loop) { - virtual_time_controller_->ScheduleRepeatingTask( - this, base::TimeDelta::FromMilliseconds(budget_ms)); - virtual_time_controller_->AddObserver(this); - virtual_time_controller_->StartVirtualTime(); - } - - ~AdditionalVirtualTimeBudget() override { - virtual_time_controller_->RemoveObserver(this); - virtual_time_controller_->CancelRepeatingTask(this); - } - - // headless::VirtualTimeController::RepeatingTask implementation: - void IntervalElapsed( - base::TimeDelta virtual_time, - base::OnceCallback<void(ContinuePolicy)> continue_callback) override { - std::move(continue_callback).Run(ContinuePolicy::NOT_REQUIRED); - } - - // headless::VirtualTimeController::Observer: - void VirtualTimeStarted(base::TimeDelta virtual_time_offset) override { - run_loop_->Quit(); - } - - void VirtualTimeStopped(base::TimeDelta virtual_time_offset) override { - test_->HandleVirtualTimeExhausted(); - delete this; - } - - private: - headless::VirtualTimeController* const virtual_time_controller_; - HeadlessRenderTest* test_; - base::RunLoop* run_loop_; -}; - -void HeadlessRenderTest::RunDevTooledTest() { - virtual_time_controller_ = - std::make_unique<VirtualTimeController>(devtools_client_.get()); - - SetDeviceMetricsOverride(headless::page::Viewport::Builder() - .SetX(0) - .SetY(0) - .SetWidth(1) - .SetHeight(1) - .SetScale(1) - .Build()); - - compositor_controller_ = std::make_unique<CompositorController>( - browser()->BrowserMainThread(), devtools_client_.get(), - virtual_time_controller_.get(), - base::TimeDelta::FromMilliseconds(kAnimationIntervalMs), - kUpdateDisplayForAnimations); - - devtools_client_->GetPage()->GetExperimental()->AddObserver(this); - devtools_client_->GetPage()->Enable(Sync()); - devtools_client_->GetRuntime()->GetExperimental()->AddObserver(this); - devtools_client_->GetRuntime()->Enable(Sync()); - - GURL url = GetPageUrl(devtools_client_.get()); - - // Pause virtual time until we actually start loading content. - { - base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( - emulation::SetVirtualTimePolicyParams::Builder() - .SetPolicy(emulation::VirtualTimePolicy::PAUSE) - .Build()); - devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( - emulation::SetVirtualTimePolicyParams::Builder() - .SetPolicy( - emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING) - .SetBudget(4001) - .SetWaitForNavigation(true) - .Build(), - base::BindOnce(&SetVirtualTimePolicyDoneCallback, &run_loop)); - - run_loop.Run(); - } - - { - base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - // Note AdditionalVirtualTimeBudget will self delete. - new AdditionalVirtualTimeBudget(virtual_time_controller_.get(), this, - &run_loop, 5000); - run_loop.Run(); - } - - state_ = STARTING; - devtools_client_->GetPage()->Navigate(url.spec()); - browser()->BrowserMainThread()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&HeadlessRenderTest::HandleTimeout, - weak_ptr_factory_.GetWeakPtr()), - base::TimeDelta::FromSeconds(10)); - - // The caller will loop until FinishAsynchronousTest() is called either - // from OnGetDomSnapshotDone() or from HandleTimeout(). -} - -void HeadlessRenderTest::SetDeviceMetricsOverride( - std::unique_ptr<headless::page::Viewport> viewport) { - gfx::Size size = GetEmulatedWindowSize(); - devtools_client_->GetEmulation()->GetExperimental()->SetDeviceMetricsOverride( - headless::emulation::SetDeviceMetricsOverrideParams::Builder() - .SetDeviceScaleFactor(0) - .SetMobile(false) - .SetWidth(size.width()) - .SetHeight(size.height()) - .SetScreenWidth(size.width()) - .SetScreenHeight(size.height()) - .SetViewport(std::move(viewport)) - .Build(), - Sync()); -} - -void HeadlessRenderTest::OnTimeout() { - ADD_FAILURE() << "Rendering timed out!"; -} - -void HeadlessRenderTest::SetUpCommandLine(base::CommandLine* command_line) { - HeadlessAsyncDevTooledBrowserTest::SetUpCommandLine(command_line); - // See bit.ly/headless-rendering for why we use these flags. - command_line->AppendSwitch(switches::kRunAllCompositorStagesBeforeDraw); - command_line->AppendSwitch(switches::kDisableNewContentRenderingTimeout); - command_line->AppendSwitch(cc::switches::kDisableCheckerImaging); - command_line->AppendSwitch(cc::switches::kDisableThreadedAnimation); - command_line->AppendSwitch(switches::kDisableImageAnimationResync); - command_line->AppendSwitch(switches::kDisableThreadedScrolling); - - scoped_feature_list_.InitAndEnableFeature( - features::kEnableSurfaceSynchronization); -} - -void HeadlessRenderTest::SetUp() { - EnablePixelOutput(); - HeadlessAsyncDevTooledBrowserTest::SetUp(); -} - -void HeadlessRenderTest::CustomizeHeadlessBrowserContext( - HeadlessBrowserContext::Builder& builder) { - builder.SetOverrideWebPreferencesCallback( - base::Bind(&HeadlessRenderTest::OverrideWebPreferences, - weak_ptr_factory_.GetWeakPtr())); -} - -bool HeadlessRenderTest::GetEnableBeginFrameControl() { - return true; -} - -void HeadlessRenderTest::OverrideWebPreferences(WebPreferences* preferences) { - preferences->hide_scrollbars = true; - preferences->javascript_enabled = true; - preferences->autoplay_policy = content::AutoplayPolicy::kUserGestureRequired; -} - -base::Optional<HeadlessRenderTest::ScreenshotOptions> -HeadlessRenderTest::GetScreenshotOptions() { - return base::nullopt; -} - -gfx::Size HeadlessRenderTest::GetEmulatedWindowSize() { - return gfx::Size(800, 600); -} - -void HeadlessRenderTest::OnLoadEventFired(const page::LoadEventFiredParams&) { - CHECK_NE(INIT, state_); - if (state_ == LOADING || state_ == STARTING) { - state_ = RENDERING; - } -} - -void HeadlessRenderTest::OnFrameStartedLoading( - const page::FrameStartedLoadingParams& params) { - CHECK_NE(INIT, state_); - if (state_ == STARTING) { - state_ = LOADING; - main_frame_ = params.GetFrameId(); - } -} - -void HeadlessRenderTest::OnFrameScheduledNavigation( - const page::FrameScheduledNavigationParams& params) { - scheduled_navigations_[params.GetFrameId()].emplace_back( - Navigation{params.GetUrl(), params.GetReason()}); -} - -void HeadlessRenderTest::OnFrameNavigated( - const page::FrameNavigatedParams& params) { - frames_[params.GetFrame()->GetId()].push_back(params.GetFrame()->Clone()); -} - -void HeadlessRenderTest::OnConsoleAPICalled( - const runtime::ConsoleAPICalledParams& params) { - std::stringstream str; - switch (params.GetType()) { - case runtime::ConsoleAPICalledType::WARNING: - str << "W"; - break; - case runtime::ConsoleAPICalledType::ASSERT: - case runtime::ConsoleAPICalledType::ERR: - str << "E"; - break; - case runtime::ConsoleAPICalledType::DEBUG: - str << "D"; - break; - case runtime::ConsoleAPICalledType::INFO: - str << "I"; - break; - default: - str << "L"; - break; - } - const auto& args = *params.GetArgs(); - for (const auto& arg : args) { - str << " "; - if (arg->HasDescription()) { - str << arg->GetDescription(); - } else if (arg->GetType() == runtime::RemoteObjectType::UNDEFINED) { - str << "undefined"; - } else if (arg->HasValue()) { - const base::Value* v = arg->GetValue(); - switch (v->type()) { - case base::Value::Type::NONE: - str << "null"; - break; - case base::Value::Type::BOOLEAN: - str << v->GetBool(); - break; - case base::Value::Type::INTEGER: - str << v->GetInt(); - break; - case base::Value::Type::DOUBLE: - str << v->GetDouble(); - break; - case base::Value::Type::STRING: - str << v->GetString(); - break; - default: - DCHECK(false); - break; - } - } else { - DCHECK(false); - } - } - console_log_.push_back(str.str()); -} - -void HeadlessRenderTest::OnExceptionThrown( - const runtime::ExceptionThrownParams& params) { - const runtime::ExceptionDetails* details = params.GetExceptionDetails(); - js_exceptions_.push_back(details->GetText() + " " + - details->GetException()->GetDescription()); -} - -void HeadlessRenderTest::VerifyDom( - dom_snapshot::GetSnapshotResult* dom_snapshot) {} - -void HeadlessRenderTest::OnPageRenderCompleted() { - CHECK_GE(state_, LOADING); - if (state_ >= DONE) - return; - state_ = DONE; - - devtools_client_->GetDOMSnapshot()->GetExperimental()->GetSnapshot( - dom_snapshot::GetSnapshotParams::Builder() - .SetComputedStyleWhitelist(std::vector<std::string>()) - .Build(), - base::BindOnce(&HeadlessRenderTest::OnGetDomSnapshotDone, - weak_ptr_factory_.GetWeakPtr())); -} - -void HeadlessRenderTest::HandleVirtualTimeExhausted() { - if (state_ < DONE) { - OnPageRenderCompleted(); - } -} - -void HeadlessRenderTest::OnGetDomSnapshotDone( - std::unique_ptr<dom_snapshot::GetSnapshotResult> result) { - CHECK_EQ(DONE, state_); - VerifyDom(result.get()); - - base::Optional<ScreenshotOptions> screenshot_options = GetScreenshotOptions(); - if (screenshot_options) { - state_ = SCREENSHOT; - CaptureScreenshot(*screenshot_options); - return; - } - RenderComplete(); -} - -void HeadlessRenderTest::CaptureScreenshot(const ScreenshotOptions& options) { - // Set up emulation according to options. - auto clip = headless::page::Viewport::Builder() - .SetX(options.x) - .SetY(options.y) - .SetWidth(options.width) - .SetHeight(options.height) - .SetScale(options.scale) - .Build(); - - SetDeviceMetricsOverride(std::move(clip)); - - compositor_controller_->CaptureScreenshot( - CompositorController::ScreenshotParamsFormat::PNG, 100, - base::BindRepeating(&HeadlessRenderTest::ScreenshotCaptured, - base::Unretained(this), options)); -} - -void HeadlessRenderTest::ScreenshotCaptured(const ScreenshotOptions& options, - const std::string& data) { - EXPECT_TRUE(ScreenshotMatchesGolden(data, options.golden_file_name)); - RenderComplete(); -} - -void HeadlessRenderTest::RenderComplete() { - state_ = FINISHED; - CleanUp(); - FinishAsynchronousTest(); -} - -void HeadlessRenderTest::HandleTimeout() { - if (state_ != FINISHED) { - CleanUp(); - FinishAsynchronousTest(); - OnTimeout(); - } -} - -void HeadlessRenderTest::CleanUp() { - devtools_client_->GetRuntime()->Disable(Sync()); - devtools_client_->GetRuntime()->GetExperimental()->RemoveObserver(this); - devtools_client_->GetPage()->Disable(Sync()); - devtools_client_->GetPage()->GetExperimental()->RemoveObserver(this); -} - -HeadlessRenderTest::ScreenshotOptions::ScreenshotOptions( - const std::string& golden_file_name, - int x, - int y, - int width, - int height, - double scale) - : golden_file_name(golden_file_name), - x(x), - y(y), - width(width), - height(height), - scale(scale) {} - -} // namespace headless
diff --git a/headless/test/headless_render_test.h b/headless/test/headless_render_test.h deleted file mode 100644 index c9bd2827..0000000 --- a/headless/test/headless_render_test.h +++ /dev/null
@@ -1,176 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef HEADLESS_TEST_HEADLESS_RENDER_TEST_H_ -#define HEADLESS_TEST_HEADLESS_RENDER_TEST_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/message_loop/message_loop_current.h" -#include "base/optional.h" -#include "base/run_loop.h" -#include "base/test/scoped_feature_list.h" -#include "headless/public/devtools/domains/emulation.h" -#include "headless/public/devtools/domains/page.h" -#include "headless/public/devtools/domains/runtime.h" -#include "headless/public/headless_browser.h" -#include "headless/public/headless_browser_context.h" -#include "headless/test/headless_browser_test.h" -#include "ui/gfx/geometry/size.h" -#include "url/gurl.h" - -namespace headless { -class CompositorController; -class HeadlessDevToolsClient; -class VirtualTimeController; -namespace dom_snapshot { -class GetSnapshotResult; -} // namespace dom_snapshot - -// Base class for tests that render a particular page and verify the output. -class HeadlessRenderTest : public HeadlessAsyncDevTooledBrowserTest, - public page::ExperimentalObserver, - public runtime::ExperimentalObserver { - public: - struct Navigation { - std::string url; - page::FrameScheduledNavigationReason reason; - }; - - void RunDevTooledTest() override; - - protected: - // Automatically waits in destructor until callback is called. - class Sync { - public: - Sync() {} - ~Sync() { - base::MessageLoopCurrent::ScopedNestableTaskAllower nest_loop; - run_loop.Run(); - } - operator base::OnceClosure() { return run_loop.QuitClosure(); } - - private: - base::RunLoop run_loop; - DISALLOW_COPY_AND_ASSIGN(Sync); - }; - - struct ScreenshotOptions { - ScreenshotOptions(const std::string& golden_file_name, - int x, - int y, - int width, - int height, - double scale); - - std::string golden_file_name; - int x; - int y; - int width; - int height; - double scale; - }; - - HeadlessRenderTest(); - ~HeadlessRenderTest() override; - - // Marks that the test case reached the final conclusion. - void SetTestCompleted() { state_ = FINISHED; } - - // Do necessary preparations and return a URL to render. - virtual GURL GetPageUrl(HeadlessDevToolsClient* client) = 0; - - // Check if the DOM snapshot is as expected. - virtual void VerifyDom(dom_snapshot::GetSnapshotResult* dom_snapshot); - - // Called when all steps needed to load and present page are done. - virtual void OnPageRenderCompleted(); - - // Called if page rendering wasn't completed within reasonable time. - virtual void OnTimeout(); - - // Override to set specific options for requests. - virtual void OverrideWebPreferences(WebPreferences* preferences); - - // Determines whether a screenshot will be taken or not. If one is taken, - // ScreenshotOptions specifies the area to capture as well as a golden data - // file to compare the result to. By default, no screenshot is taken. - virtual base::Optional<ScreenshotOptions> GetScreenshotOptions(); - - // Returns the emulated width/height of the window. Defaults to 800x600. - virtual gfx::Size GetEmulatedWindowSize(); - - // Setting up the browsertest. - void SetUpCommandLine(base::CommandLine* command_line) override; - void SetUp() override; - void CustomizeHeadlessBrowserContext( - HeadlessBrowserContext::Builder& builder) override; - bool GetEnableBeginFrameControl() override; - void PostRunAsynchronousTest() override; - - // page::ExperimentalObserver implementation: - void OnLoadEventFired(const page::LoadEventFiredParams& params) override; - void OnFrameStartedLoading( - const page::FrameStartedLoadingParams& params) override; - void OnFrameScheduledNavigation( - const page::FrameScheduledNavigationParams& params) override; - void OnFrameNavigated(const page::FrameNavigatedParams& params) override; - - // runtime::ExperimentalObserver implementation: - void OnConsoleAPICalled( - const runtime::ConsoleAPICalledParams& params) override; - void OnExceptionThrown(const runtime::ExceptionThrownParams& params) override; - - // For each frame, keep track of scheduled navigations. - // FYI: It doesn't track every navigations. For instance, it doesn't include - // the first navigation. It doesn't include HTTP redirect, but it includes - // client-side redirect. - std::map<std::string, std::vector<Navigation>> scheduled_navigations_; - - std::map<std::string, std::vector<std::unique_ptr<page::Frame>>> frames_; - std::string main_frame_; - std::vector<std::string> console_log_; - std::vector<std::string> js_exceptions_; - - private: - class AdditionalVirtualTimeBudget; - - void SetDeviceMetricsOverride( - std::unique_ptr<headless::page::Viewport> viewport); - void HandleVirtualTimeExhausted(); - void OnGetDomSnapshotDone( - std::unique_ptr<dom_snapshot::GetSnapshotResult> result); - void CaptureScreenshot(const ScreenshotOptions& options); - void ScreenshotCaptured(const ScreenshotOptions& options, - const std::string& data); - void RenderComplete(); - void HandleTimeout(); - void CleanUp(); - - enum State { - INIT, // Setting up the client, no navigation performed yet. - STARTING, // Navigation request issued but URL not being loaded yet. - LOADING, // URL was requested but resources are not fully loaded yet. - RENDERING, // Main resources were loaded but page is still being rendered. - DONE, // Page considered to be rendered, DOM snapshot is being taken. - SCREENSHOT, // DOM snapshot has completed, screenshot is being taken. - FINISHED, // Test has finished. - }; - State state_ = INIT; - - std::unique_ptr<VirtualTimeController> virtual_time_controller_; - std::unique_ptr<CompositorController> compositor_controller_; - - base::test::ScopedFeatureList scoped_feature_list_; - - base::WeakPtrFactory<HeadlessRenderTest> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(HeadlessRenderTest); -}; - -} // namespace headless - -#endif // HEADLESS_TEST_HEADLESS_RENDER_TEST_H_
diff --git a/infra/config/branch/cq.cfg b/infra/config/branch/cq.cfg index 11d8983..e93a992 100644 --- a/infra/config/branch/cq.cfg +++ b/infra/config/branch/cq.cfg
@@ -2,7 +2,6 @@ # documentation of this file format. version: 1 -cq_name: "chromium" cq_status_url: "https://chromium-cq-status.appspot.com" git_repo_url: "https://chromium.googlesource.com/chromium/src" commit_burst_delay: 60
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.mm b/ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.mm index 5ab31b59..37eb84e 100644 --- a/ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.mm +++ b/ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.mm
@@ -43,10 +43,7 @@ [super configureCell:cell]; cell.textLabel.text = self.text; cell.switchView.enabled = self.isEnabled; - - // Force disabled cells to be drawn in the "off" state, but do not change the - // value of the |on| property. - cell.switchView.on = self.isOn && self.isEnabled; + cell.switchView.on = self.isOn; cell.textLabel.textColor = [CollectionViewSwitchCell defaultTextColorForState:cell.switchView.state]; }
diff --git a/ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item_unittest.mm b/ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item_unittest.mm index fbdcb4a..67a46e92 100644 --- a/ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item_unittest.mm +++ b/ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item_unittest.mm
@@ -74,12 +74,11 @@ EXPECT_FALSE(cell.switchView.isOn); EXPECT_NSEQ(disabledColor, cell.textLabel.textColor); - // Disabled and on. In this case, the switch should draw in the "off" state, - // because it is disabled. + // Disabled and on. item.on = YES; item.enabled = NO; [item configureCell:cell]; - EXPECT_FALSE(cell.switchView.isOn); + EXPECT_TRUE(cell.switchView.isOn); EXPECT_NSEQ(disabledColor, cell.textLabel.textColor); }
diff --git a/ios/chrome/browser/ui/settings/autofill_settings_egtest.mm b/ios/chrome/browser/ui/settings/autofill_settings_egtest.mm index 4b38c61..04d6610 100644 --- a/ios/chrome/browser/ui/settings/autofill_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/autofill_settings_egtest.mm
@@ -269,15 +269,14 @@ performAction:grey_tap()]; // Check the Autofill, address, and credit card switches are disabled. - // Disabled switches are toggled off. [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsSwitchCell( - @"autofillItem_switch", NO, NO)] + @"autofillItem_switch", YES, NO)] assertWithMatcher:grey_notNil()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsSwitchCell( - @"addressItem_switch", NO, NO)] + @"addressItem_switch", YES, NO)] assertWithMatcher:grey_notNil()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsSwitchCell( - @"cardItem_switch", NO, NO)] + @"cardItem_switch", YES, NO)] assertWithMatcher:grey_notNil()]; } @@ -372,16 +371,15 @@ performAction:chrome_test_util::TurnSettingsSwitchOn(!expectedState)]; // Expect Autofill address and credit card switches to be disabled when - // Autofill toggle is off and enabled when it is on. Disabled switches are - // toggled off. + // Autofill toggle is off and enabled when it is on. [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsSwitchCell( - @"addressItem_switch", - !expectedState, !expectedState)] - assertWithMatcher:grey_notNil()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsSwitchCell( - @"cardItem_switch", !expectedState, + @"addressItem_switch", YES, !expectedState)] assertWithMatcher:grey_notNil()]; + [[EarlGrey + selectElementWithMatcher:chrome_test_util::SettingsSwitchCell( + @"cardItem_switch", YES, !expectedState)] + assertWithMatcher:grey_notNil()]; // Expect Autofill addresses and credit cards to remain visible. [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(
diff --git a/ios/chrome/browser/ui/settings/cells/settings_switch_item.mm b/ios/chrome/browser/ui/settings/cells/settings_switch_item.mm index f133fe8..6854e48 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_switch_item.mm +++ b/ios/chrome/browser/ui/settings/cells/settings_switch_item.mm
@@ -54,10 +54,7 @@ [super configureCell:cell]; cell.textLabel.text = self.text; cell.switchView.enabled = self.isEnabled; - - // Force disabled cells to be drawn in the "off" state, but do not change the - // value of the |on| property. - cell.switchView.on = self.isOn && self.isEnabled; + cell.switchView.on = self.isOn; cell.textLabel.textColor = [SettingsSwitchCell defaultTextColorForState:cell.switchView.state];
diff --git a/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm index 21a2232..6ee06da4 100644 --- a/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm
@@ -914,10 +914,9 @@ TapEdit(); - // Check that the "Save Passwords" switch is disabled. Disabled switches are - // toggled off. + // Check that the "Save Passwords" switch is disabled. [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsSwitchCell( - @"savePasswordsItem_switch", NO, NO)] + @"savePasswordsItem_switch", YES, NO)] assertWithMatcher:grey_notNil()]; [GetInteractionForPasswordEntry(@"example.com, concrete username")
diff --git a/ios/chrome/browser/ui/settings/voicesearch_collection_view_controller.mm b/ios/chrome/browser/ui/settings/voicesearch_collection_view_controller.mm index 60717e82..1b5acbf 100644 --- a/ios/chrome/browser/ui/settings/voicesearch_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/voicesearch_collection_view_controller.mm
@@ -78,8 +78,9 @@ SettingsSwitchItem* tts = [[SettingsSwitchItem alloc] initWithType:ItemTypeTTSEnabled]; tts.text = l10n_util::GetNSString(IDS_IOS_VOICE_SEARCH_SETTING_TTS); - tts.on = _ttsEnabled.GetValue(); - tts.enabled = [self currentLanguageSupportsTTS]; + BOOL enabled = [self currentLanguageSupportsTTS]; + tts.on = enabled && _ttsEnabled.GetValue(); + tts.enabled = enabled; [model addItem:tts toSectionWithIdentifier:SectionIdentifierTTS]; // Variables used to populate the languages section.
diff --git a/ios/chrome/browser/ui/settings/voicesearch_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/voicesearch_collection_view_controller_unittest.mm index be545a8..37b870666 100644 --- a/ios/chrome/browser/ui/settings/voicesearch_collection_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/voicesearch_collection_view_controller_unittest.mm
@@ -146,7 +146,7 @@ CreateController(); SettingsSwitchItem* switchItem = GetCollectionViewItem(0, 0); - EXPECT_TRUE(switchItem.isOn); + EXPECT_FALSE(switchItem.isOn); EXPECT_FALSE(switchItem.isEnabled); }
diff --git a/ios/net/cookies/cookie_store_ios_persistent.mm b/ios/net/cookies/cookie_store_ios_persistent.mm index 4fa4a68..9817467 100644 --- a/ios/net/cookies/cookie_store_ios_persistent.mm +++ b/ios/net/cookies/cookie_store_ios_persistent.mm
@@ -8,6 +8,7 @@ #include <memory> +#include "base/bind.h" #include "base/threading/thread_checker.h" #import "ios/net/cookies/ns_http_system_cookie_store.h" #import "ios/net/cookies/system_cookie_util.h" @@ -19,6 +20,20 @@ namespace net { +namespace { +// Add metrics reporting to GetCookieListWithOptionsAsync cookie monster +// callback. +void CookieListCallbackWithMetricsLogging( + CookieMonster::GetCookieListCallback callback, + const CookieList& cookies) { + net::ReportGetCookiesForURLResult(SystemCookieStoreType::kCookieMonster, + !cookies.empty()); + if (!callback.is_null()) { + std::move(callback).Run(cookies); + } +} +} // namespace + #pragma mark - #pragma mark CookieStoreIOSPersistent @@ -65,9 +80,11 @@ const net::CookieOptions& options, GetCookieListCallback callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - cookie_monster()->GetCookieListWithOptionsAsync(url, options, - std::move(callback)); + ReportGetCookiesForURLCall(SystemCookieStoreType::kCookieMonster); + cookie_monster()->GetCookieListWithOptionsAsync( + url, options, + base::BindOnce(&CookieListCallbackWithMetricsLogging, + base::Passed(&callback))); } void CookieStoreIOSPersistent::GetAllCookiesAsync(
diff --git a/ios/net/cookies/ns_http_system_cookie_store.mm b/ios/net/cookies/ns_http_system_cookie_store.mm index b5c1973..8e5cbc3f09 100644 --- a/ios/net/cookies/ns_http_system_cookie_store.mm +++ b/ios/net/cookies/ns_http_system_cookie_store.mm
@@ -8,6 +8,7 @@ #include "base/time/time.h" #import "ios/net/cookies/cookie_creation_time_manager.h" #import "ios/net/cookies/cookie_store_ios_client.h" +#import "ios/net/cookies/system_cookie_util.h" #import "net/base/mac/url_conversions.h" #include "url/gurl.h" @@ -41,14 +42,19 @@ void NSHTTPSystemCookieStore::GetCookiesForURLAsync( const GURL& url, SystemCookieCallbackForCookies callback) { + ReportGetCookiesForURLCall(SystemCookieStoreType::kNSHTTPSystemCookieStore); NSArray* cookies = GetCookiesForURL(url); + net::ReportGetCookiesForURLResult( + SystemCookieStoreType::kNSHTTPSystemCookieStore, cookies.count != 0); RunCookieCallback(base::BindOnce(std::move(callback), cookies)); } + void NSHTTPSystemCookieStore::GetAllCookiesAsync( SystemCookieCallbackForCookies callback) { NSArray* cookies = GetAllCookies(); RunCookieCallback(base::BindOnce(std::move(callback), cookies)); } + void NSHTTPSystemCookieStore::DeleteCookieAsync(NSHTTPCookie* cookie, SystemCookieCallback callback) { DeleteCookie(cookie);
diff --git a/ios/net/cookies/system_cookie_util.h b/ios/net/cookies/system_cookie_util.h index 3907885..5759956 100644 --- a/ios/net/cookies/system_cookie_util.h +++ b/ios/net/cookies/system_cookie_util.h
@@ -31,6 +31,42 @@ COOKIES_APPLICATION_FOREGROUNDED // The application has been foregrounded. }; +// Enum for the IOS.Cookies.GetCookiesForURLCallStoreType UMA histogram to +// report the type of the backing system cookie store, when GetCookiesForURL +// method is called. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class SystemCookieStoreType { + kWKHTTPSystemCookieStore = 0, + kNSHTTPSystemCookieStore = 1, + kCookieMonster = 2, + kMaxValue = kCookieMonster, +}; + +// Enum for the IOS.Cookies.GetCookiesForURLCallResult UMA histogram to report +// if the call found cookies or no cookies were found on a specific system +// cookie store type. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class GetCookiesForURLCallResult { + kCookiesFoundOnWKHTTPSystemCookieStore = 0, + kNoCookiesOnWKHTTPSystemCookieStore = 1, + kCookiesFoundOnNSHTTPSystemCookieStore = 2, + kNoCookiesOnNSHTTPSystemCookieStore = 3, + kCookiesFoundOnCookieMonster = 4, + kNoCookiesOnCookieMonster = 5, + kMaxValue = kNoCookiesOnCookieMonster, +}; + +// Reports metrics to indicate if call to GetCookiesForURL found cookies or no +// cookies were found on a specific system cookie store type. +void ReportGetCookiesForURLResult(SystemCookieStoreType store_type, + bool has_cookies); + +// Reports metrics to indicate that GetCookiesForURL was called from cookie +// store with type |store_type|. +void ReportGetCookiesForURLCall(SystemCookieStoreType store_type); + // Report metrics if the number of cookies drops unexpectedly. void CheckForCookieLoss(size_t cookie_count, CookieEvent event);
diff --git a/ios/net/cookies/system_cookie_util.mm b/ios/net/cookies/system_cookie_util.mm index 945bbdb5..c899b23 100644 --- a/ios/net/cookies/system_cookie_util.mm +++ b/ios/net/cookies/system_cookie_util.mm
@@ -82,6 +82,41 @@ net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT); } +void ReportGetCookiesForURLResult(SystemCookieStoreType store_type, + bool has_cookies) { + GetCookiesForURLCallResult call_result = + GetCookiesForURLCallResult::kCookiesFoundOnWKHTTPSystemCookieStore; + switch (store_type) { + case SystemCookieStoreType::kWKHTTPSystemCookieStore: + call_result = + has_cookies + ? GetCookiesForURLCallResult:: + kCookiesFoundOnWKHTTPSystemCookieStore + : GetCookiesForURLCallResult::kNoCookiesOnWKHTTPSystemCookieStore; + break; + case SystemCookieStoreType::kNSHTTPSystemCookieStore: + call_result = + has_cookies + ? GetCookiesForURLCallResult:: + kCookiesFoundOnNSHTTPSystemCookieStore + : GetCookiesForURLCallResult::kNoCookiesOnNSHTTPSystemCookieStore; + + break; + case SystemCookieStoreType::kCookieMonster: + call_result = + has_cookies ? GetCookiesForURLCallResult::kCookiesFoundOnCookieMonster + : GetCookiesForURLCallResult::kNoCookiesOnCookieMonster; + break; + } + UMA_HISTOGRAM_ENUMERATION("IOS.Cookies.GetCookiesForURLCallResult", + call_result); +} + +void ReportGetCookiesForURLCall(SystemCookieStoreType store_type) { + UMA_HISTOGRAM_ENUMERATION("IOS.Cookies.GetCookiesForURLCallStoreType", + store_type); +} + // Converts net::CanonicalCookie to NSHTTPCookie. NSHTTPCookie* SystemCookieFromCanonicalCookie( const net::CanonicalCookie& cookie) {
diff --git a/ios/net/cookies/system_cookie_util_unittest.mm b/ios/net/cookies/system_cookie_util_unittest.mm index 8e4f2cf..4b29e9bc 100644 --- a/ios/net/cookies/system_cookie_util_unittest.mm +++ b/ios/net/cookies/system_cookie_util_unittest.mm
@@ -7,6 +7,7 @@ #import <Foundation/Foundation.h> #include "base/strings/sys_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" #include "base/time/time.h" #include "net/cookies/cookie_constants.h" #include "testing/gtest/include/gtest/gtest.h" @@ -27,6 +28,8 @@ const char kCookiePath[] = "path/"; const char kCookieValue[] = "value"; const char kCookieValueInvalidUtf8[] = "\x81r\xe4\xbd\xa0\xe5\xa5\xbd"; +const char kGetCookiesResultHistogram[] = + "IOS.Cookies.GetCookiesForURLCallResult"; void CheckSystemCookie(const base::Time& expires, bool secure, bool httponly) { // Generate a canonical cookie. @@ -59,6 +62,14 @@ system_cookie_expire_date); } +void VerifyGetCookiesResultHistogram( + const base::HistogramTester& histogram_tester, + GetCookiesForURLCallResult expected_value) { + histogram_tester.ExpectBucketCount( + kGetCookiesResultHistogram, + static_cast<base::HistogramBase::Sample>(expected_value), 1); +} + } // namespace using CookieUtil = PlatformTest; @@ -109,6 +120,38 @@ EXPECT_TRUE(chrome_cookie.IsSecure()); } +// Tests that histogram is reported correctly based on the input. +TEST_F(CookieUtil, ReportGetCookiesForURLResult) { + base::HistogramTester histogram_tester; + histogram_tester.ExpectTotalCount(kGetCookiesResultHistogram, 0); + ReportGetCookiesForURLResult(SystemCookieStoreType::kNSHTTPSystemCookieStore, + /*has_cookies=*/true); + VerifyGetCookiesResultHistogram( + histogram_tester, + GetCookiesForURLCallResult::kCookiesFoundOnNSHTTPSystemCookieStore); + histogram_tester.ExpectTotalCount(kGetCookiesResultHistogram, 1); + + ReportGetCookiesForURLResult(SystemCookieStoreType::kNSHTTPSystemCookieStore, + /*has_cookies=*/false); + VerifyGetCookiesResultHistogram( + histogram_tester, + GetCookiesForURLCallResult::kNoCookiesOnNSHTTPSystemCookieStore); + histogram_tester.ExpectTotalCount(kGetCookiesResultHistogram, 2); + + ReportGetCookiesForURLResult(SystemCookieStoreType::kCookieMonster, + /*has_cookies=*/false); + VerifyGetCookiesResultHistogram( + histogram_tester, GetCookiesForURLCallResult::kNoCookiesOnCookieMonster); + histogram_tester.ExpectTotalCount(kGetCookiesResultHistogram, 3); + + ReportGetCookiesForURLResult(SystemCookieStoreType::kWKHTTPSystemCookieStore, + /*has_cookies=*/true); + VerifyGetCookiesResultHistogram( + histogram_tester, + GetCookiesForURLCallResult::kCookiesFoundOnWKHTTPSystemCookieStore); + histogram_tester.ExpectTotalCount(kGetCookiesResultHistogram, 4); +} + TEST_F(CookieUtil, SystemCookieFromCanonicalCookie) { base::Time expire_date = base::Time::Now() + base::TimeDelta::FromHours(2);
diff --git a/ios/web/net/cookies/wk_http_system_cookie_store.mm b/ios/web/net/cookies/wk_http_system_cookie_store.mm index 618fa953..ac1d734 100644 --- a/ios/web/net/cookies/wk_http_system_cookie_store.mm +++ b/ios/web/net/cookies/wk_http_system_cookie_store.mm
@@ -64,6 +64,8 @@ SystemCookieCallbackForCookies callback) { // This function shouldn't be called if cookie_store_ is deleted. DCHECK(cookie_store_); + net::ReportGetCookiesForURLCall( + net::SystemCookieStoreType::kWKHTTPSystemCookieStore); __block SystemCookieCallbackForCookies shared_callback = std::move(callback); base::WeakPtr<net::CookieCreationTimeManager> weak_time_manager = creation_time_manager_->GetWeakPtr(); @@ -77,6 +79,9 @@ [result addObject:cookie]; } } + net::ReportGetCookiesForURLResult( + net::SystemCookieStoreType::kWKHTTPSystemCookieStore, + cookies.count != 0); RunSystemCookieCallbackForCookies(std::move(shared_callback), weak_time_manager, result); }];
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 709578f..3ca7160 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc
@@ -215,13 +215,13 @@ if (format != PIXEL_FORMAT_ARGB && format != PIXEL_FORMAT_XRGB && format != PIXEL_FORMAT_RGB32 && format != PIXEL_FORMAT_UYVY && format != PIXEL_FORMAT_NV12 && format != PIXEL_FORMAT_I420) { - LOG(DFATAL) << "Unsupported pixel format: " + DLOG(ERROR) << "Unsupported pixel format: " << VideoPixelFormatToString(format); return nullptr; } const StorageType storage = STORAGE_OPAQUE; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - LOG(DFATAL) << __func__ << " Invalid config." + DLOG(ERROR) << __func__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; @@ -317,7 +317,7 @@ base::TimeDelta timestamp) { const StorageType storage = STORAGE_UNOWNED_MEMORY; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - LOG(DFATAL) << __func__ << " Invalid config." + DLOG(ERROR) << __func__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; @@ -353,14 +353,14 @@ base::TimeDelta timestamp) { const StorageType storage = STORAGE_UNOWNED_MEMORY; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - LOG(DFATAL) << __func__ << " Invalid config." + DLOG(ERROR) << __func__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; } if (NumPlanes(format) != 4) { - LOG(DFATAL) << "Expecting Y, U, V and A planes to be present for the video" + DLOG(ERROR) << "Expecting Y, U, V and A planes to be present for the video" << " format."; return nullptr; } @@ -390,14 +390,14 @@ base::TimeDelta timestamp) { const StorageType storage = STORAGE_DMABUFS; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - LOG(DFATAL) << __func__ << " Invalid config." + DLOG(ERROR) << __func__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; } if (dmabuf_fds.empty() || dmabuf_fds.size() > NumPlanes(format)) { - LOG(DFATAL) << __func__ << " Incorrect number of dmabuf fds provided, got: " + DLOG(ERROR) << __func__ << " Incorrect number of dmabuf fds provided, got: " << dmabuf_fds.size() << ", expected 1 to " << NumPlanes(format); return nullptr; } @@ -406,7 +406,7 @@ scoped_refptr<VideoFrame> frame = new VideoFrame( format, storage, coded_size, visible_rect, natural_size, timestamp); if (!frame) { - LOG(DFATAL) << __func__ << " Couldn't create VideoFrame instance."; + DLOG(ERROR) << __func__ << " Couldn't create VideoFrame instance."; return nullptr; } memcpy(&frame->mailbox_holders_, mailbox_holders, @@ -438,7 +438,7 @@ // minimum OS X and iOS SDKs permits it. format = PIXEL_FORMAT_NV12; } else { - LOG(DFATAL) << "CVPixelBuffer format not supported: " << cv_format; + DLOG(ERROR) << "CVPixelBuffer format not supported: " << cv_format; return nullptr; } @@ -448,7 +448,7 @@ const StorageType storage = STORAGE_UNOWNED_MEMORY; if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { - LOG(DFATAL) << __func__ << " Invalid config." + DLOG(ERROR) << __func__ << " Invalid config." << ConfigToString(format, storage, coded_size, visible_rect, natural_size); return nullptr; @@ -474,7 +474,7 @@ DCHECK(frame->visible_rect().Contains(visible_rect)); if (!AreValidPixelFormatsForWrap(frame->format(), format)) { - LOG(DFATAL) << __func__ << " Invalid format conversion." + DLOG(ERROR) << __func__ << " Invalid format conversion." << VideoPixelFormatToString(frame->format()) << " to " << VideoPixelFormatToString(format); return nullptr; @@ -482,7 +482,7 @@ if (!IsValidConfig(format, frame->storage_type(), frame->coded_size(), visible_rect, natural_size)) { - LOG(DFATAL) << __func__ << " Invalid config." + DLOG(ERROR) << __func__ << " Invalid config." << ConfigToString(format, frame->storage_type(), frame->coded_size(), visible_rect, natural_size); @@ -505,7 +505,7 @@ if (frame->storage_type() == STORAGE_DMABUFS) { wrapping_frame->dmabuf_fds_ = DuplicateFDs(frame->dmabuf_fds_); if (wrapping_frame->dmabuf_fds_.empty()) { - LOG(DFATAL) << __func__ << " Couldn't duplicate fds."; + DLOG(ERROR) << __func__ << " Couldn't duplicate fds."; return nullptr; } } @@ -991,7 +991,7 @@ // http://crbug.com/555909 if (format != PIXEL_FORMAT_I420 && format != PIXEL_FORMAT_Y16 && format != PIXEL_FORMAT_ARGB) { - LOG(DFATAL) << "Only PIXEL_FORMAT_I420, PIXEL_FORMAT_Y16, and " + DLOG(ERROR) << "Only PIXEL_FORMAT_I420, PIXEL_FORMAT_Y16, and " "PIXEL_FORMAT_ARGB formats are supported: " << VideoPixelFormatToString(format); return nullptr; @@ -999,7 +999,7 @@ if (!IsValidConfig(format, storage_type, coded_size, visible_rect, natural_size)) { - LOG(DFATAL) << __func__ << " Invalid config." + DLOG(ERROR) << __func__ << " Invalid config." << ConfigToString(format, storage_type, coded_size, visible_rect, natural_size); return nullptr; @@ -1049,7 +1049,7 @@ coded_size.width() / 2}); return frame; default: - LOG(DFATAL) << "Invalid number of planes: " << NumPlanes(format) + DLOG(ERROR) << "Invalid number of planes: " << NumPlanes(format) << " in format: " << VideoPixelFormatToString(format); return nullptr; } @@ -1161,7 +1161,7 @@ const StorageType storage = STORAGE_OWNED_MEMORY; if (!IsValidConfig(layout.format(), storage, layout.coded_size(), visible_rect, natural_size)) { - LOG(DFATAL) << __func__ << " Invalid config." + DLOG(ERROR) << __func__ << " Invalid config." << ConfigToString(layout.format(), storage, layout.coded_size(), visible_rect, natural_size); return nullptr;
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 58f84ef..29a6274 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -2889,6 +2889,12 @@ } UpdateSecondaryProperties(); + + // If the WatchTimeReporter was recreated in the middle of playback, we want + // to resume playback here too since we won't get another play() call. When + // seeking, the seek completion will restart it if necessary. + if (!paused_ && !seeking_) + watch_time_reporter_->OnPlaying(); } void WebMediaPlayerImpl::UpdateSecondaryProperties() { @@ -3132,7 +3138,8 @@ void WebMediaPlayerImpl::SwitchToLocalRenderer( MediaObserverClient::ReasonToSwitchToLocal reason) { DCHECK(main_task_runner_->BelongsToCurrentThread()); - DCHECK(disable_pipeline_auto_suspend_); + if (!disable_pipeline_auto_suspend_) + return; // Is currently with local renderer. disable_pipeline_auto_suspend_ = false; // Capabilities reporting may resume now that playback is local.
diff --git a/media/gpu/android/codec_wrapper.cc b/media/gpu/android/codec_wrapper.cc index 7d851d1..acbe29e 100644 --- a/media/gpu/android/codec_wrapper.cc +++ b/media/gpu/android/codec_wrapper.cc
@@ -24,7 +24,7 @@ class CodecWrapperImpl : public base::RefCountedThreadSafe<CodecWrapperImpl> { public: CodecWrapperImpl(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb); + CodecWrapper::OutputReleasedCB output_buffer_release_cb); using DequeueStatus = CodecWrapper::DequeueStatus; using QueueStatus = CodecWrapper::QueueStatus; @@ -89,7 +89,7 @@ // A callback that's called whenever an output buffer is released back to the // codec. - base::Closure output_buffer_release_cb_; + CodecWrapper::OutputReleasedCB output_buffer_release_cb_; // Do we owe the client an EOS in DequeueOutput, due to an eos that we elided // while we're already flushed? @@ -111,8 +111,9 @@ return codec_->ReleaseCodecOutputBuffer(id_, true); } -CodecWrapperImpl::CodecWrapperImpl(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb) +CodecWrapperImpl::CodecWrapperImpl( + CodecSurfacePair codec_surface_pair, + CodecWrapper::OutputReleasedCB output_buffer_release_cb) : state_(State::kFlushed), codec_(std::move(codec_surface_pair.first)), surface_bundle_(std::move(codec_surface_pair.second)), @@ -386,13 +387,15 @@ int index = buffer_it->second; codec_->ReleaseOutputBuffer(index, render); buffer_ids_.erase(buffer_ids_.begin(), buffer_it + 1); - if (output_buffer_release_cb_) - output_buffer_release_cb_.Run(); + if (output_buffer_release_cb_) { + output_buffer_release_cb_.Run(state_ == State::kDrained || + state_ == State::kDraining); + } return true; } CodecWrapper::CodecWrapper(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb) + OutputReleasedCB output_buffer_release_cb) : impl_(new CodecWrapperImpl(std::move(codec_surface_pair), std::move(output_buffer_release_cb))) {}
diff --git a/media/gpu/android/codec_wrapper.h b/media/gpu/android/codec_wrapper.h index b316f11..2c81fe9 100644 --- a/media/gpu/android/codec_wrapper.h +++ b/media/gpu/android/codec_wrapper.h
@@ -68,8 +68,12 @@ // released back to the codec (whether it's rendered or not). This is a signal // that the codec might be ready to accept more input. It may be run on any // thread. + // + // OutputReleasedCB will be called with a bool indicating if CodecWrapper is + // currently draining or in the drained state. + using OutputReleasedCB = base::RepeatingCallback<void(bool)>; CodecWrapper(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb); + OutputReleasedCB output_buffer_release_cb); ~CodecWrapper(); // Takes the backing codec and surface, implicitly discarding all outstanding
diff --git a/media/gpu/android/codec_wrapper_unittest.cc b/media/gpu/android/codec_wrapper_unittest.cc index b01bb38..e08a4a3 100644 --- a/media/gpu/android/codec_wrapper_unittest.cc +++ b/media/gpu/android/codec_wrapper_unittest.cc
@@ -63,7 +63,8 @@ NiceMock<MockMediaCodecBridge>* codec_; std::unique_ptr<CodecWrapper> wrapper_; scoped_refptr<AVDASurfaceBundle> surface_bundle_; - NiceMock<base::MockCallback<base::Closure>> output_buffer_release_cb_; + NiceMock<base::MockCallback<CodecWrapper::OutputReleasedCB>> + output_buffer_release_cb_; scoped_refptr<DecoderBuffer> fake_decoder_buffer_; }; @@ -211,13 +212,22 @@ TEST_F(CodecWrapperTest, OutputBufferReleaseCbIsCalledWhenRendering) { auto codec_buffer = DequeueCodecOutputBuffer(); - EXPECT_CALL(output_buffer_release_cb_, Run()).Times(1); + EXPECT_CALL(output_buffer_release_cb_, Run(false)).Times(1); codec_buffer->ReleaseToSurface(); } TEST_F(CodecWrapperTest, OutputBufferReleaseCbIsCalledWhenDestructing) { auto codec_buffer = DequeueCodecOutputBuffer(); - EXPECT_CALL(output_buffer_release_cb_, Run()).Times(1); + EXPECT_CALL(output_buffer_release_cb_, Run(false)).Times(1); +} + +TEST_F(CodecWrapperTest, OutputBufferReflectsDrainingOrDrainedStatus) { + wrapper_->QueueInputBuffer(*fake_decoder_buffer_, EncryptionScheme()); + auto eos = DecoderBuffer::CreateEOSBuffer(); + wrapper_->QueueInputBuffer(*eos, EncryptionScheme()); + ASSERT_TRUE(wrapper_->IsDraining()); + auto codec_buffer = DequeueCodecOutputBuffer(); + EXPECT_CALL(output_buffer_release_cb_, Run(true)).Times(1); } TEST_F(CodecWrapperTest, CodecStartsInFlushedState) {
diff --git a/media/gpu/android/media_codec_video_decoder.cc b/media/gpu/android/media_codec_video_decoder.cc index bdaceaa..ace97d8 100644 --- a/media/gpu/android/media_codec_video_decoder.cc +++ b/media/gpu/android/media_codec_video_decoder.cc
@@ -89,6 +89,16 @@ } } +void OutputBufferReleased(bool using_async_api, + base::RepeatingClosure pump_cb, + bool is_drained_or_draining) { + // The asynchronous API doesn't need pumping upon calls to ReleaseOutputBuffer + // unless we're draining or drained. + if (using_async_api && !is_drained_or_draining) + return; + pump_cb.Run(); +} + } // namespace // static @@ -455,12 +465,10 @@ codec_ = std::make_unique<CodecWrapper>( CodecSurfacePair(std::move(codec), std::move(surface_bundle)), - // The async API will always get an OnBuffersAvailable callback once an - // output buffer is available, so we don't need to manually pump here. - using_async_api_ ? base::RepeatingClosure() - : BindToCurrentLoop(base::BindRepeating( - &MediaCodecVideoDecoder::StartTimerOrPumpCodec, - weak_factory_.GetWeakPtr()))); + base::BindRepeating(&OutputBufferReleased, using_async_api_, + BindToCurrentLoop(base::BindRepeating( + &MediaCodecVideoDecoder::StartTimerOrPumpCodec, + weak_factory_.GetWeakPtr())))); // If the target surface changed while codec creation was in progress, // transition to it immediately.
diff --git a/media/gpu/ipc/service/vda_video_decoder.cc b/media/gpu/ipc/service/vda_video_decoder.cc index beff80c..97e51cb 100644 --- a/media/gpu/ipc/service/vda_video_decoder.cc +++ b/media/gpu/ipc/service/vda_video_decoder.cc
@@ -503,6 +503,8 @@ DCHECK(vda_initialized_); if (parent_task_runner_->BelongsToCurrentThread()) { + if (!parent_weak_this_) + return; // Note: This optimization is only correct if the output callback does not // reentrantly call Decode(). MojoVideoDecoderService is safe, but there is // no guarantee in the media::VideoDecoder interface definition. @@ -553,6 +555,8 @@ DCHECK(vda_initialized_); if (parent_task_runner_->BelongsToCurrentThread()) { + if (!parent_weak_this_) + return; // Note: This optimization is only correct if the decode callback does not // reentrantly call Decode(). MojoVideoDecoderService is safe, but there is // no guarantee in the media::VideoDecoder interface definition. @@ -688,6 +692,8 @@ DVLOG(1) << __func__; if (parent_task_runner_->BelongsToCurrentThread()) { + if (!parent_weak_this_) + return; AddEventOnParentThread(std::move(event)); return; }
diff --git a/net/BUILD.gn b/net/BUILD.gn index aa90b645..1d4e113 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1561,20 +1561,14 @@ "third_party/quic/platform/impl/quic_url_impl.h", "third_party/quic/platform/impl/quic_url_utils_impl.cc", "third_party/quic/platform/impl/quic_url_utils_impl.h", - "third_party/quic/quartc/quartc_clock_interface.h", "third_party/quic/quartc/quartc_factory.cc", "third_party/quic/quartc/quartc_factory.h", - "third_party/quic/quartc/quartc_factory_interface.cc", - "third_party/quic/quartc/quartc_factory_interface.h", "third_party/quic/quartc/quartc_packet_writer.cc", "third_party/quic/quartc/quartc_packet_writer.h", "third_party/quic/quartc/quartc_session.cc", "third_party/quic/quartc/quartc_session.h", - "third_party/quic/quartc/quartc_session_interface.h", "third_party/quic/quartc/quartc_stream.cc", "third_party/quic/quartc/quartc_stream.h", - "third_party/quic/quartc/quartc_stream_interface.h", - "third_party/quic/quartc/quartc_task_runner_interface.h", "third_party/spdy/core/fuzzing/hpack_fuzz_util.cc", "third_party/spdy/core/fuzzing/hpack_fuzz_util.h", "third_party/spdy/core/hpack/hpack_constants.cc",
diff --git a/net/http/http_stream_factory_job_controller.cc b/net/http/http_stream_factory_job_controller.cc index d632aabb..3f33223 100644 --- a/net/http/http_stream_factory_job_controller.cc +++ b/net/http/http_stream_factory_job_controller.cc
@@ -107,7 +107,7 @@ bound_job_ = nullptr; if (proxy_resolve_request_) { DCHECK_EQ(STATE_RESOLVE_PROXY_COMPLETE, next_state_); - session_->proxy_resolution_service()->CancelRequest(proxy_resolve_request_); + proxy_resolve_request_.reset(); } net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER); } @@ -155,8 +155,7 @@ LoadState HttpStreamFactory::JobController::GetLoadState() const { DCHECK(request_); if (next_state_ == STATE_RESOLVE_PROXY_COMPLETE) - return session_->proxy_resolution_service()->GetLoadState( - proxy_resolve_request_); + return proxy_resolve_request_->GetLoadState(); if (bound_job_) return bound_job_->GetLoadState(); if (main_job_)
diff --git a/net/http/http_stream_factory_job_controller.h b/net/http/http_stream_factory_job_controller.h index ac3f842..e43c00f 100644 --- a/net/http/http_stream_factory_job_controller.h +++ b/net/http/http_stream_factory_job_controller.h
@@ -370,7 +370,7 @@ bool can_start_alternative_proxy_job_; State next_state_; - ProxyResolutionService::Request* proxy_resolve_request_; + std::unique_ptr<ProxyResolutionService::Request> proxy_resolve_request_; const HttpRequestInfo request_info_; ProxyInfo proxy_info_; const SSLConfig server_ssl_config_;
diff --git a/net/proxy_resolution/proxy_resolution_service.cc b/net/proxy_resolution/proxy_resolution_service.cc index ea417271..3703bcb 100644 --- a/net/proxy_resolution/proxy_resolution_service.cc +++ b/net/proxy_resolution/proxy_resolution_service.cc
@@ -829,148 +829,54 @@ const ProxyResolutionService::PacPollPolicy* ProxyResolutionService::PacFileDeciderPoller::poll_policy_ = NULL; -// ProxyResolutionService::Request -------------------------------------------- - -class ProxyResolutionService::Request - : public base::RefCounted<ProxyResolutionService::Request> { +class ProxyResolutionService::RequestImpl + : public ProxyResolutionService::Request { public: - Request(ProxyResolutionService* service, - const GURL& url, - const std::string& method, - ProxyDelegate* proxy_delegate, - ProxyInfo* results, - CompletionOnceCallback user_callback, - const NetLogWithSource& net_log) - : service_(service), - user_callback_(std::move(user_callback)), - results_(results), - url_(url), - method_(method), - proxy_delegate_(proxy_delegate), - resolve_job_(nullptr), - net_log_(net_log), - creation_time_(TimeTicks::Now()) { - DCHECK(!user_callback_.is_null()); - } + RequestImpl(ProxyResolutionService* service, + const GURL& url, + const std::string& method, + ProxyDelegate* proxy_delegate, + ProxyInfo* results, + const CompletionOnceCallback user_callback, + const NetLogWithSource& net_log); + ~RequestImpl() override; // Starts the resolve proxy request. - int Start() { - DCHECK(!was_cancelled()); - DCHECK(!is_started()); - - DCHECK(service_->config_); - traffic_annotation_ = MutableNetworkTrafficAnnotationTag( - service_->config_->traffic_annotation()); - - return resolver()->GetProxyForURL( - url_, results_, - base::Bind(&Request::QueryComplete, base::Unretained(this)), - &resolve_job_, net_log_); - } + int Start(); bool is_started() const { // Note that !! casts to bool. (VS gives a warning otherwise). return !!resolve_job_.get(); } - void StartAndCompleteCheckingForSynchronous() { - int rv = - service_->TryToCompleteSynchronously(url_, proxy_delegate_, results_); - if (rv == ERR_IO_PENDING) - rv = Start(); - if (rv != ERR_IO_PENDING) - QueryComplete(rv); - } + void StartAndCompleteCheckingForSynchronous(); - void CancelResolveJob() { - DCHECK(is_started()); - // The request may already be running in the resolver. - resolve_job_.reset(); - DCHECK(!is_started()); - } + void CancelResolveJob(); - void Cancel() { - net_log_.AddEvent(NetLogEventType::CANCELLED); + // Returns true if the request has been completed. + bool was_completed() const { return user_callback_.is_null(); } - if (is_started()) - CancelResolveJob(); - - // Mark as cancelled, to prevent accessing this again later. - service_ = NULL; - user_callback_.Reset(); - results_ = NULL; - - net_log_.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE); - } - - // Returns true if Cancel() has been called. - bool was_cancelled() const { - return user_callback_.is_null(); - } + // Callback for when the ProxyResolver request has completed. + void QueryComplete(int result_code); // Helper to call after ProxyResolver completion (both synchronous and // asynchronous). Fixes up the result that is to be returned to user. - int QueryDidComplete(int result_code) { - DCHECK(!was_cancelled()); + int QueryDidComplete(int result_code); - // Clear |resolve_job_| so is_started() returns false while - // DidFinishResolvingProxy() runs. - resolve_job_.reset(); - - // Note that DidFinishResolvingProxy might modify |results_|. - int rv = service_->DidFinishResolvingProxy(url_, method_, proxy_delegate_, - results_, result_code, net_log_); - - // Make a note in the results which configuration was in use at the - // time of the resolve. - results_->did_use_pac_script_ = true; - results_->proxy_resolve_start_time_ = creation_time_; - results_->proxy_resolve_end_time_ = TimeTicks::Now(); - - // If annotation is not already set, e.g. through TryToCompleteSynchronously - // function, use in-progress-resolve annotation. - if (!results_->traffic_annotation_.is_valid()) - results_->set_traffic_annotation(traffic_annotation_); - - // If proxy is set without error, ensure that an annotation is provided. - if (!rv) - DCHECK(results_->traffic_annotation_.is_valid()); - - // Reset the state associated with in-progress-resolve. - traffic_annotation_.reset(); - - return rv; - } + // Helper to call if the request completes synchronously, since in that case + // the request will not be added to |pending_requests_| (in + // |ProxyResolutionService|). + int QueryDidCompleteSynchronously(int result_code); NetLogWithSource* net_log() { return &net_log_; } - LoadState GetLoadState() const { - if (is_started()) - return resolve_job_->GetLoadState(); - return LOAD_STATE_RESOLVING_PROXY_FOR_URL; - } + // Request implementation: + LoadState GetLoadState() const override; private: - friend class base::RefCounted<ProxyResolutionService::Request>; - - ~Request() = default; - - // Callback for when the ProxyResolver request has completed. - void QueryComplete(int result_code) { - result_code = QueryDidComplete(result_code); - - // Remove this completed Request from the service's pending list. - /// (which will probably cause deletion of |this|). - if (!user_callback_.is_null()) { - CompletionOnceCallback callback = std::move(user_callback_); - service_->RemovePendingRequest(this); - std::move(callback).Run(result_code); - } - } - ProxyResolver* resolver() const { return service_->resolver_.get(); } - // Note that we don't hold a reference to the ProxyResolutionService. + // Note that Request holds a bare pointer to the ProxyResolutionService. // Outstanding requests are cancelled during ~ProxyResolutionService, so this // is guaranteed to be valid throughout our lifetime. ProxyResolutionService* service_; @@ -984,9 +890,140 @@ NetLogWithSource net_log_; // Time when the request was created. Stored here rather than in |results_| // because the time in |results_| will be cleared. - TimeTicks creation_time_; + base::TimeTicks creation_time_; + + DISALLOW_COPY_AND_ASSIGN(RequestImpl); }; +ProxyResolutionService::RequestImpl::RequestImpl( + ProxyResolutionService* service, + const GURL& url, + const std::string& method, + ProxyDelegate* proxy_delegate, + ProxyInfo* results, + CompletionOnceCallback user_callback, + const NetLogWithSource& net_log) + : service_(service), + user_callback_(std::move(user_callback)), + results_(results), + url_(url), + method_(method), + proxy_delegate_(proxy_delegate), + resolve_job_(nullptr), + net_log_(net_log), + creation_time_(base::TimeTicks::Now()) { + DCHECK(!user_callback_.is_null()); +} + +ProxyResolutionService::RequestImpl::~RequestImpl() { + if (service_) { + service_->RemovePendingRequest(this); + net_log_.AddEvent(NetLogEventType::CANCELLED); + + if (is_started()) + CancelResolveJob(); + + // This should be emitted last, after any message |CancelResolveJob()| may + // trigger. + net_log_.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE); + } +} + +// Starts the resolve proxy request. +int ProxyResolutionService::RequestImpl::Start() { + DCHECK(!was_completed()); + DCHECK(!is_started()); + + DCHECK(service_->config_); + traffic_annotation_ = MutableNetworkTrafficAnnotationTag( + service_->config_->traffic_annotation()); + + return resolver()->GetProxyForURL( + url_, results_, + base::Bind(&ProxyResolutionService::RequestImpl::QueryComplete, + base::Unretained(this)), + &resolve_job_, net_log_); +} + +void ProxyResolutionService::RequestImpl:: + StartAndCompleteCheckingForSynchronous() { + int rv = + service_->TryToCompleteSynchronously(url_, proxy_delegate_, results_); + if (rv == ERR_IO_PENDING) + rv = Start(); + if (rv != ERR_IO_PENDING) + QueryComplete(rv); +} + +void ProxyResolutionService::RequestImpl::CancelResolveJob() { + DCHECK(is_started()); + // The request may already be running in the resolver. + resolve_job_.reset(); + DCHECK(!is_started()); +} + +int ProxyResolutionService::RequestImpl::QueryDidComplete(int result_code) { + DCHECK(!was_completed()); + + // Clear |resolve_job_| so is_started() returns false while + // DidFinishResolvingProxy() runs. + resolve_job_.reset(); + + // Note that DidFinishResolvingProxy might modify |results_|. + int rv = service_->DidFinishResolvingProxy(url_, method_, proxy_delegate_, + results_, result_code, net_log_); + + // Make a note in the results which configuration was in use at the + // time of the resolve. + results_->did_use_pac_script_ = true; + results_->proxy_resolve_start_time_ = creation_time_; + results_->proxy_resolve_end_time_ = TimeTicks::Now(); + + // If annotation is not already set, e.g. through TryToCompleteSynchronously + // function, use in-progress-resolve annotation. + if (!results_->traffic_annotation_.is_valid()) + results_->set_traffic_annotation(traffic_annotation_); + + // If proxy is set without error, ensure that an annotation is provided. + if (result_code != ERR_ABORTED && !rv) + DCHECK(results_->traffic_annotation_.is_valid()); + + // Reset the state associated with in-progress-resolve. + traffic_annotation_.reset(); + + return rv; +} + +int ProxyResolutionService::RequestImpl::QueryDidCompleteSynchronously( + int result_code) { + int rv = QueryDidComplete(result_code); + service_ = nullptr; + return rv; +} + +LoadState ProxyResolutionService::RequestImpl::GetLoadState() const { + if (service_ && + service_->current_state_ == STATE_WAITING_FOR_INIT_PROXY_RESOLVER) { + return service_->init_proxy_resolver_->GetLoadState(); + } + + if (is_started()) + return resolve_job_->GetLoadState(); + return LOAD_STATE_RESOLVING_PROXY_FOR_URL; +} + +// Callback for when the ProxyResolver request has completed. +void ProxyResolutionService::RequestImpl::QueryComplete(int result_code) { + result_code = QueryDidComplete(result_code); + + CompletionOnceCallback callback = std::move(user_callback_); + + service_->RemovePendingRequest(this); + service_ = nullptr; + user_callback_.Reset(); + std::move(callback).Run(result_code); +} + // ProxyResolutionService ----------------------------------------------------- ProxyResolutionService::ProxyResolutionService( @@ -999,7 +1036,8 @@ stall_proxy_auto_config_delay_( TimeDelta::FromMilliseconds(kDelayAfterNetworkChangesMs)), quick_check_enabled_(true), - sanitize_url_policy_(SanitizeUrlPolicy::SAFE) { + sanitize_url_policy_(SanitizeUrlPolicy::SAFE), + weak_ptr_factory_(this) { NetworkChangeNotifier::AddIPAddressObserver(this); NetworkChangeNotifier::AddDNSObserver(this); ResetConfigService(std::move(config_service)); @@ -1085,12 +1123,12 @@ const std::string& method, ProxyInfo* result, CompletionOnceCallback callback, - Request** pac_request, + std::unique_ptr<Request>* out_request, ProxyDelegate* proxy_delegate, const NetLogWithSource& net_log) { DCHECK(!callback.is_null()); return ResolveProxyHelper(raw_url, method, result, std::move(callback), - pac_request, proxy_delegate, net_log); + out_request, proxy_delegate, net_log); } int ProxyResolutionService::ResolveProxyHelper( @@ -1098,10 +1136,11 @@ const std::string& method, ProxyInfo* result, CompletionOnceCallback callback, - Request** pac_request, + std::unique_ptr<Request>* out_request, ProxyDelegate* proxy_delegate, const NetLogWithSource& net_log) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(out_request || callback.is_null()); net_log.BeginEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE); @@ -1132,14 +1171,14 @@ if (callback.is_null()) return ERR_IO_PENDING; - scoped_refptr<Request> req(new Request(this, url, method, proxy_delegate, - result, std::move(callback), net_log)); + std::unique_ptr<RequestImpl> req = std::make_unique<RequestImpl>( + this, url, method, proxy_delegate, result, std::move(callback), net_log); if (current_state_ == STATE_READY) { // Start the resolve request. rv = req->Start(); if (rv != ERR_IO_PENDING) - return req->QueryDidComplete(rv); + return req->QueryDidCompleteSynchronously(rv); } else { req->net_log()->BeginEvent( NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC); @@ -1147,12 +1186,11 @@ DCHECK_EQ(ERR_IO_PENDING, rv); DCHECK(!ContainsPendingRequest(req.get())); - pending_requests_.insert(req); + pending_requests_.insert(req.get()); // Completion will be notified through |callback|, unless the caller cancels - // the request using |pac_request|. - if (pac_request) - *pac_request = req.get(); + // the request using |out_request|. + *out_request = std::move(req); return rv; // ERR_IO_PENDING } @@ -1163,7 +1201,7 @@ ProxyDelegate* proxy_delegate, const NetLogWithSource& net_log) { return ResolveProxyHelper(raw_url, method, result, CompletionOnceCallback(), - nullptr /* pac_request*/, proxy_delegate, + nullptr /* out_request*/, proxy_delegate, net_log) == OK; } @@ -1200,10 +1238,15 @@ config_service_->RemoveObserver(this); // Cancel any inprogress requests. - for (PendingRequests::iterator it = pending_requests_.begin(); - it != pending_requests_.end(); - ++it) { - (*it)->Cancel(); + // This cancels the internal requests, but leaves the responsibility of + // canceling the high-level Request (by deleting it) to the client. + // Since |pending_requests_| might be modified in one of the requests' + // callbacks (if it deletes another request), iterating through the set in a + // for-loop will not work. + while (!pending_requests_.empty()) { + RequestImpl* req = *pending_requests_.begin(); + req->QueryComplete(ERR_ABORTED); + pending_requests_.erase(req); } } @@ -1211,7 +1254,7 @@ for (PendingRequests::iterator it = pending_requests_.begin(); it != pending_requests_.end(); ++it) { - Request* req = it->get(); + RequestImpl* req = *it; if (req->is_started()) { req->CancelResolveJob(); @@ -1225,22 +1268,26 @@ DCHECK(!init_proxy_resolver_.get()); current_state_ = STATE_READY; - // Make a copy in case |this| is deleted during the synchronous completion - // of one of the requests. If |this| is deleted then all of the Request - // instances will be Cancel()-ed. - PendingRequests pending_copy = pending_requests_; + // TODO(lilyhoughton): This is necessary because a callback invoked by + // |StartAndCompleteCheckingForSynchronous()| might delete |this|. A better + // solution would be to disallow synchronous callbacks altogether. + base::WeakPtr<ProxyResolutionService> weak_this = + weak_ptr_factory_.GetWeakPtr(); - for (PendingRequests::iterator it = pending_copy.begin(); - it != pending_copy.end(); - ++it) { - Request* req = it->get(); - if (!req->is_started() && !req->was_cancelled()) { + auto pending_requests_copy = pending_requests_; + for (auto* req : pending_requests_copy) { + if (!ContainsPendingRequest(req)) + continue; + + if (!req->is_started()) { req->net_log()->EndEvent( NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC); // Note that we re-check for synchronous completion, in case we are - // no longer using a ProxyResolver (can happen if we fell-back to manual). + // no longer using a ProxyResolver (can happen if we fell-back to manual.) req->StartAndCompleteCheckingForSynchronous(); + if (!weak_this) + return; // Synchronous callback deleted |this| } } } @@ -1355,25 +1402,11 @@ } } -void ProxyResolutionService::CancelRequest(Request* req) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(req); - req->Cancel(); - RemovePendingRequest(req); -} - -LoadState ProxyResolutionService::GetLoadState(const Request* req) const { - CHECK(req); - if (current_state_ == STATE_WAITING_FOR_INIT_PROXY_RESOLVER) - return init_proxy_resolver_->GetLoadState(); - return req->GetLoadState(); -} - -bool ProxyResolutionService::ContainsPendingRequest(Request* req) { +bool ProxyResolutionService::ContainsPendingRequest(RequestImpl* req) { return pending_requests_.count(req) == 1; } -void ProxyResolutionService::RemovePendingRequest(Request* req) { +void ProxyResolutionService::RemovePendingRequest(RequestImpl* req) { DCHECK(ContainsPendingRequest(req)); pending_requests_.erase(req); } @@ -1410,7 +1443,7 @@ result_code); bool reset_config = result_code == ERR_PAC_SCRIPT_TERMINATED; - if (!config_->value().pac_mandatory()) { + if (config_ && !config_->value().pac_mandatory()) { // Fall-back to direct when the proxy resolver fails. This corresponds // with a javascript runtime error in the PAC script. //
diff --git a/net/proxy_resolution/proxy_resolution_service.h b/net/proxy_resolution/proxy_resolution_service.h index 27485a2..d85001e7e 100644 --- a/net/proxy_resolution/proxy_resolution_service.h +++ b/net/proxy_resolution/proxy_resolution_service.h
@@ -23,9 +23,11 @@ #include "net/base/net_export.h" #include "net/base/network_change_notifier.h" #include "net/base/proxy_server.h" +#include "net/log/net_log_with_source.h" #include "net/proxy_resolution/proxy_config_service.h" #include "net/proxy_resolution/proxy_config_with_annotation.h" #include "net/proxy_resolution/proxy_info.h" +#include "net/proxy_resolution/proxy_resolver.h" #include "url/gurl.h" class GURL; @@ -39,9 +41,7 @@ class DhcpPacFileFetcher; class NetLog; -class NetLogWithSource; class ProxyDelegate; -class ProxyResolver; class ProxyResolverFactory; class PacFileData; class PacFileFetcher; @@ -123,7 +123,17 @@ ~ProxyResolutionService() override; // Used to track proxy resolution requests that complete asynchronously. - class Request; + class Request { + public: + virtual ~Request() = default; + virtual LoadState GetLoadState() const = 0; + + protected: + Request() = default; + + private: + DISALLOW_COPY_AND_ASSIGN(Request); + }; // Determines the appropriate proxy for |url| for a |method| request and // stores the result in |results|. If |method| is empty, the caller can expect @@ -135,10 +145,9 @@ // ResolveProxy. // // The caller is responsible for ensuring that |results| and |callback| - // remain valid until the callback is run or until |request| is cancelled - // via CancelRequest. |request| is only valid while the completion - // callback is still pending. NULL can be passed for |request| if - // the caller will not need to cancel the request. + // remain valid until the callback is run or until |request| is cancelled, + // which occurs when the unique pointer to it is deleted (by leaving scope or + // otherwise). |request| must not be NULL. // // We use the three possible proxy access types in the following order, // doing fallback if one doesn't work. See "pac_script_decider.h" @@ -152,7 +161,7 @@ const std::string& method, ProxyInfo* results, CompletionOnceCallback callback, - Request** request, + std::unique_ptr<Request>* request, ProxyDelegate* proxy_delegate, const NetLogWithSource& net_log); @@ -185,12 +194,6 @@ void ReportSuccess(const ProxyInfo& proxy_info, ProxyDelegate* proxy_delegate); - // Call this method with a non-null |request| to cancel the PAC request. - void CancelRequest(Request* request); - - // Returns the LoadState for this |request| which must be non-NULL. - LoadState GetLoadState(const Request* request) const; - // Sets the PacFileFetcher and DhcpPacFileFetcher dependencies. This // is needed if the ProxyResolver is of type ProxyResolverWithoutFetch. void SetPacFileFetchers( @@ -312,11 +315,11 @@ UpdateConfigAfterFailedAutodetect); FRIEND_TEST_ALL_PREFIXES(ProxyResolutionServiceTest, UpdateConfigFromPACToDirect); - friend class Request; class InitProxyResolver; class PacFileDeciderPoller; + class RequestImpl; - typedef std::set<scoped_refptr<Request>> PendingRequests; + typedef std::set<RequestImpl*> PendingRequests; enum State { STATE_NONE, @@ -355,7 +358,7 @@ const std::string& method, ProxyInfo* results, CompletionOnceCallback callback, - Request** request, + std::unique_ptr<Request>* request, ProxyDelegate* proxy_delegate, const NetLogWithSource& net_log); @@ -368,10 +371,10 @@ void SetReady(); // Returns true if |pending_requests_| contains |req|. - bool ContainsPendingRequest(Request* req); + bool ContainsPendingRequest(RequestImpl* req); // Removes |req| from the list of pending requests. - void RemovePendingRequest(Request* req); + void RemovePendingRequest(RequestImpl* req); // Called when proxy resolution has completed (either synchronously or // asynchronously). Handles logging the result, and cleaning out @@ -472,6 +475,10 @@ THREAD_CHECKER(thread_checker_); + // Flag used by |SetReady()| to check if |this| has been deleted by a + // synchronous callback. + base::WeakPtrFactory<ProxyResolutionService> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(ProxyResolutionService); };
diff --git a/net/proxy_resolution/proxy_resolution_service_unittest.cc b/net/proxy_resolution/proxy_resolution_service_unittest.cc index 72258a1..43e7a8b 100644 --- a/net/proxy_resolution/proxy_resolution_service_unittest.cc +++ b/net/proxy_resolution/proxy_resolution_service_unittest.cc
@@ -390,8 +390,9 @@ ProxyInfo info; TestCompletionCallback callback; BoundTestNetLog log; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(), - nullptr, nullptr, log.bound()); + &request, nullptr, log.bound()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(factory->pending_requests().empty()); @@ -431,8 +432,9 @@ // First, warm up the ProxyResolutionService and fake an error to mark the // first server as bad. + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(), - nullptr, nullptr, log.bound()); + &request, nullptr, log.bound()); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("badproxy:8080", info.proxy_server().ToURI()); @@ -443,7 +445,7 @@ // Verify that network delegate is invoked. TestResolveProxyDelegate delegate; - rv = service.ResolveProxy(url, "GET", &info, callback.callback(), nullptr, + rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request, &delegate, log.bound()); EXPECT_TRUE(delegate.on_resolve_proxy_called()); EXPECT_THAT(delegate.proxy_retry_info(), ElementsAre(Key("badproxy:8080"))); @@ -455,21 +457,21 @@ delegate.set_add_proxy(true); // Callback should interpose: - rv = service.ResolveProxy(url, "GET", &info, callback.callback(), nullptr, + rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request, &delegate, log.bound()); EXPECT_FALSE(info.is_direct()); EXPECT_EQ(info.proxy_server().host_port_pair().host(), "delegate_proxy.com"); delegate.set_add_proxy(false); // Check non-bypassed URL: - rv = service.ResolveProxy(url, "GET", &info, callback.callback(), nullptr, + rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request, &delegate, log.bound()); EXPECT_FALSE(info.is_direct()); EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1"); // Check bypassed URL: rv = service.ResolveProxy(bypass_url, "GET", &info, callback.callback(), - nullptr, &delegate, log.bound()); + &request, &delegate, log.bound()); EXPECT_TRUE(info.is_direct()); } @@ -493,31 +495,369 @@ BoundTestNetLog log; // First, warm up the ProxyResolutionService. + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(), - nullptr, nullptr, log.bound()); + &request, nullptr, log.bound()); EXPECT_THAT(rv, IsOk()); TestResolveProxyDelegate delegate; delegate.set_remove_proxy(true); // Callback should interpose: - rv = service.ResolveProxy(url, "GET", &info, callback.callback(), nullptr, + rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request, &delegate, log.bound()); EXPECT_TRUE(info.is_direct()); delegate.set_remove_proxy(false); // Check non-bypassed URL: - rv = service.ResolveProxy(url, "GET", &info, callback.callback(), nullptr, + rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request, &delegate, log.bound()); EXPECT_FALSE(info.is_direct()); EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1"); // Check bypassed URL: rv = service.ResolveProxy(bypass_url, "GET", &info, callback.callback(), - nullptr, &delegate, log.bound()); + &request, &delegate, log.bound()); EXPECT_TRUE(info.is_direct()); } +// Test callback that deletes an item when called. This is used to test various +// permutations of important objects being deleted in the middle of a series of +// requests. +template <typename T> +class DeletingCallback : public TestCompletionCallbackBase { + public: + explicit DeletingCallback(std::unique_ptr<T>* deletee); + ~DeletingCallback() override; + + const CompletionCallback& callback() const { return callback_; } + + private: + void DeleteItem(std::unique_ptr<T>* deletee, int result) { + deletee->reset(); + SetResult(result); + } + + const CompletionCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(DeletingCallback); +}; + +template <typename T> +DeletingCallback<T>::DeletingCallback(std::unique_ptr<T>* deletee) + : callback_(base::BindRepeating(&DeletingCallback::DeleteItem, + base::Unretained(this), + deletee)) {} + +template <typename T> +DeletingCallback<T>::~DeletingCallback() = default; + +// Test that the ProxyResolutionService correctly handles the case where a +// request callback deletes another request. +TEST_F(ProxyResolutionServiceTest, CallbackDeletesRequest) { + MockProxyConfigService* config_service = + new MockProxyConfigService("http://foopy/proxy.pac"); + + MockAsyncProxyResolver resolver; + MockAsyncProxyResolverFactory* factory = + new MockAsyncProxyResolverFactory(false); + + std::unique_ptr<ProxyResolutionService> service = + std::make_unique<ProxyResolutionService>( + base::WrapUnique(config_service), base::WrapUnique(factory), nullptr); + + GURL url("http://www.google.com/"); + GURL url2("http://www.example.com/"); + + ProxyInfo info; + std::unique_ptr<ProxyResolutionService::Request> request, request2; + DeletingCallback<ProxyResolutionService::Request> callback(&request2); + net::CompletionOnceCallback callback2 = + base::BindOnce([](int result) { ASSERT_FALSE(true); }); + + int rv = service->ResolveProxy(url, std::string(), &info, callback.callback(), + &request, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + rv = service->ResolveProxy(url2, std::string(), &info, std::move(callback2), + &request2, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + // Run pending requests. + ASSERT_EQ(1u, factory->pending_requests().size()); + EXPECT_EQ(GURL("http://foopy/proxy.pac"), + factory->pending_requests()[0]->script_data()->url()); + factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver); + + ASSERT_EQ(2u, resolver.pending_jobs().size()); + // Job order is nondeterministic, as requests are stored in an std::set, so + // this loop figures out which one is the correct one to start. + int deleting_job = 2; + for (int i = 0; i < 2; i++) { + if (resolver.pending_jobs()[i]->url() == url) { + deleting_job = i; + break; + } + ASSERT_LE(i, 1); // The loop should never actually make it to the end. + } + + // Set the result in proxy resolver. + resolver.pending_jobs()[deleting_job]->results()->UseNamedProxy("foopy"); + resolver.pending_jobs()[deleting_job]->CompleteNow(OK); + + //// Only one of the callbacks should have been run: + EXPECT_TRUE(callback.have_result()); + EXPECT_THAT(callback.WaitForResult(), IsOk()); + + ASSERT_EQ(0u, resolver.pending_jobs().size()); + ASSERT_EQ(1u, resolver.cancelled_jobs().size()); + ASSERT_EQ(url2, resolver.cancelled_jobs()[0]->url()); +} + +// Test that the ProxyResolutionService correctly handles the case where a +// request callback deletes another request. (Triggered by the loop in +// ProxyResolutionService's destructor). +TEST_F(ProxyResolutionServiceTest, CallbackDeletesRequestDuringDestructor) { + MockProxyConfigService* config_service = + new MockProxyConfigService("http://foopy/proxy.pac"); + + MockAsyncProxyResolver resolver; + MockAsyncProxyResolverFactory* factory = + new MockAsyncProxyResolverFactory(false); + + std::unique_ptr<ProxyResolutionService> service = + std::make_unique<ProxyResolutionService>( + base::WrapUnique(config_service), base::WrapUnique(factory), nullptr); + + GURL url("http://www.google.com/"); + + ProxyInfo info; + std::unique_ptr<ProxyResolutionService::Request> request, request2; + DeletingCallback<ProxyResolutionService::Request> callback(&request2), + callback2(&request); + + int rv = service->ResolveProxy(url, std::string(), &info, callback.callback(), + &request, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + rv = service->ResolveProxy(url, std::string(), &info, callback2.callback(), + &request2, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + // Make sure that ProxyResolutionServices is deleted before the requests, as + // this triggers completion of the pending requests. + service.reset(); + + // Only one of the callbacks should have been run: + EXPECT_TRUE(callback.have_result() ^ callback2.have_result()); + + // Callbacks run during destruction of ProxyResolutionService for Requests + // that have not been started are called with net::ERR_ABORTED + if (callback.have_result()) { + EXPECT_THAT(callback.WaitForResult(), + IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED)); + } + if (callback2.have_result()) { + EXPECT_THAT(callback2.WaitForResult(), + IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED)); + } +} + +// Test that the ProxyResolutionService correctly handles the case where a +// request callback deletes its own handle. +TEST_F(ProxyResolutionServiceTest, CallbackDeletesSelf) { + MockProxyConfigService* config_service = + new MockProxyConfigService("http://foopy/proxy.pac"); + + MockAsyncProxyResolver resolver; + MockAsyncProxyResolverFactory* factory = + new MockAsyncProxyResolverFactory(false); + + std::unique_ptr<ProxyResolutionService> service = + std::make_unique<ProxyResolutionService>( + base::WrapUnique(config_service), base::WrapUnique(factory), nullptr); + + GURL url("http://www.google.com/"); + ProxyInfo info; + + std::unique_ptr<ProxyResolutionService::Request> request1; + TestCompletionCallback callback1; + int rv = + service->ResolveProxy(url, std::string(), &info, callback1.callback(), + &request1, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + GURL url2("http://www.example.com/"); + std::unique_ptr<ProxyResolutionService::Request> request2; + DeletingCallback<ProxyResolutionService::Request> callback2(&request2); + rv = service->ResolveProxy(url2, std::string(), &info, callback2.callback(), + &request2, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + std::unique_ptr<ProxyResolutionService::Request> request3; + TestCompletionCallback callback3; + rv = service->ResolveProxy(url, std::string(), &info, callback3.callback(), + &request3, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + ASSERT_EQ(1u, factory->pending_requests().size()); + EXPECT_EQ(GURL("http://foopy/proxy.pac"), + factory->pending_requests()[0]->script_data()->url()); + factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver); + + ASSERT_EQ(3u, resolver.pending_jobs().size()); + // Job order is nondeterministic, as requests are stored in an std::set, so + // this loop figures out which one is the correct one to start. + int self_deleting_job = 3; + for (int i = 0; i < 3; i++) { + if (resolver.pending_jobs()[i]->url() == url2) { + self_deleting_job = i; + break; + } + ASSERT_LE(i, 2); // The loop should never actually make it to the end. + } + + // Set the result in proxy resolver. + resolver.pending_jobs()[self_deleting_job]->results()->UseNamedProxy("foopy"); + resolver.pending_jobs()[self_deleting_job]->CompleteNow(OK); + + ASSERT_EQ(2u, resolver.pending_jobs().size()); + ASSERT_EQ(0u, resolver.cancelled_jobs().size()); + ASSERT_EQ(url, resolver.pending_jobs()[0]->url()); + ASSERT_EQ(url, resolver.pending_jobs()[1]->url()); +} + +// Test that the ProxyResolutionService correctly handles the case where a +// request callback deletes its own handle, when triggered by +// ProxyResolutionService's destructor. +TEST_F(ProxyResolutionServiceTest, CallbackDeletesSelfDuringDestructor) { + MockProxyConfigService* config_service = + new MockProxyConfigService("http://foopy/proxy.pac"); + + MockAsyncProxyResolver resolver; + MockAsyncProxyResolverFactory* factory = + new MockAsyncProxyResolverFactory(false); + + std::unique_ptr<ProxyResolutionService> service = + std::make_unique<ProxyResolutionService>( + base::WrapUnique(config_service), base::WrapUnique(factory), nullptr); + + GURL url("http://www.google.com/"); + ProxyInfo info; + + std::unique_ptr<ProxyResolutionService::Request> request1; + TestCompletionCallback callback1; + int rv = + service->ResolveProxy(url, std::string(), &info, callback1.callback(), + &request1, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + std::unique_ptr<ProxyResolutionService::Request> request2; + DeletingCallback<ProxyResolutionService::Request> callback2(&request2); + rv = service->ResolveProxy(url, std::string(), &info, callback2.callback(), + &request2, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + std::unique_ptr<ProxyResolutionService::Request> request3; + TestCompletionCallback callback3; + rv = service->ResolveProxy(url, std::string(), &info, callback3.callback(), + &request3, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + service.reset(); + + EXPECT_THAT(callback1.WaitForResult(), + IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED)); + EXPECT_THAT(callback2.WaitForResult(), + IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED)); + EXPECT_THAT(callback3.WaitForResult(), + IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED)); +} + +TEST_F(ProxyResolutionServiceTest, ProxyServiceDeletedBeforeRequest) { + MockProxyConfigService* config_service = + new MockProxyConfigService("http://foopy/proxy.pac"); + + MockAsyncProxyResolver resolver; + MockAsyncProxyResolverFactory* factory = + new MockAsyncProxyResolverFactory(false); + + GURL url("http://www.google.com/"); + + ProxyInfo info; + TestCompletionCallback callback; + std::unique_ptr<ProxyResolutionService::Request> request; + BoundTestNetLog log; + + int rv; + { + ProxyResolutionService service(base::WrapUnique(config_service), + base::WrapUnique(factory), nullptr); + rv = service.ResolveProxy(url, std::string(), &info, callback.callback(), + &request, nullptr, log.bound()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request->GetLoadState()); + + ASSERT_EQ(1u, factory->pending_requests().size()); + EXPECT_EQ(GURL("http://foopy/proxy.pac"), + factory->pending_requests()[0]->script_data()->url()); + factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver); + ASSERT_EQ(1u, resolver.pending_jobs().size()); + } + + ASSERT_EQ(0u, resolver.pending_jobs().size()); + + EXPECT_THAT(callback.WaitForResult(), IsOk()); +} + +// Test that the ProxyResolutionService correctly handles the case where a +// request callback deletes the service. +TEST_F(ProxyResolutionServiceTest, CallbackDeletesService) { + MockProxyConfigService* config_service = + new MockProxyConfigService("http://foopy/proxy.pac"); + + MockAsyncProxyResolver resolver; + MockAsyncProxyResolverFactory* factory = + new MockAsyncProxyResolverFactory(false); + + std::unique_ptr<ProxyResolutionService> service = + std::make_unique<ProxyResolutionService>( + base::WrapUnique(config_service), base::WrapUnique(factory), nullptr); + + GURL url("http://www.google.com/"); + + ProxyInfo info; + + DeletingCallback<ProxyResolutionService> callback(&service); + std::unique_ptr<ProxyResolutionService::Request> request1; + int rv = service->ResolveProxy(url, std::string(), &info, callback.callback(), + &request1, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request1->GetLoadState()); + + TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; + rv = service->ResolveProxy(url, std::string(), &info, callback2.callback(), + &request2, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + TestCompletionCallback callback3; + std::unique_ptr<ProxyResolutionService::Request> request3; + rv = service->ResolveProxy(url, std::string(), &info, callback3.callback(), + &request3, nullptr, NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + config_service->SetConfig(ProxyConfigWithAnnotation( + ProxyConfig::CreateDirect(), TRAFFIC_ANNOTATION_FOR_TESTS)); + + ASSERT_EQ(0u, resolver.pending_jobs().size()); + ASSERT_THAT(callback.WaitForResult(), IsOk()); + ASSERT_THAT(callback2.WaitForResult(), IsOk()); + ASSERT_THAT(callback3.WaitForResult(), IsOk()); +} + TEST_F(ProxyResolutionServiceTest, PAC) { MockProxyConfigService* config_service = new MockProxyConfigService("http://foopy/proxy.pac"); @@ -533,14 +873,14 @@ ProxyInfo info; TestCompletionCallback callback; - ProxyResolutionService::Request* request; + std::unique_ptr<ProxyResolutionService::Request> request; BoundTestNetLog log; int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(), &request, nullptr, log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request)); + EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request->GetLoadState()); ASSERT_EQ(1u, factory->pending_requests().size()); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -597,8 +937,9 @@ ProxyInfo info; TestCompletionCallback callback; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -628,8 +969,9 @@ ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -675,8 +1017,9 @@ ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -732,8 +1075,9 @@ ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -787,8 +1131,9 @@ GURL url("http://www.google.com/"); ProxyInfo info; TestCompletionCallback callback; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver); ASSERT_EQ(1u, resolver.pending_jobs().size()); @@ -826,8 +1171,9 @@ GURL url("http://www.google.com/"); ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -854,7 +1200,7 @@ // regardless of whether the first request failed in it. TestCompletionCallback callback2; rv = service.ResolveProxy(url, std::string(), &info, callback2.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, resolver.pending_jobs().size()); @@ -888,8 +1234,9 @@ GURL url("http://www.google.com/"); ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, factory->pending_requests().size()); @@ -919,7 +1266,7 @@ TestCompletionCallback callback2; rv = service.ResolveProxy(url, std::string(), &info, callback2.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, factory->pending_requests().size()); @@ -959,13 +1306,14 @@ GURL url2("https://www.google.com/"); ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1, request2; int rv = service.ResolveProxy(url1, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); TestCompletionCallback callback2; rv = service.ResolveProxy(url2, std::string(), &info, callback2.callback(), - nullptr, nullptr, NetLogWithSource()); + &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, factory->pending_requests().size()); @@ -1029,8 +1377,9 @@ GURL url("http://www.google.com/"); ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -1050,7 +1399,7 @@ // to DIRECT. TestCompletionCallback callback2; rv = service.ResolveProxy(url, std::string(), &info, callback2.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED)); EXPECT_FALSE(info.is_direct()); } @@ -1081,8 +1430,9 @@ GURL url("http://www.google.com/"); ProxyInfo info; TestCompletionCallback callback; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Check that nothing has been sent to the proxy resolver factory yet. @@ -1127,8 +1477,9 @@ GURL url("http://www.google.com/"); ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -1151,7 +1502,7 @@ // regardless of whether the first request failed in it. TestCompletionCallback callback2; rv = service.ResolveProxy(url, std::string(), &info, callback2.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, resolver.pending_jobs().size()); @@ -1186,8 +1537,9 @@ // Get the proxy information. ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -1232,7 +1584,7 @@ TestCompletionCallback callback3; rv = service.ResolveProxy(url, std::string(), &info, callback3.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, resolver.pending_jobs().size()); @@ -1279,7 +1631,7 @@ // Look up proxies again TestCompletionCallback callback7; rv = service.ResolveProxy(url, std::string(), &info, callback7.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, resolver.pending_jobs().size()); @@ -1320,8 +1672,9 @@ // Get the proxy information. ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -1381,8 +1734,10 @@ // Get the proxy information. ProxyInfo info; TestCompletionCallback callback1; + TestResolveProxyDelegate delegate1; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, &delegate1, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -1413,9 +1768,10 @@ // Fake a PAC failure. ProxyInfo info2; - TestCompletionCallback callback3; - rv = service.ResolveProxy(url, std::string(), &info2, callback3.callback(), - nullptr, nullptr, NetLogWithSource()); + TestCompletionCallback callback2; + TestResolveProxyDelegate delegate2; + rv = service.ResolveProxy(url, std::string(), &info2, callback2.callback(), + &request, &delegate2, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, resolver.pending_jobs().size()); @@ -1426,7 +1782,7 @@ // Although the resolver failed, the ProxyResolutionService will implicitly // fall-back to a DIRECT connection. - EXPECT_THAT(callback3.WaitForResult(), IsOk()); + EXPECT_THAT(callback2.WaitForResult(), IsOk()); EXPECT_TRUE(info2.is_direct()); EXPECT_FALSE(info2.is_empty()); @@ -1434,9 +1790,11 @@ // proxy list. Since we have not marked the configuration as bad, it should // "just work" the next time we call it. ProxyInfo info3; - TestCompletionCallback callback4; - rv = service.ResolveProxy(url, std::string(), &info3, callback4.callback(), - nullptr, nullptr, NetLogWithSource()); + TestCompletionCallback callback3; + TestResolveProxyDelegate delegate3; + std::unique_ptr<ProxyResolutionService::Request> request3; + rv = service.ResolveProxy(url, std::string(), &info3, callback3.callback(), + &request3, &delegate3, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, resolver.pending_jobs().size()); @@ -1448,7 +1806,7 @@ // The first proxy was deprioritized since it was added to the bad proxies // list by the earlier ReportSuccess(). - EXPECT_THAT(callback4.WaitForResult(), IsOk()); + EXPECT_THAT(callback3.WaitForResult(), IsOk()); EXPECT_FALSE(info3.is_direct()); EXPECT_EQ("foopy2:9090", info3.proxy_server().ToURI()); EXPECT_EQ(2u, info3.proxy_list().size()); @@ -1456,6 +1814,10 @@ EXPECT_FALSE(info.proxy_resolve_start_time().is_null()); EXPECT_FALSE(info.proxy_resolve_end_time().is_null()); EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time()); + + EXPECT_TRUE(delegate1.on_resolve_proxy_called()); + EXPECT_TRUE(delegate2.on_resolve_proxy_called()); + EXPECT_TRUE(delegate3.on_resolve_proxy_called()); } TEST_F(ProxyResolutionServiceTest, ProxyFallback_BadConfigMandatory) { @@ -1479,8 +1841,9 @@ // Get the proxy information. ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -1512,8 +1875,9 @@ // Fake a PAC failure. ProxyInfo info2; TestCompletionCallback callback3; + std::unique_ptr<ProxyResolutionService::Request> request3; rv = service.ResolveProxy(url, std::string(), &info2, callback3.callback(), - nullptr, nullptr, NetLogWithSource()); + &request3, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, resolver.pending_jobs().size()); @@ -1534,8 +1898,9 @@ // "just work" the next time we call it. ProxyInfo info3; TestCompletionCallback callback4; + std::unique_ptr<ProxyResolutionService::Request> request4; rv = service.ResolveProxy(url, std::string(), &info3, callback4.callback(), - nullptr, nullptr, NetLogWithSource()); + &request4, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_EQ(1u, resolver.pending_jobs().size()); @@ -1569,17 +1934,19 @@ int rv; GURL url1("http://www.webkit.org"); GURL url2("http://www.webkit.com"); + std::unique_ptr<ProxyResolutionService::Request> request1; + std::unique_ptr<ProxyResolutionService::Request> request2; // Request for a .org domain should bypass proxy. rv = service.ResolveProxy(url1, std::string(), &info[0], - callback[0].callback(), nullptr, nullptr, + callback[0].callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(info[0].is_direct()); // Request for a .com domain hits the proxy. rv = service.ResolveProxy(url2, std::string(), &info[1], - callback[1].callback(), nullptr, nullptr, + callback[1].callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI()); @@ -1624,6 +1991,7 @@ ProxyConfig config; config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080"); config.set_auto_detect(false); + std::unique_ptr<ProxyResolutionService::Request> request; { ProxyResolutionService service( std::make_unique<MockProxyConfigService>(config), nullptr, nullptr); @@ -1631,7 +1999,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_FALSE(info.is_direct()); @@ -1644,7 +2012,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(info.is_direct()); @@ -1657,7 +2025,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_FALSE(info.is_direct()); @@ -1671,7 +2039,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_FALSE(info.is_direct()); @@ -1683,6 +2051,7 @@ // Test that the proxy config source is set correctly when resolving proxies // using manual proxy rules. Namely, the config source should only be set if // any of the rules were applied. + std::unique_ptr<ProxyResolutionService::Request> request; { ProxyConfig config; config.proxy_rules().ParseFromString("https=foopy2:8080"); @@ -1692,7 +2061,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); ASSERT_THAT(rv, IsOk()); // Should be test, even if there are no HTTP proxies configured. @@ -1708,7 +2077,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); ASSERT_THAT(rv, IsOk()); // Used the HTTPS proxy. So traffic annotation should test. @@ -1723,7 +2092,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); ASSERT_THAT(rv, IsOk()); // ProxyConfig is empty. Traffic annotation should still be TEST. @@ -1741,6 +2110,7 @@ EXPECT_EQ(ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME, config.proxy_rules().type); + std::unique_ptr<ProxyResolutionService::Request> request; { ProxyResolutionService service( std::make_unique<MockProxyConfigService>(config), nullptr, nullptr); @@ -1748,7 +2118,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_FALSE(info.is_direct()); @@ -1761,7 +2131,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_FALSE(info.is_direct()); @@ -1774,7 +2144,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_FALSE(info.is_direct()); @@ -1787,7 +2157,7 @@ ProxyInfo info; TestCompletionCallback callback; int rv = service.ResolveProxy(test_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_FALSE(info.is_direct()); @@ -1814,9 +2184,10 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url1, std::string(), &info1, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Successfully initialize the PAC script. @@ -1828,7 +2199,7 @@ ProxyInfo info2; TestCompletionCallback callback2; - ProxyResolutionService::Request* request2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -1837,13 +2208,14 @@ ProxyInfo info3; TestCompletionCallback callback3; + std::unique_ptr<ProxyResolutionService::Request> request3; rv = service.ResolveProxy(url3, std::string(), &info3, callback3.callback(), - nullptr, nullptr, NetLogWithSource()); + &request3, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); GetPendingJobsForURLs(resolver, url1, url2, url3); // Cancel the second request - service.CancelRequest(request2); + request2.reset(); JobMap jobs = GetPendingJobsForURLs(resolver, url1, url3); @@ -1888,7 +2260,7 @@ ProxyInfo info1; TestCompletionCallback callback1; - ProxyResolutionService::Request* request1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url1, std::string(), &info1, callback1.callback(), &request1, nullptr, NetLogWithSource()); @@ -1900,14 +2272,14 @@ ProxyInfo info2; TestCompletionCallback callback2; - ProxyResolutionService::Request* request2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ProxyInfo info3; TestCompletionCallback callback3; - ProxyResolutionService::Request* request3; + std::unique_ptr<ProxyResolutionService::Request> request3; rv = service.ResolveProxy(url3, std::string(), &info3, callback3.callback(), &request3, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -1915,9 +2287,9 @@ // Nothing has been sent to the factory yet. EXPECT_TRUE(factory->pending_requests().empty()); - EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, service.GetLoadState(request1)); - EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, service.GetLoadState(request2)); - EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, service.GetLoadState(request3)); + EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, request1->GetLoadState()); + EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, request2->GetLoadState()); + EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, request3->GetLoadState()); // At this point the ProxyResolutionService should be waiting for the // PacFileFetcher to invoke its completion callback, notifying it of @@ -1932,9 +2304,9 @@ JobMap jobs = GetPendingJobsForURLs(resolver, url1, url2, url3); - EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request1)); - EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request2)); - EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request3)); + EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request1->GetLoadState()); + EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request2->GetLoadState()); + EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request3->GetLoadState()); // Complete all the jobs (in some order). @@ -1993,9 +2365,10 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url1, std::string(), &info1, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // The first request should have triggered download of PAC script. @@ -2004,8 +2377,9 @@ ProxyInfo info2; TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(), - nullptr, nullptr, NetLogWithSource()); + &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // At this point the ProxyResolutionService should be waiting for the @@ -2052,7 +2426,7 @@ // Start 3 requests. ProxyInfo info1; TestCompletionCallback callback1; - ProxyResolutionService::Request* request1; + std::unique_ptr<ProxyResolutionService::Request> request1; BoundTestNetLog log1; int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1, callback1.callback(), &request1, nullptr, @@ -2065,7 +2439,7 @@ ProxyInfo info2; TestCompletionCallback callback2; - ProxyResolutionService::Request* request2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2, callback2.callback(), &request2, nullptr, NetLogWithSource()); @@ -2073,8 +2447,9 @@ ProxyInfo info3; TestCompletionCallback callback3; + std::unique_ptr<ProxyResolutionService::Request> request3; rv = service.ResolveProxy(GURL("http://request3"), std::string(), &info3, - callback3.callback(), nullptr, nullptr, + callback3.callback(), &request3, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2082,8 +2457,8 @@ EXPECT_TRUE(factory->pending_requests().empty()); // Cancel the first 2 jobs. - service.CancelRequest(request1); - service.CancelRequest(request2); + request1.reset(); + request2.reset(); // At this point the ProxyResolutionService should be waiting for the // PacFileFetcher to invoke its completion callback, notifying it of @@ -2153,14 +2528,15 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url1, std::string(), &info1, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ProxyInfo info2; TestCompletionCallback callback2; - ProxyResolutionService::Request* request2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2236,14 +2612,15 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(url1, std::string(), &info1, callback1.callback(), - nullptr, nullptr, NetLogWithSource()); + &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ProxyInfo info2; TestCompletionCallback callback2; - ProxyResolutionService::Request* request2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2312,14 +2689,15 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1, - callback1.callback(), nullptr, nullptr, + callback1.callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ProxyInfo info2; TestCompletionCallback callback2; - ProxyResolutionService::Request* request2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2, callback2.callback(), &request2, nullptr, NetLogWithSource()); @@ -2374,9 +2752,10 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://www.google.com"), std::string(), - &info1, callback1.callback(), nullptr, nullptr, - NetLogWithSource()); + &info1, callback1.callback(), &request1, + nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Check that nothing has been sent to the proxy resolver factory yet. @@ -2405,8 +2784,9 @@ // Start another request, it should pickup the bypass item. ProxyInfo info2; TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://www.google.com"), std::string(), - &info2, callback2.callback(), nullptr, nullptr, + &info2, callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2444,9 +2824,10 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://www.google.com"), std::string(), - &info1, callback1.callback(), nullptr, nullptr, - NetLogWithSource()); + &info1, callback1.callback(), &request1, + nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Check that nothing has been sent to the proxy resolver factory yet. @@ -2477,8 +2858,9 @@ ProxyInfo info; TestCompletionCallback callback; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_EQ(GURL("http://foopy/proxy.pac"), @@ -2494,8 +2876,9 @@ ProxyInfo info; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info, - callback1.callback(), nullptr, nullptr, + callback1.callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); @@ -2505,8 +2888,9 @@ config2.set_auto_detect(false); service.ResetConfigService(std::make_unique<MockProxyConfigService>(config2)); TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info, - callback2.callback(), nullptr, nullptr, + callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI()); @@ -2528,9 +2912,10 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://www.google.com"), std::string(), - &info1, callback1.callback(), nullptr, nullptr, - NetLogWithSource()); + &info1, callback1.callback(), &request1, + nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Successfully set the autodetect script. @@ -2557,8 +2942,9 @@ // Start another request -- the effective configuration has changed. ProxyInfo info2; TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://www.google.com"), std::string(), - &info2, callback2.callback(), nullptr, nullptr, + &info2, callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); @@ -2590,8 +2976,9 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1, - callback1.callback(), nullptr, nullptr, + callback1.callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2633,8 +3020,9 @@ // Start a second request. ProxyInfo info2; TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2, - callback2.callback(), nullptr, nullptr, + callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2708,8 +3096,9 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1, - callback1.callback(), nullptr, nullptr, + callback1.callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2769,8 +3158,9 @@ // Start a second request. ProxyInfo info2; TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2, - callback2.callback(), nullptr, nullptr, + callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2815,8 +3205,9 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1, - callback1.callback(), nullptr, nullptr, + callback1.callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2882,8 +3273,9 @@ // Start a second request. ProxyInfo info2; TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2, - callback2.callback(), nullptr, nullptr, + callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2928,8 +3320,9 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1, - callback1.callback(), nullptr, nullptr, + callback1.callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2992,8 +3385,9 @@ // Start a second request. ProxyInfo info2; TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2, - callback2.callback(), nullptr, nullptr, + callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -3038,8 +3432,9 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1, - callback1.callback(), nullptr, nullptr, + callback1.callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -3099,8 +3494,9 @@ // Start a second request. ProxyInfo info2; TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2, - callback2.callback(), nullptr, nullptr, + callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(info2.is_direct()); @@ -3201,8 +3597,9 @@ ProxyInfo info1; TestCompletionCallback callback1; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1, - callback1.callback(), nullptr, nullptr, + callback1.callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -3246,8 +3643,9 @@ // Start a second request. ProxyInfo info2; TestCompletionCallback callback2; + std::unique_ptr<ProxyResolutionService::Request> request2; rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2, - callback2.callback(), nullptr, nullptr, + callback2.callback(), &request2, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -3277,8 +3675,9 @@ // since the PAC script poller experienced a failure. ProxyInfo info3; TestCompletionCallback callback3; + std::unique_ptr<ProxyResolutionService::Request> request3; rv = service.ResolveProxy(GURL("http://request3"), std::string(), &info3, - callback3.callback(), nullptr, nullptr, + callback3.callback(), &request3, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(info3.is_direct()); @@ -3359,9 +3758,10 @@ ProxyInfo info; TestCompletionCallback callback; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service_->ResolveProxy(url, std::string(), &info, callback.callback(), - nullptr, nullptr, NetLogWithSource()); + &request, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // First step is to download the PAC script. @@ -3391,8 +3791,9 @@ // Issue a request and see what URL is sent to the proxy resolver. ProxyInfo info; TestCompletionCallback callback; + std::unique_ptr<ProxyResolutionService::Request> request1; int rv = service_->ResolveProxy(raw_url, std::string(), &info, - callback.callback(), nullptr, nullptr, + callback.callback(), &request1, nullptr, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -3575,7 +3976,7 @@ ProxyInfo info; TestCompletionCallback callback; - ProxyResolutionService::Request* request; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(GURL("http://request/"), std::string(), &info, callback.callback(), &request, nullptr, NetLogWithSource()); @@ -3610,7 +4011,7 @@ ProxyInfo info; TestCompletionCallback callback; - ProxyResolutionService::Request* request; + std::unique_ptr<ProxyResolutionService::Request> request; int rv = service.ResolveProxy(GURL("http://request/"), std::string(), &info, callback.callback(), &request, nullptr, NetLogWithSource());
diff --git a/net/socket/udp_socket_posix.cc b/net/socket/udp_socket_posix.cc index 7605385..cb98312 100644 --- a/net/socket/udp_socket_posix.cc +++ b/net/socket/udp_socket_posix.cc
@@ -1023,8 +1023,9 @@ case IPAddress::kIPv4AddressSize: { if (addr_family_ != AF_INET) return ERR_ADDRESS_INVALID; - ip_mreq mreq = {}; - mreq.imr_interface.s_addr = INADDR_ANY; + ip_mreqn mreq = {}; + mreq.imr_ifindex = multicast_interface_; + mreq.imr_address.s_addr = INADDR_ANY; memcpy(&mreq.imr_multiaddr, group_address.bytes().data(), IPAddress::kIPv4AddressSize); int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP,
diff --git a/net/third_party/quic/core/http/end_to_end_test.cc b/net/third_party/quic/core/http/end_to_end_test.cc index 947afcb..df26fb2b8 100644 --- a/net/third_party/quic/core/http/end_to_end_test.cc +++ b/net/third_party/quic/core/http/end_to_end_test.cc
@@ -11,7 +11,6 @@ #include <utility> #include <vector> -#include "net/test/test_with_scoped_task_environment.h" #include "net/third_party/quic/core/crypto/null_encrypter.h" #include "net/third_party/quic/core/http/quic_spdy_client_stream.h" #include "net/third_party/quic/core/quic_epoll_connection_helper.h" @@ -263,8 +262,7 @@ QuicClient* client_; }; -class EndToEndTest : public QuicTestWithParam<TestParams>, - public net::WithScopedTaskEnvironment { +class EndToEndTest : public QuicTestWithParam<TestParams> { protected: EndToEndTest() : initialized_(false), @@ -594,6 +592,7 @@ *client_->client()->client_session(), n); } + ScopedEnvironmentForThreads environment_; bool initialized_; QuicSocketAddress server_address_; QuicString server_hostname_;
diff --git a/net/third_party/quic/platform/api/quic_test.h b/net/third_party/quic/platform/api/quic_test.h index 5f0f3c5..979c785 100644 --- a/net/third_party/quic/platform/api/quic_test.h +++ b/net/third_party/quic/platform/api/quic_test.h
@@ -14,4 +14,7 @@ template <class T> using QuicTestWithParam = QuicTestWithParamImpl<T>; +// Class which needs to be instantiated in tests which use threads. +using ScopedEnvironmentForThreads = ScopedEnvironmentForThreadsImpl; + #endif // NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_TEST_H_
diff --git a/net/third_party/quic/platform/impl/quic_test_impl.h b/net/third_party/quic/platform/impl/quic_test_impl.h index fe743104..1117842 100644 --- a/net/third_party/quic/platform/impl/quic_test_impl.h +++ b/net/third_party/quic/platform/impl/quic_test_impl.h
@@ -7,6 +7,7 @@ #include "base/logging.h" #include "net/third_party/quic/platform/api/quic_flags.h" +#include "net/test/test_with_scoped_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" // IWYU pragma: export #include "testing/gtest/include/gtest/gtest.h" // IWYU pragma: export @@ -50,4 +51,14 @@ QuicFlagSaverImpl saver_; // Save/restore all QUIC flag values. }; +class ScopedEnvironmentForThreadsImpl { + public: + ScopedEnvironmentForThreadsImpl() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO) {} + + public: + base::test::ScopedTaskEnvironment scoped_task_environment_; +}; + #endif // NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_TEST_IMPL_H_
diff --git a/net/third_party/quic/quartc/quartc_clock_interface.h b/net/third_party/quic/quartc/quartc_clock_interface.h deleted file mode 100644 index 53366d70..0000000 --- a/net/third_party/quic/quartc/quartc_clock_interface.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright (c) 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_CLOCK_INTERFACE_H_ -#define NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_CLOCK_INTERFACE_H_ - -#include <stdint.h> - -namespace quic { - -// Implemented by the Quartc API user to provide a timebase. -class QuartcClockInterface { - public: - virtual ~QuartcClockInterface() {} - virtual int64_t NowMicroseconds() = 0; -}; - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_CLOCK_INTERFACE_H_
diff --git a/net/third_party/quic/quartc/quartc_factory.cc b/net/third_party/quic/quartc/quartc_factory.cc index 099808c..e5e0287e 100644 --- a/net/third_party/quic/quartc/quartc_factory.cc +++ b/net/third_party/quic/quartc/quartc_factory.cc
@@ -11,106 +11,17 @@ namespace quic { -namespace { - -// Implements the QuicAlarm with QuartcTaskRunnerInterface for the Quartc -// users other than Chromium. For example, WebRTC will create QuartcAlarm with -// a QuartcTaskRunner implemented by WebRTC. -class QuartcAlarm : public QuicAlarm, public QuartcTaskRunnerInterface::Task { - public: - QuartcAlarm(const QuicClock* clock, - QuartcTaskRunnerInterface* task_runner, - QuicArenaScopedPtr<QuicAlarm::Delegate> delegate) - : QuicAlarm(std::move(delegate)), - clock_(clock), - task_runner_(task_runner) {} - - ~QuartcAlarm() override { - // Cancel the scheduled task before getting deleted. - CancelImpl(); - } - - // QuicAlarm overrides. - void SetImpl() override { - DCHECK(deadline().IsInitialized()); - // Cancel it if already set. - CancelImpl(); - - int64_t delay_ms = (deadline() - (clock_->Now())).ToMilliseconds(); - if (delay_ms < 0) { - delay_ms = 0; - } - - DCHECK(task_runner_); - DCHECK(!scheduled_task_); - scheduled_task_ = task_runner_->Schedule(this, delay_ms); - } - - void CancelImpl() override { - if (scheduled_task_) { - scheduled_task_->Cancel(); - scheduled_task_.reset(); - } - } - - // QuartcTaskRunner::Task overrides. - void Run() override { - // The alarm may have been cancelled. - if (!deadline().IsInitialized()) { - return; - } - - // The alarm may have been re-set to a later time. - if (clock_->Now() < deadline()) { - SetImpl(); - return; - } - - Fire(); - } - - private: - // Not owned by QuartcAlarm. Owned by the QuartcFactory. - const QuicClock* clock_; - // Not owned by QuartcAlarm. Owned by the QuartcFactory. - QuartcTaskRunnerInterface* task_runner_; - // Owned by QuartcAlarm. - std::unique_ptr<QuartcTaskRunnerInterface::ScheduledTask> scheduled_task_; -}; - -// Adapts QuartcClockInterface (provided by the user) to QuicClock -// (expected by QUIC). -class QuartcClock : public QuicClock { - public: - explicit QuartcClock(QuartcClockInterface* clock) : clock_(clock) {} - QuicTime ApproximateNow() const override { return Now(); } - QuicTime Now() const override { - return QuicTime::Zero() + - QuicTime::Delta::FromMicroseconds(clock_->NowMicroseconds()); - } - QuicWallTime WallNow() const override { - return QuicWallTime::FromUNIXMicroseconds(clock_->NowMicroseconds()); - } - - private: - QuartcClockInterface* clock_; -}; - -} // namespace - QuartcFactory::QuartcFactory(const QuartcFactoryConfig& factory_config) - : task_runner_(factory_config.task_runner), - clock_(new QuartcClock(factory_config.clock)) {} + : alarm_factory_(factory_config.alarm_factory), + clock_(factory_config.clock) {} QuartcFactory::~QuartcFactory() {} -std::unique_ptr<QuartcSessionInterface> QuartcFactory::CreateQuartcSession( +std::unique_ptr<QuartcSession> QuartcFactory::CreateQuartcSession( const QuartcSessionConfig& quartc_session_config) { DCHECK(quartc_session_config.packet_transport); - Perspective perspective = quartc_session_config.is_server - ? Perspective::IS_SERVER - : Perspective::IS_CLIENT; + Perspective perspective = quartc_session_config.perspective; // QuartcSession will eventually own both |writer| and |quic_connection|. auto writer = @@ -135,53 +46,50 @@ // Enable time-based loss detection. copt.push_back(kTIME); - if (quartc_session_config.congestion_control == - QuartcCongestionControl::kBBR) { - copt.push_back(kTBBR); + copt.push_back(kTBBR); - // Note: These settings have no effect for Exoblaze builds since - // SetQuicReloadableFlag() gets stubbed out. - SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true); - SetQuicReloadableFlag(quic_unified_iw_options, true); - for (const auto option : quartc_session_config.bbr_options) { - switch (option) { - case (QuartcBbrOptions::kSlowerStartup): - copt.push_back(kBBRS); - break; - case (QuartcBbrOptions::kFullyDrainQueue): - copt.push_back(kBBR3); - break; - case (QuartcBbrOptions::kReduceProbeRtt): - copt.push_back(kBBR6); - break; - case (QuartcBbrOptions::kSkipProbeRtt): - copt.push_back(kBBR7); - break; - case (QuartcBbrOptions::kSkipProbeRttAggressively): - copt.push_back(kBBR8); - break; - case (QuartcBbrOptions::kFillUpLinkDuringProbing): - quic_connection->set_fill_up_link_during_probing(true); - break; - case (QuartcBbrOptions::kInitialWindow3): - copt.push_back(kIW03); - break; - case (QuartcBbrOptions::kInitialWindow10): - copt.push_back(kIW10); - break; - case (QuartcBbrOptions::kInitialWindow20): - copt.push_back(kIW20); - break; - case (QuartcBbrOptions::kInitialWindow50): - copt.push_back(kIW50); - break; - case (QuartcBbrOptions::kStartup1RTT): - copt.push_back(k1RTT); - break; - case (QuartcBbrOptions::kStartup2RTT): - copt.push_back(k2RTT); - break; - } + // Note: These settings have no effect for Exoblaze builds since + // SetQuicReloadableFlag() gets stubbed out. + SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true); + SetQuicReloadableFlag(quic_unified_iw_options, true); + for (const auto option : quartc_session_config.bbr_options) { + switch (option) { + case (QuartcBbrOptions::kSlowerStartup): + copt.push_back(kBBRS); + break; + case (QuartcBbrOptions::kFullyDrainQueue): + copt.push_back(kBBR3); + break; + case (QuartcBbrOptions::kReduceProbeRtt): + copt.push_back(kBBR6); + break; + case (QuartcBbrOptions::kSkipProbeRtt): + copt.push_back(kBBR7); + break; + case (QuartcBbrOptions::kSkipProbeRttAggressively): + copt.push_back(kBBR8); + break; + case (QuartcBbrOptions::kFillUpLinkDuringProbing): + quic_connection->set_fill_up_link_during_probing(true); + break; + case (QuartcBbrOptions::kInitialWindow3): + copt.push_back(kIW03); + break; + case (QuartcBbrOptions::kInitialWindow10): + copt.push_back(kIW10); + break; + case (QuartcBbrOptions::kInitialWindow20): + copt.push_back(kIW20); + break; + case (QuartcBbrOptions::kInitialWindow50): + copt.push_back(kIW50); + break; + case (QuartcBbrOptions::kStartup1RTT): + copt.push_back(k1RTT); + break; + case (QuartcBbrOptions::kStartup2RTT): + copt.push_back(k2RTT); + break; } } QuicConfig quic_config; @@ -202,15 +110,15 @@ kStreamReceiveWindowLimit); quic_config.SetConnectionOptionsToSend(copt); quic_config.SetClientConnectionOptions(copt); - if (quartc_session_config.max_time_before_crypto_handshake_secs > 0) { + if (quartc_session_config.max_time_before_crypto_handshake > + QuicTime::Delta::Zero()) { quic_config.set_max_time_before_crypto_handshake( - QuicTime::Delta::FromSeconds( - quartc_session_config.max_time_before_crypto_handshake_secs)); + quartc_session_config.max_time_before_crypto_handshake); } - if (quartc_session_config.max_idle_time_before_crypto_handshake_secs > 0) { + if (quartc_session_config.max_idle_time_before_crypto_handshake > + QuicTime::Delta::Zero()) { quic_config.set_max_idle_time_before_crypto_handshake( - QuicTime::Delta::FromSeconds( - quartc_session_config.max_idle_time_before_crypto_handshake_secs)); + quartc_session_config.max_idle_time_before_crypto_handshake); } if (quartc_session_config.idle_network_timeout > QuicTime::Delta::Zero()) { quic_config.SetIdleNetworkTimeout( @@ -224,7 +132,7 @@ return QuicMakeUnique<QuartcSession>( std::move(quic_connection), quic_config, quartc_session_config.unique_remote_server_id, perspective, - this /*QuicConnectionHelperInterface*/, clock_.get(), std::move(writer)); + this /*QuicConnectionHelperInterface*/, clock_, std::move(writer)); } std::unique_ptr<QuicConnection> QuartcFactory::CreateQuicConnection( @@ -236,28 +144,12 @@ QuicSocketAddress dummy_address(QuicIpAddress::Any4(), 0 /*Port*/); return QuicMakeUnique<QuicConnection>( dummy_id, dummy_address, this, /*QuicConnectionHelperInterface*/ - this /*QuicAlarmFactory*/, packet_writer, /*owns_writer=*/false, + alarm_factory_ /*QuicAlarmFactory*/, packet_writer, /*owns_writer=*/false, perspective, CurrentSupportedVersions()); } -QuicAlarm* QuartcFactory::CreateAlarm(QuicAlarm::Delegate* delegate) { - return new QuartcAlarm(GetClock(), task_runner_, - QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate)); -} - -QuicArenaScopedPtr<QuicAlarm> QuartcFactory::CreateAlarm( - QuicArenaScopedPtr<QuicAlarm::Delegate> delegate, - QuicConnectionArena* arena) { - if (arena != nullptr) { - return arena->New<QuartcAlarm>(GetClock(), task_runner_, - std::move(delegate)); - } - return QuicArenaScopedPtr<QuicAlarm>( - new QuartcAlarm(GetClock(), task_runner_, std::move(delegate))); -} - const QuicClock* QuartcFactory::GetClock() const { - return clock_.get(); + return clock_; } QuicRandom* QuartcFactory::GetRandomGenerator() { @@ -268,10 +160,9 @@ return &buffer_allocator_; } -std::unique_ptr<QuartcFactoryInterface> CreateQuartcFactory( +std::unique_ptr<QuartcFactory> CreateQuartcFactory( const QuartcFactoryConfig& factory_config) { - return std::unique_ptr<QuartcFactoryInterface>( - new QuartcFactory(factory_config)); + return std::unique_ptr<QuartcFactory>(new QuartcFactory(factory_config)); } } // namespace quic
diff --git a/net/third_party/quic/quartc/quartc_factory.h b/net/third_party/quic/quartc/quartc_factory.h index f56c2499..8db0340 100644 --- a/net/third_party/quic/quartc/quartc_factory.h +++ b/net/third_party/quic/quartc/quartc_factory.h
@@ -8,34 +8,83 @@ #include "net/third_party/quic/core/quic_alarm_factory.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_simple_buffer_allocator.h" -#include "net/third_party/quic/platform/api/quic_export.h" -#include "net/third_party/quic/quartc/quartc_factory_interface.h" #include "net/third_party/quic/quartc/quartc_packet_writer.h" -#include "net/third_party/quic/quartc/quartc_task_runner_interface.h" +#include "net/third_party/quic/quartc/quartc_session.h" namespace quic { -// Implements the QuartcFactoryInterface to create the instances of -// QuartcSessionInterface. Implements the QuicAlarmFactory to create alarms -// using the QuartcTaskRunner. Implements the QuicConnectionHelperInterface used -// by the QuicConnections. Only one QuartcFactory is expected to be created. -class QUIC_EXPORT_PRIVATE QuartcFactory : public QuartcFactoryInterface, - public QuicAlarmFactory, - public QuicConnectionHelperInterface { +// Options that control the BBR algorithm. +enum class QuartcBbrOptions { + kSlowerStartup, // Once a loss is encountered in STARTUP, + // switches startup to a 1.5x pacing gain. + kFullyDrainQueue, // Fully drains the queue once per cycle. + kReduceProbeRtt, // Probe RTT reduces CWND to 0.75 * BDP instead of 4 + // packets. + kSkipProbeRtt, // Skip Probe RTT and extend the existing min_rtt if a + // recent min_rtt is within 12.5% of the current min_rtt. + kSkipProbeRttAggressively, // Skip ProbeRTT and extend the existing min_rtt + // as long as you've been app limited at least + // once. + kFillUpLinkDuringProbing, // Sends probing retransmissions whenever we + // become application limited. + kInitialWindow3, // Use a 3-packet initial congestion window. + kInitialWindow10, // Use a 10-packet initial congestion window. + kInitialWindow20, // Use a 20-packet initial congestion window. + kInitialWindow50, // Use a 50-packet initial congestion window. + kStartup1RTT, // Stay in STARTUP for 1 RTT. + kStartup2RTT, // Stay in STARTUP for 2 RTTs. +}; + +// The configuration for creating a QuartcFactory. +struct QuartcFactoryConfig { + // Factory for |QuicAlarm|s. Implemented by the Quartc user with different + // mechanisms. For example in WebRTC, it is implemented with rtc::Thread. + // Owned by the user, and needs to stay alive for as long as the QuartcFactory + // exists. + QuicAlarmFactory* alarm_factory = nullptr; + // The clock used by |QuicAlarm|s. Implemented by the Quartc user. Owned by + // the user, and needs to stay alive for as long as the QuartcFactory exists. + QuicClock* clock = nullptr; +}; + +struct QuartcSessionConfig { + // When using Quartc, there are two endpoints. The QuartcSession on one + // endpoint must act as a server and the one on the other side must act as a + // client. + Perspective perspective = Perspective::IS_CLIENT; + // This is only needed when is_server = false. It must be unique + // for each endpoint the local endpoint may communicate with. For example, + // a WebRTC client could use the remote endpoint's crypto fingerprint + QuicString unique_remote_server_id; + // The way the QuicConnection will send and receive packets, like a virtual + // UDP socket. For WebRTC, this will typically be an IceTransport. + QuartcPacketTransport* packet_transport = nullptr; + // The maximum size of the packet can be written with the packet writer. + // 1200 bytes by default. + QuicPacketLength max_packet_size = 1200; + // Options to control the BBR algorithm. In case the congestion control is + // set to anything but BBR, these options are ignored. + std::vector<QuartcBbrOptions> bbr_options; + // Timeouts for the crypto handshake. Set them to higher values to + // prevent closing the session before it started on a slow network. + // Zero entries are ignored and QUIC defaults are used in that case. + QuicTime::Delta max_idle_time_before_crypto_handshake = + QuicTime::Delta::Zero(); + QuicTime::Delta max_time_before_crypto_handshake = QuicTime::Delta::Zero(); + QuicTime::Delta idle_network_timeout = QuicTime::Delta::Zero(); +}; + +// Factory that creates instances of QuartcSession. Implements the +// QuicConnectionHelperInterface used by the QuicConnections. Only one +// QuartcFactory is expected to be created. +class QUIC_EXPORT_PRIVATE QuartcFactory : public QuicConnectionHelperInterface { public: explicit QuartcFactory(const QuartcFactoryConfig& factory_config); ~QuartcFactory() override; - // QuartcFactoryInterface overrides. - std::unique_ptr<QuartcSessionInterface> CreateQuartcSession( - const QuartcSessionConfig& quartc_session_config) override; - - // QuicAlarmFactory overrides. - QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override; - - QuicArenaScopedPtr<QuicAlarm> CreateAlarm( - QuicArenaScopedPtr<QuicAlarm::Delegate> delegate, - QuicConnectionArena* arena) override; + // Creates a new QuartcSession using the given configuration. + std::unique_ptr<QuartcSession> CreateQuartcSession( + const QuartcSessionConfig& quartc_session_config); // QuicConnectionHelperInterface overrides. const QuicClock* GetClock() const override; @@ -49,15 +98,19 @@ Perspective perspective, QuartcPacketWriter* packet_writer); - // Used to implement QuicAlarmFactory.. - QuartcTaskRunnerInterface* task_runner_; - // Used to implement the QuicConnectionHelperInterface. - // The QuicClock wrapper held in this variable is owned by QuartcFactory, - // but the QuartcClockInterface inside of it belongs to the user! - std::unique_ptr<QuicClock> clock_; + // Used to implement QuicAlarmFactory. Owned by the user and must outlive + // QuartcFactory. + QuicAlarmFactory* alarm_factory_; + // Used to implement the QuicConnectionHelperInterface. Owned by the user and + // must outlive QuartcFactory. + QuicClock* clock_; SimpleBufferAllocator buffer_allocator_; }; +// Creates a new instance of QuartcFactory. +std::unique_ptr<QuartcFactory> CreateQuartcFactory( + const QuartcFactoryConfig& factory_config); + } // namespace quic #endif // NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_FACTORY_H_
diff --git a/net/third_party/quic/quartc/quartc_factory_interface.cc b/net/third_party/quic/quartc/quartc_factory_interface.cc deleted file mode 100644 index 12897fa..0000000 --- a/net/third_party/quic/quartc/quartc_factory_interface.cc +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright (c) 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/third_party/quic/quartc/quartc_factory_interface.h" - -namespace quic { - -QuartcFactoryInterface::QuartcSessionConfig::QuartcSessionConfig() = default; -QuartcFactoryInterface::QuartcSessionConfig::~QuartcSessionConfig() = default; - -} // namespace quic
diff --git a/net/third_party/quic/quartc/quartc_factory_interface.h b/net/third_party/quic/quartc/quartc_factory_interface.h deleted file mode 100644 index 8013bc9..0000000 --- a/net/third_party/quic/quartc/quartc_factory_interface.h +++ /dev/null
@@ -1,108 +0,0 @@ -// Copyright (c) 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_FACTORY_INTERFACE_H_ -#define NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_FACTORY_INTERFACE_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <memory> - -#include "net/third_party/quic/platform/api/quic_export.h" -#include "net/third_party/quic/quartc/quartc_clock_interface.h" -#include "net/third_party/quic/quartc/quartc_session_interface.h" -#include "net/third_party/quic/quartc/quartc_task_runner_interface.h" - -namespace quic { - -// Algorithm to use for congestion control. -enum class QuartcCongestionControl { - kDefault, // Use an arbitrary algorithm chosen by QUIC. - kBBR, // Use BBR. -}; - -// Options that control the BBR algorithm. -enum class QuartcBbrOptions { - kSlowerStartup, // Once a loss is encountered in STARTUP, - // switches startup to a 1.5x pacing gain. - kFullyDrainQueue, // Fully drains the queue once per cycle. - kReduceProbeRtt, // Probe RTT reduces CWND to 0.75 * BDP instead of 4 - // packets. - kSkipProbeRtt, // Skip Probe RTT and extend the existing min_rtt if a - // recent min_rtt is within 12.5% of the current min_rtt. - kSkipProbeRttAggressively, // Skip ProbeRTT and extend the existing min_rtt - // as long as you've been app limited at least - // once. - kFillUpLinkDuringProbing, // Sends probing retransmissions whenever we - // become application limited. - kInitialWindow3, // Use a 3-packet initial congestion window. - kInitialWindow10, // Use a 10-packet initial congestion window. - kInitialWindow20, // Use a 20-packet initial congestion window. - kInitialWindow50, // Use a 50-packet initial congestion window. - kStartup1RTT, // Stay in STARTUP for 1 RTT. - kStartup2RTT, // Stay in STARTUP for 2 RTTs. -}; - -// Used to create instances for Quartc objects such as QuartcSession. -class QUIC_EXPORT_PRIVATE QuartcFactoryInterface { - public: - virtual ~QuartcFactoryInterface() {} - - struct QuartcSessionConfig { - QuartcSessionConfig(); - ~QuartcSessionConfig(); - - // When using Quartc, there are two endpoints. The QuartcSession on one - // endpoint must act as a server and the one on the other side must act as a - // client. - bool is_server = false; - // This is only needed when is_server = false. It must be unique - // for each endpoint the local endpoint may communicate with. For example, - // a WebRTC client could use the remote endpoint's crypto fingerprint - std::string unique_remote_server_id; - // The way the QuicConnection will send and receive packets, like a virtual - // UDP socket. For WebRTC, this will typically be an IceTransport. - QuartcPacketTransport* packet_transport = nullptr; - // The maximum size of the packet can be written with the packet writer. - // 1200 bytes by default. - uint64_t max_packet_size = 1200; - // Algorithm to use for congestion control. By default, uses an arbitrary - // congestion control algorithm chosen by QUIC. - QuartcCongestionControl congestion_control = - QuartcCongestionControl::kDefault; - // Options to control the BBR algorithm. In case the congestion control is - // set to anything but BBR, these options are ignored. - std::vector<QuartcBbrOptions> bbr_options; - // Timeouts for the crypto handshake. Set them to higher values to - // prevent closing the session before it started on a slow network. - // Zero entries are ignored and QUIC defaults are used in that case. - uint32_t max_idle_time_before_crypto_handshake_secs = 0; - uint32_t max_time_before_crypto_handshake_secs = 0; - QuicTime::Delta idle_network_timeout = QuicTime::Delta::Zero(); - }; - - virtual std::unique_ptr<QuartcSessionInterface> CreateQuartcSession( - const QuartcSessionConfig& quartc_config) = 0; -}; - -// The configuration for creating a QuartcFactory. -struct QuartcFactoryConfig { - // The task runner used by the QuartcAlarm. Implemented by the Quartc user - // with different mechanism. For example in WebRTC, it is implemented with - // rtc::Thread. Owned by the user, and needs to stay alive for as long - // as the QuartcFactory exists. - QuartcTaskRunnerInterface* task_runner = nullptr; - // The clock used by QuartcAlarms. Implemented by the Quartc user. Owned by - // the user, and needs to stay alive for as long as the QuartcFactory exists. - QuartcClockInterface* clock = nullptr; -}; - -// Creates a new instance of QuartcFactoryInterface. -std::unique_ptr<QuartcFactoryInterface> CreateQuartcFactory( - const QuartcFactoryConfig& factory_config); - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_FACTORY_INTERFACE_H_
diff --git a/net/third_party/quic/quartc/quartc_packet_writer.h b/net/third_party/quic/quartc/quartc_packet_writer.h index a1cabb7..a4dca96 100644 --- a/net/third_party/quic/quartc/quartc_packet_writer.h +++ b/net/third_party/quic/quartc/quartc_packet_writer.h
@@ -5,12 +5,31 @@ #ifndef NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_ #define NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_ +#include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_packet_writer.h" +#include "net/third_party/quic/core/quic_types.h" #include "net/third_party/quic/platform/api/quic_export.h" -#include "net/third_party/quic/quartc/quartc_session_interface.h" namespace quic { +// Send and receive packets, like a virtual UDP socket. For example, this +// could be implemented by WebRTC's IceTransport. +class QUIC_EXPORT_PRIVATE QuartcPacketTransport { + public: + // Additional metadata provided for each packet written. + struct PacketInfo { + QuicPacketNumber packet_number; + }; + + virtual ~QuartcPacketTransport() {} + + // Called by the QuartcPacketWriter when writing packets to the network. + // Return the number of written bytes. Return 0 if the write is blocked. + virtual int Write(const char* buffer, + size_t buf_len, + const PacketInfo& info) = 0; +}; + // Implements a QuicPacketWriter using a QuartcPacketTransport, which allows a // QuicConnection to use (for example), a WebRTC IceTransport. class QUIC_EXPORT_PRIVATE QuartcPacketWriter : public QuicPacketWriter { @@ -20,7 +39,7 @@ ~QuartcPacketWriter() override {} // The QuicConnection calls WritePacket and the QuicPacketWriter writes them - // to the QuartcSessionInterface::PacketTransport. + // to the QuartcSession::PacketTransport. WriteResult WritePacket(const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
diff --git a/net/third_party/quic/quartc/quartc_session.cc b/net/third_party/quic/quartc/quartc_session.cc index c8d48c2..f61da4e 100644 --- a/net/third_party/quic/quartc/quartc_session.cc +++ b/net/third_party/quic/quartc/quartc_session.cc
@@ -8,8 +8,6 @@ #include "net/third_party/quic/core/tls_server_handshaker.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" -using std::string; - namespace quic { namespace { @@ -31,14 +29,14 @@ // ProofSource override. void GetProof(const QuicSocketAddress& server_addr, - const string& hostname, - const string& server_config, + const QuicString& hostname, + const QuicString& server_config, QuicTransportVersion transport_version, QuicStringPiece chlo_hash, std::unique_ptr<Callback> callback) override { QuicReferenceCountedPointer<ProofSource::Chain> chain; QuicCryptoProof proof; - std::vector<string> certs; + std::vector<QuicString> certs; certs.push_back("Dummy cert"); chain = new ProofSource::Chain(certs); proof.signature = "Dummy signature"; @@ -48,13 +46,13 @@ QuicReferenceCountedPointer<Chain> GetCertChain( const QuicSocketAddress& server_address, - const string& hostname) override { + const QuicString& hostname) override { return QuicReferenceCountedPointer<Chain>(); } void ComputeTlsSignature( const QuicSocketAddress& server_address, - const string& hostname, + const QuicString& hostname, uint16_t signature_algorithm, QuicStringPiece in, std::unique_ptr<SignatureCallback> callback) override { @@ -72,26 +70,26 @@ // ProofVerifier override. QuicAsyncStatus VerifyProof( - const string& hostname, + const QuicString& hostname, const uint16_t port, - const string& server_config, + const QuicString& server_config, QuicTransportVersion transport_version, QuicStringPiece chlo_hash, - const std::vector<string>& certs, - const string& cert_sct, - const string& signature, + const std::vector<QuicString>& certs, + const QuicString& cert_sct, + const QuicString& signature, const ProofVerifyContext* context, - string* error_details, + QuicString* error_details, std::unique_ptr<ProofVerifyDetails>* verify_details, std::unique_ptr<ProofVerifierCallback> callback) override { return QUIC_SUCCESS; } QuicAsyncStatus VerifyCertChain( - const string& hostname, - const std::vector<string>& certs, + const QuicString& hostname, + const std::vector<QuicString>& certs, const ProofVerifyContext* context, - string* error_details, + QuicString* error_details, std::unique_ptr<ProofVerifyDetails>* details, std::unique_ptr<ProofVerifierCallback> callback) override { return QUIC_SUCCESS; @@ -114,65 +112,13 @@ const QuicSocketAddress& client_address, const QuicSocketAddress& peer_address, const QuicSocketAddress& self_address, - string* error_details) const { + QuicString* error_details) const { return true; } -QuartcSessionVisitorAdapter::~QuartcSessionVisitorAdapter() {} - -QuartcSessionVisitorAdapter::QuartcSessionVisitorAdapter() {} - -void QuartcSessionVisitorAdapter::OnPacketSent( - const SerializedPacket& serialized_packet, - QuicPacketNumber original_packet_number, - TransmissionType transmission_type, - QuicTime sent_time) { - for (QuartcSessionVisitor* visitor : visitors_) { - visitor->OnPacketSent(serialized_packet, original_packet_number, - transmission_type, sent_time); - } -} - -void QuartcSessionVisitorAdapter::OnIncomingAck( - const QuicAckFrame& ack_frame, - QuicTime ack_receive_time, - QuicPacketNumber largest_observed, - bool rtt_updated, - QuicPacketNumber least_unacked_sent_packet) { - for (QuartcSessionVisitor* visitor : visitors_) { - visitor->OnIncomingAck(ack_frame, ack_receive_time, largest_observed, - rtt_updated, least_unacked_sent_packet); - } -} - -void QuartcSessionVisitorAdapter::OnPacketLoss( - QuicPacketNumber lost_packet_number, - TransmissionType transmission_type, - QuicTime detection_time) { - for (QuartcSessionVisitor* visitor : visitors_) { - visitor->OnPacketLoss(lost_packet_number, transmission_type, - detection_time); - } -} - -void QuartcSessionVisitorAdapter::OnWindowUpdateFrame( - const QuicWindowUpdateFrame& frame, - const QuicTime& receive_time) { - for (QuartcSessionVisitor* visitor : visitors_) { - visitor->OnWindowUpdateFrame(frame, receive_time); - } -} - -void QuartcSessionVisitorAdapter::OnSuccessfulVersionNegotiation( - const ParsedQuicVersion& version) { - for (QuartcSessionVisitor* visitor : visitors_) { - visitor->OnSuccessfulVersionNegotiation(version); - } -} - QuartcSession::QuartcSession(std::unique_ptr<QuicConnection> connection, const QuicConfig& config, - const string& unique_remote_server_id, + const QuicString& unique_remote_server_id, Perspective perspective, QuicConnectionHelperInterface* helper, QuicClock* clock, @@ -200,7 +146,7 @@ helper_->GetRandomGenerator()->RandBytes(source_address_token_secret, kInputKeyingMaterialLength); quic_crypto_server_config_ = QuicMakeUnique<QuicCryptoServerConfig>( - string(source_address_token_secret, kInputKeyingMaterialLength), + QuicString(source_address_token_secret, kInputKeyingMaterialLength), helper_->GetRandomGenerator(), std::move(proof_source), TlsServerHandshaker::CreateSslCtx()); // Provide server with serialized config string to prove ownership. @@ -241,15 +187,6 @@ } } -void QuartcSession::CloseStream(QuicStreamId stream_id) { - if (IsClosedStream(stream_id)) { - // When CloseStream has been called recursively (via - // QuicStream::OnClose), the stream is already closed so return. - return; - } - QuicSession::CloseStream(stream_id); -} - void QuartcSession::CancelStream(QuicStreamId stream_id) { ResetStream(stream_id, QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED); } @@ -265,21 +202,12 @@ } } -bool QuartcSession::IsOpenStream(QuicStreamId stream_id) { - return QuicSession::IsOpenStream(stream_id); -} - -QuicConnectionStats QuartcSession::GetStats() { - return connection_->GetStats(); -} - void QuartcSession::OnConnectionClosed(QuicErrorCode error, - const string& error_details, + const QuicString& error_details, ConnectionCloseSource source) { QuicSession::OnConnectionClosed(error, error_details, source); DCHECK(session_delegate_); - session_delegate_->OnConnectionClosed( - error, source == ConnectionCloseSource::FROM_PEER); + session_delegate_->OnConnectionClosed(error, error_details, source); } void QuartcSession::SetPreSharedKey(QuicStringPiece key) { @@ -313,35 +241,13 @@ } } -bool QuartcSession::ExportKeyingMaterial(const string& label, - const uint8_t* context, - size_t context_len, - bool used_context, - uint8_t* result, - size_t result_len) { - string quic_context(reinterpret_cast<const char*>(context), context_len); - string quic_result; - bool success = crypto_stream_->ExportKeyingMaterial(label, quic_context, - result_len, &quic_result); - quic_result.copy(reinterpret_cast<char*>(result), result_len); - DCHECK(quic_result.length() == result_len); - return success; -} - -void QuartcSession::CloseConnection(const string& details) { +void QuartcSession::CloseConnection(const QuicString& details) { connection_->CloseConnection( QuicErrorCode::QUIC_CONNECTION_CANCELLED, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET_WITH_NO_ACK); } -QuartcStreamInterface* QuartcSession::CreateOutgoingStream( - const OutgoingStreamParameters& param) { - // The |param| is for forward-compatibility. Not used for now. - return CreateOutgoingDynamicStream(); -} - -void QuartcSession::SetDelegate( - QuartcSessionInterface::Delegate* session_delegate) { +void QuartcSession::SetDelegate(Delegate* session_delegate) { if (session_delegate_) { LOG(WARNING) << "The delegate for the session has already been set."; } @@ -349,25 +255,6 @@ DCHECK(session_delegate_); } -void QuartcSession::AddSessionVisitor(QuartcSessionVisitor* visitor) { - // If there aren't any visitors yet, install the adapter as a connection debug - // visitor to delegate any future calls. - if (session_visitor_adapter_.visitors().empty()) { - connection_->set_debug_visitor(&session_visitor_adapter_); - } - session_visitor_adapter_.mutable_visitors().insert(visitor); - visitor->OnQuicConnection(connection_.get()); -} - -void QuartcSession::RemoveSessionVisitor(QuartcSessionVisitor* visitor) { - session_visitor_adapter_.mutable_visitors().erase(visitor); - // If the last visitor is removed, uninstall the connection debug visitor to - // avoid delegating debug calls unnecessarily. - if (session_visitor_adapter_.visitors().empty()) { - connection_->set_debug_visitor(nullptr); - } -} - void QuartcSession::OnTransportCanWrite() { connection()->writer()->SetWritable(); if (HasDataToWrite()) { @@ -376,29 +263,12 @@ } bool QuartcSession::OnTransportReceived(const char* data, size_t data_len) { - // If the session is currently bundling packets, it must stop and flush writes - // before processing incoming data. QUIC expects pending packets to be - // written before receiving data, because received data may change the - // contents of ACK frames in pending packets. - FlushWrites(); - QuicReceivedPacket packet(data, data_len, clock_->Now()); ProcessUdpPacket(connection()->self_address(), connection()->peer_address(), packet); return true; } -void QuartcSession::BundleWrites() { - if (!packet_flusher_) { - packet_flusher_ = QuicMakeUnique<QuicConnection::ScopedPacketFlusher>( - connection_.get(), QuicConnection::SEND_ACK_IF_QUEUED); - } -} - -void QuartcSession::FlushWrites() { - packet_flusher_ = nullptr; -} - void QuartcSession::OnProofValid( const QuicCryptoClientConfig::CachedState& cached) { // TODO(zhihuang): Handle the proof verification. @@ -409,16 +279,6 @@ // TODO(zhihuang): Handle the proof verification. } -void QuartcSession::SetClientCryptoConfig( - QuicCryptoClientConfig* client_config) { - quic_crypto_client_config_.reset(client_config); -} - -void QuartcSession::SetServerCryptoConfig( - QuicCryptoServerConfig* server_config) { - quic_crypto_server_config_.reset(server_config); -} - QuicStream* QuartcSession::CreateIncomingDynamicStream(QuicStreamId id) { return ActivateDataStream(CreateDataStream(id, QuicStream::kDefaultPriority)); }
diff --git a/net/third_party/quic/quartc/quartc_session.h b/net/third_party/quic/quartc/quartc_session.h index ac1eb24c..82a43338 100644 --- a/net/third_party/quic/quartc/quartc_session.h +++ b/net/third_party/quic/quartc/quartc_session.h
@@ -11,9 +11,7 @@ #include "net/third_party/quic/core/quic_error_codes.h" #include "net/third_party/quic/core/quic_session.h" #include "net/third_party/quic/platform/api/quic_export.h" -#include "net/third_party/quic/quartc/quartc_clock_interface.h" #include "net/third_party/quic/quartc/quartc_packet_writer.h" -#include "net/third_party/quic/quartc/quartc_session_interface.h" #include "net/third_party/quic/quartc/quartc_stream.h" namespace quic { @@ -28,58 +26,23 @@ const QuicSocketAddress& client_address, const QuicSocketAddress& peer_address, const QuicSocketAddress& self_address, - std::string* error_details) const override; + QuicString* error_details) const override; }; -// Adapts |QuartcSessionVisitor|s to the |QuicConnectionDebugVisitor| interface. -// Keeps a set of |QuartcSessionVisitor|s and forwards QUIC debug callbacks to -// each visitor in the set. -class QuartcSessionVisitorAdapter : public QuicConnectionDebugVisitor { - public: - QuartcSessionVisitorAdapter(); - ~QuartcSessionVisitorAdapter() override; - - void OnPacketSent(const SerializedPacket& serialized_packet, - QuicPacketNumber original_packet_number, - TransmissionType transmission_type, - QuicTime sent_time) override; - void OnIncomingAck(const QuicAckFrame& ack_frame, - QuicTime ack_receive_time, - QuicPacketNumber largest_observed, - bool rtt_updated, - QuicPacketNumber least_unacked_sent_packet) override; - void OnPacketLoss(QuicPacketNumber lost_packet_number, - TransmissionType transmission_type, - QuicTime detection_time) override; - void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame, - const QuicTime& receive_time) override; - void OnSuccessfulVersionNegotiation( - const ParsedQuicVersion& version) override; - - const std::set<QuartcSessionVisitor*>& visitors() const { return visitors_; } - std::set<QuartcSessionVisitor*>& mutable_visitors() { return visitors_; } - - // Disallow copy and assign. - QuartcSessionVisitorAdapter(const QuartcSessionVisitorAdapter&) = delete; - QuartcSessionVisitorAdapter operator=(const QuartcSessionVisitorAdapter&) = - delete; - - private: - std::set<QuartcSessionVisitor*> visitors_; -}; - +// QuartcSession owns and manages a QUIC connection. class QUIC_EXPORT_PRIVATE QuartcSession : public QuicSession, - public QuartcSessionInterface, public QuicCryptoClientStream::ProofHandler { public: QuartcSession(std::unique_ptr<QuicConnection> connection, const QuicConfig& config, - const std::string& unique_remote_server_id, + const QuicString& unique_remote_server_id, Perspective perspective, QuicConnectionHelperInterface* helper, QuicClock* clock, std::unique_ptr<QuartcPacketWriter> packet_writer); + QuartcSession(const QuartcSession&) = delete; + QuartcSession& operator=(const QuartcSession&) = delete; ~QuartcSession() override; // QuicSession overrides. @@ -91,48 +54,67 @@ void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override; - void CloseStream(QuicStreamId stream_id) override; - // QuicConnectionVisitorInterface overrides. void OnConnectionClosed(QuicErrorCode error, - const std::string& error_details, + const QuicString& error_details, ConnectionCloseSource source) override; - // QuartcSessionInterface overrides - void SetPreSharedKey(QuicStringPiece key) override; + // QuartcSession methods. - void StartCryptoHandshake() override; + // Sets a pre-shared key for use during the crypto handshake. Must be set + // before StartCryptoHandshake() is called. + void SetPreSharedKey(QuicStringPiece key); - bool ExportKeyingMaterial(const std::string& label, - const uint8_t* context, - size_t context_len, - bool used_context, - uint8_t* result, - size_t result_len) override; + void StartCryptoHandshake(); - void CloseConnection(const std::string& details) override; + // Closes the connection with the given human-readable error details. + // The connection closes with the QUIC_CONNECTION_CANCELLED error code to + // indicate the application closed it. + // + // Informs the peer that the connection has been closed. This prevents the + // peer from waiting until the connection times out. + // + // Cleans up the underlying QuicConnection's state. Closing the connection + // makes it safe to delete the QuartcSession. + void CloseConnection(const QuicString& details); - QuartcStreamInterface* CreateOutgoingStream( - const OutgoingStreamParameters& param) override; + // If the given stream is still open, sends a reset frame to cancel it. + // Note: This method cancels a stream by QuicStreamId rather than by pointer + // (or by a method on QuartcStream) because QuartcSession (and not + // the caller) owns the streams. Streams may finish and be deleted before the + // caller tries to cancel them, rendering the caller's pointers invalid. + void CancelStream(QuicStreamId stream_id); - void CancelStream(QuicStreamId stream_id) override; + // Callbacks called by the QuartcSession to notify the user of the + // QuartcSession of certain events. + class Delegate { + public: + virtual ~Delegate() {} - bool IsOpenStream(QuicStreamId stream_id) override; + // Called when the crypto handshake is complete. + virtual void OnCryptoHandshakeComplete() = 0; - QuicConnectionStats GetStats() override; + // Called when a new stream is received from the remote endpoint. + virtual void OnIncomingStream(QuartcStream* stream) = 0; - void SetDelegate(QuartcSessionInterface::Delegate* session_delegate) override; + // Called when the connection is closed. This means all of the streams will + // be closed and no new streams can be created. + virtual void OnConnectionClosed(QuicErrorCode error_code, + const QuicString& error_details, + ConnectionCloseSource source) = 0; - void AddSessionVisitor(QuartcSessionVisitor* visitor) override; - void RemoveSessionVisitor(QuartcSessionVisitor* visitor) override; + // TODO(zhihuang): Add proof verification. + }; - void OnTransportCanWrite() override; + // The |delegate| is not owned by QuartcSession. + void SetDelegate(Delegate* session_delegate); - // Decrypts an incoming QUIC packet to a data stream. - bool OnTransportReceived(const char* data, size_t data_len) override; + // Called when CanWrite() changes from false to true. + void OnTransportCanWrite(); - void BundleWrites() override; - void FlushWrites() override; + // Called when a packet has been received and should be handled by the + // QuicConnection. + bool OnTransportReceived(const char* data, size_t data_len); // ProofHandler overrides. void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override; @@ -143,12 +125,6 @@ void OnProofVerifyDetailsAvailable( const ProofVerifyDetails& verify_details) override; - // Override the default crypto configuration. - // The session will take the ownership of the configurations. - void SetClientCryptoConfig(QuicCryptoClientConfig* client_config); - - void SetServerCryptoConfig(QuicCryptoServerConfig* server_config); - protected: // QuicSession override. QuicStream* CreateIncomingDynamicStream(QuicStreamId id) override; @@ -164,7 +140,7 @@ private: // For crypto handshake. std::unique_ptr<QuicCryptoStream> crypto_stream_; - const std::string unique_remote_server_id_; + const QuicString unique_remote_server_id_; Perspective perspective_; // Packet writer used by |connection_|. @@ -179,7 +155,7 @@ // For recording packet receipt time QuicClock* clock_; // Not owned by QuartcSession. - QuartcSessionInterface::Delegate* session_delegate_ = nullptr; + Delegate* session_delegate_ = nullptr; // Used by QUIC crypto server stream to track most recently compressed certs. std::unique_ptr<QuicCompressedCertsCache> quic_compressed_certs_cache_; // This helper is needed when create QuicCryptoServerStream. @@ -188,14 +164,6 @@ std::unique_ptr<QuicCryptoClientConfig> quic_crypto_client_config_; // Config for QUIC crypto server stream, used by the server. std::unique_ptr<QuicCryptoServerConfig> quic_crypto_server_config_; - - // Holds pointers to QuartcSessionVisitors and adapts them to the - // QuicConnectionDebugVisitor interface. - QuartcSessionVisitorAdapter session_visitor_adapter_; - - std::unique_ptr<QuicConnection::ScopedPacketFlusher> packet_flusher_; - - DISALLOW_COPY_AND_ASSIGN(QuartcSession); }; } // namespace quic
diff --git a/net/third_party/quic/quartc/quartc_session_interface.h b/net/third_party/quic/quartc/quartc_session_interface.h deleted file mode 100644 index 2db5f35..0000000 --- a/net/third_party/quic/quartc/quartc_session_interface.h +++ /dev/null
@@ -1,155 +0,0 @@ -// Copyright (c) 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_SESSION_INTERFACE_H_ -#define NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_SESSION_INTERFACE_H_ - -#include <stddef.h> -#include <stdint.h> -#include <string> - -#include "net/third_party/quic/core/quic_bandwidth.h" -#include "net/third_party/quic/core/quic_error_codes.h" -#include "net/third_party/quic/core/quic_time.h" -#include "net/third_party/quic/core/quic_types.h" -#include "net/third_party/quic/platform/api/quic_export.h" -#include "net/third_party/quic/quartc/quartc_session_visitor_interface.h" -#include "net/third_party/quic/quartc/quartc_stream_interface.h" - -namespace quic { - -// Send and receive packets, like a virtual UDP socket. For example, this -// could be implemented by WebRTC's IceTransport. -class QUIC_EXPORT_PRIVATE QuartcPacketTransport { - public: - // Additional metadata provided for each packet written. - struct PacketInfo { - QuicPacketNumber packet_number; - }; - - virtual ~QuartcPacketTransport() {} - - // Called by the QuartcPacketWriter when writing packets to the network. - // Return the number of written bytes. Return 0 if the write is blocked. - virtual int Write(const char* buffer, - size_t buf_len, - const PacketInfo& info) = 0; -}; - -// Given a PacketTransport, provides a way to send and receive separate streams -// of reliable, in-order, encrypted data. For example, this can build on top of -// a WebRTC IceTransport for sending and receiving data over QUIC. -class QUIC_EXPORT_PRIVATE QuartcSessionInterface { - public: - virtual ~QuartcSessionInterface() {} - - // Sets a pre-shared key for use during the crypto handshake. Must be set - // before StartCryptoHandshake() is called. - virtual void SetPreSharedKey(QuicStringPiece key) = 0; - - virtual void StartCryptoHandshake() = 0; - - // Only needed when using SRTP with QuicTransport - // Key Exporter interface from RFC 5705 - // Arguments are: - // label -- the exporter label. - // part of the RFC defining each exporter usage (IN) - // context/context_len -- a context to bind to for this connection; - // optional, can be NULL, 0 (IN) - // use_context -- whether to use the context value - // (needed to distinguish no context from - // zero-length ones). - // result -- where to put the computed value - // result_len -- the length of the computed value - virtual bool ExportKeyingMaterial(const std::string& label, - const uint8_t* context, - size_t context_len, - bool used_context, - uint8_t* result, - size_t result_len) = 0; - - // Closes the connection with the given human-readable error details. - // The connection closes with the QUIC_CONNECTION_CANCELLED error code to - // indicate the application closed it. - // - // Informs the peer that the connection has been closed. This prevents the - // peer from waiting until the connection times out. - // - // Cleans up the underlying QuicConnection's state. Closing the connection - // makes it safe to delete the QuartcSession. - virtual void CloseConnection(const std::string& error_details) = 0; - - // For forward-compatibility. More parameters could be added through the - // struct without changing the API. - struct OutgoingStreamParameters {}; - - virtual QuartcStreamInterface* CreateOutgoingStream( - const OutgoingStreamParameters& params) = 0; - - // If the given stream is still open, sends a reset frame to cancel it. - // Note: This method cancels a stream by QuicStreamId rather than by pointer - // (or by a method on QuartcStreamInterface) because QuartcSession (and not - // the caller) owns the streams. Streams may finish and be deleted before the - // caller tries to cancel them, rendering the caller's pointers invalid. - virtual void CancelStream(QuicStreamId stream_id) = 0; - - // This method verifies if a stream is still open and stream pointer can be - // used. When true is returned, the interface pointer is good for making a - // call immediately on the same thread, but may be rendered invalid by ANY - // other QUIC activity. - virtual bool IsOpenStream(QuicStreamId stream_id) = 0; - - // Gets stats associated with the current QUIC connection. - virtual QuicConnectionStats GetStats() = 0; - - // Called when CanWrite() changes from false to true. - virtual void OnTransportCanWrite() = 0; - - // Called when a packet has been received and should be handled by the - // QuicConnection. - virtual bool OnTransportReceived(const char* data, size_t data_len) = 0; - - // Bundles subsequent writes on a best-effort basis. - // Data is sent whenever enough data is accumulated to fill a packet. - // The session stops bundling writes and sends data immediately as soon as - // FlushWrites() is called or a packet is received. - virtual void BundleWrites() = 0; - - // Stop bundling writes and flush any pending writes immediately. - virtual void FlushWrites() = 0; - - // Callbacks called by the QuartcSession to notify the user of the - // QuartcSession of certain events. - class Delegate { - public: - virtual ~Delegate() {} - - // Called when the crypto handshake is complete. - virtual void OnCryptoHandshakeComplete() = 0; - - // Called when a new stream is received from the remote endpoint. - virtual void OnIncomingStream(QuartcStreamInterface* stream) = 0; - - // Called when the connection is closed. This means all of the streams will - // be closed and no new streams can be created. - // TODO(zhihuang): Create mapping from integer error code to WebRTC error - // code. - virtual void OnConnectionClosed(int error_code, bool from_remote) = 0; - - // TODO(zhihuang): Add proof verification. - }; - - // The |delegate| is not owned by QuartcSession. - virtual void SetDelegate(Delegate* delegate) = 0; - - // Add or remove session visitors. Session visitors observe internals of the - // Quartc/QUIC session for the purpose of gathering metrics or debug - // information. - virtual void AddSessionVisitor(QuartcSessionVisitor* visitor) = 0; - virtual void RemoveSessionVisitor(QuartcSessionVisitor* visitor) = 0; -}; - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_SESSION_INTERFACE_H_
diff --git a/net/third_party/quic/quartc/quartc_session_test.cc b/net/third_party/quic/quartc/quartc_session_test.cc index aedd3675..da48a90 100644 --- a/net/third_party/quic/quartc/quartc_session_test.cc +++ b/net/third_party/quic/quartc/quartc_session_test.cc
@@ -4,6 +4,7 @@ #include "net/third_party/quic/quartc/quartc_session.h" +#include "build/build_config.h" #include "net/third_party/quic/core/crypto/crypto_server_config_protobuf.h" #include "net/third_party/quic/core/quic_simple_buffer_allocator.h" #include "net/third_party/quic/core/quic_types.h" @@ -13,229 +14,100 @@ #include "net/third_party/quic/platform/api/quic_test.h" #include "net/third_party/quic/platform/api/quic_test_mem_slice_vector.h" #include "net/third_party/quic/quartc/quartc_factory.h" -#include "net/third_party/quic/quartc/quartc_factory_interface.h" #include "net/third_party/quic/quartc/quartc_packet_writer.h" -#include "net/third_party/quic/quartc/quartc_stream_interface.h" #include "net/third_party/quic/test_tools/mock_clock.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using std::string; - +// Tests flaky on iOS. +// TODO(vasilvv): figure out what's wrong and re-enable if possible. +#if !defined(OS_IOS) namespace quic { namespace { -static const char kExporterLabel[] = "label"; -static const uint8_t kExporterContext[] = "context"; -static const size_t kExporterContextLen = sizeof(kExporterContext); -static const size_t kOutputKeyLength = 20; -static QuartcStreamInterface::WriteParameters kDefaultWriteParam; -static QuartcSessionInterface::OutgoingStreamParameters kDefaultStreamParam; static QuicByteCount kDefaultMaxPacketSize = 1200; -// Single-threaded scheduled task runner based on a MockClock. +// Single-threaded alarm implementation based on a MockClock. // -// Simulates asynchronous execution on a single thread by holding scheduled -// tasks until Run() is called. Performs no synchronization, assumes that -// Schedule() and Run() are called on the same thread. -class FakeTaskRunner : public QuartcTaskRunnerInterface { +// Simulates asynchronous execution on a single thread by holding alarms +// until Run() is called. Performs no synchronization, assumes that +// CreateAlarm(), Set(), Cancel(), and Run() are called on the same thread. +class FakeAlarmFactory : public QuicAlarmFactory { public: - explicit FakeTaskRunner(MockClock* clock) - : tasks_([this](const TaskType& l, const TaskType& r) { - // Items at a later time should run after items at an earlier time. - // Priority queue comparisons should return true if l appears after r. - return l->time() > r->time(); - }), - clock_(clock) {} + class FakeAlarm : public QuicAlarm { + public: + FakeAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate, + FakeAlarmFactory* parent) + : QuicAlarm(std::move(delegate)), parent_(parent) {} - ~FakeTaskRunner() override {} + ~FakeAlarm() override { parent_->RemoveAlarm(this); } - // Runs all tasks scheduled in the next total_ms milliseconds. Advances the + void SetImpl() override { parent_->AddAlarm(this); } + + void CancelImpl() override { parent_->RemoveAlarm(this); } + + void Run() { Fire(); } + + private: + FakeAlarmFactory* parent_; + }; + + explicit FakeAlarmFactory(MockClock* clock) : clock_(clock) {} + FakeAlarmFactory(const FakeAlarmFactory&) = delete; + FakeAlarmFactory& operator=(const FakeAlarmFactory&) = delete; + + QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override { + return new FakeAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate), + this); + } + + QuicArenaScopedPtr<QuicAlarm> CreateAlarm( + QuicArenaScopedPtr<QuicAlarm::Delegate> delegate, + QuicConnectionArena* arena) override { + return arena->New<FakeAlarm>(std::move(delegate), this); + } + + // Runs all alarms scheduled in the next total_ms milliseconds. Advances the // clock by total_ms. Runs tasks in time order. Executes tasks scheduled at // the same in an arbitrary order. void Run(uint32_t total_ms) { for (uint32_t i = 0; i < total_ms; ++i) { - while (!tasks_.empty() && tasks_.top()->time() <= clock_->Now()) { - tasks_.top()->Run(); - tasks_.pop(); + while (!alarms_.empty() && alarms_.top()->deadline() <= clock_->Now()) { + alarms_.top()->Run(); + alarms_.pop(); } clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); } } private: - class InnerTask { - public: - InnerTask(std::function<void()> task, QuicTime time) - : task_(std::move(task)), time_(time) {} - - void Cancel() { cancelled_ = true; } - - void Run() { - if (!cancelled_) { - task_(); + void RemoveAlarm(FakeAlarm* alarm) { + std::vector<FakeAlarm*> leftovers; + while (!alarms_.empty()) { + FakeAlarm* top = alarms_.top(); + alarms_.pop(); + if (top == alarm) { + break; } + leftovers.push_back(top); } - - QuicTime time() const { return time_; } - - private: - bool cancelled_ = false; - std::function<void()> task_; - QuicTime time_; - }; - - public: - // Hook for cancelling a scheduled task. - class ScheduledTask : public QuartcTaskRunnerInterface::ScheduledTask { - public: - explicit ScheduledTask(std::shared_ptr<InnerTask> inner) - : inner_(std::move(inner)) {} - - // Cancel if the caller deletes the ScheduledTask. This behavior is - // consistent with the actual task runner Quartc uses. - ~ScheduledTask() override { Cancel(); } - - // ScheduledTask implementation. - void Cancel() override { inner_->Cancel(); } - - private: - std::shared_ptr<InnerTask> inner_; - }; - - // See QuartcTaskRunnerInterface. - std::unique_ptr<QuartcTaskRunnerInterface::ScheduledTask> Schedule( - Task* task, - uint64_t delay_ms) override { - auto inner = std::shared_ptr<InnerTask>(new InnerTask( - [task] { task->Run(); }, - clock_->Now() + QuicTime::Delta::FromMilliseconds(delay_ms))); - tasks_.push(inner); - return std::unique_ptr<QuartcTaskRunnerInterface::ScheduledTask>( - new ScheduledTask(inner)); - } - - // Schedules a function to run immediately. - void Schedule(std::function<void()> task) { - tasks_.push(std::shared_ptr<InnerTask>( - new InnerTask(std::move(task), clock_->Now()))); - } - - private: - // InnerTasks are shared by the queue and ScheduledTask (which hooks into it - // to implement Cancel()). - using TaskType = std::shared_ptr<InnerTask>; - std::priority_queue<TaskType, - std::vector<TaskType>, - std::function<bool(const TaskType&, const TaskType&)>> - tasks_; - MockClock* clock_; -}; - -// QuartcClock that wraps a MockClock. -// -// This is silly because Quartc wraps it as a QuicClock, and MockClock is -// already a QuicClock. But we don't have much choice. We need to pass a -// QuartcClockInterface into the Quartc wrappers. -class MockQuartcClock : public QuartcClockInterface { - public: - explicit MockQuartcClock(MockClock* clock) : clock_(clock) {} - - int64_t NowMicroseconds() override { - return clock_->WallNow().ToUNIXMicroseconds(); - } - - private: - MockClock* clock_; -}; - -// Used by QuicCryptoServerConfig to provide server credentials, returning a -// canned response equal to |success|. -class FakeProofSource : public ProofSource { - public: - explicit FakeProofSource(bool success) : success_(success) {} - - // ProofSource override. - void GetProof(const QuicSocketAddress& server_ip, - const string& hostname, - const string& server_config, - QuicTransportVersion transport_version, - QuicStringPiece chlo_hash, - std::unique_ptr<Callback> callback) override { - QuicReferenceCountedPointer<ProofSource::Chain> chain; - QuicCryptoProof proof; - if (success_) { - std::vector<string> certs; - certs.push_back("Required to establish handshake"); - chain = new ProofSource::Chain(certs); - proof.signature = "Signature"; - proof.leaf_cert_scts = "Time"; + for (FakeAlarm* leftover : leftovers) { + alarms_.push(leftover); } - callback->Run(success_, chain, proof, nullptr /* details */); } - QuicReferenceCountedPointer<Chain> GetCertChain( - const QuicSocketAddress& server_address, - const string& hostname) override { - return QuicReferenceCountedPointer<Chain>(); - } + void AddAlarm(FakeAlarm* alarm) { alarms_.push(alarm); } - void ComputeTlsSignature( - const QuicSocketAddress& server_address, - const string& hostname, - uint16_t signature_algorithm, - QuicStringPiece in, - std::unique_ptr<SignatureCallback> callback) override { - callback->Run(true, "Signature"); - } + MockClock* clock_; - private: - // Whether or not obtaining proof source succeeds. - bool success_; -}; - -// Used by QuicCryptoClientConfig to verify server credentials, returning a -// canned response of QUIC_SUCCESS if |success| is true. -class FakeProofVerifier : public ProofVerifier { - public: - explicit FakeProofVerifier(bool success) : success_(success) {} - - // ProofVerifier override - QuicAsyncStatus VerifyProof( - const string& hostname, - const uint16_t port, - const string& server_config, - QuicTransportVersion transport_version, - QuicStringPiece chlo_hash, - const std::vector<string>& certs, - const string& cert_sct, - const string& signature, - const ProofVerifyContext* context, - string* error_details, - std::unique_ptr<ProofVerifyDetails>* verify_details, - std::unique_ptr<ProofVerifierCallback> callback) override { - return success_ ? QUIC_SUCCESS : QUIC_FAILURE; - } - - QuicAsyncStatus VerifyCertChain( - const string& hostname, - const std::vector<string>& certs, - const ProofVerifyContext* context, - string* error_details, - std::unique_ptr<ProofVerifyDetails>* details, - std::unique_ptr<ProofVerifierCallback> callback) override { - LOG(INFO) << "VerifyProof() ignoring credentials and returning success"; - return success_ ? QUIC_SUCCESS : QUIC_FAILURE; - } - - std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override { - return nullptr; - } - - private: - // Whether or not proof verification succeeds. - bool success_; + using AlarmCompare = std::function<bool(const FakeAlarm*, const FakeAlarm*)>; + const AlarmCompare alarm_later_ = [](const FakeAlarm* l, const FakeAlarm* r) { + // Sort alarms so that the earliest deadline appears first. + return l->deadline() > r->deadline(); + }; + std::priority_queue<FakeAlarm*, std::vector<FakeAlarm*>, AlarmCompare> + alarms_{alarm_later_}; }; // Used by the FakeTransportChannel. @@ -244,15 +116,17 @@ virtual ~FakeTransportChannelObserver() {} // Called when the other peer is trying to send message. - virtual void OnTransportChannelReadPacket(const string& data) = 0; + virtual void OnTransportChannelReadPacket(const QuicString& data) = 0; }; // Simulate the P2P communication transport. Used by the -// QuartcSessionInterface::Transport. -class FakeTransportChannel { +// QuartcSession::Transport. +class FakeTransportChannel : QuicAlarm::Delegate { public: - explicit FakeTransportChannel(FakeTaskRunner* task_runner, MockClock* clock) - : task_runner_(task_runner), clock_(clock) {} + explicit FakeTransportChannel(QuicAlarmFactory* alarm_factory, + MockClock* clock) + : alarm_(alarm_factory->CreateAlarm(new AlarmDelegate(this))), + clock_(clock) {} void SetDestination(FakeTransportChannel* dest) { if (!dest_) { @@ -268,21 +142,16 @@ } // Advance the time 10us to ensure the RTT is never 0ms. clock_->AdvanceTime(QuicTime::Delta::FromMicroseconds(10)); - if (async_ && task_runner_) { - string packet(data, len); - task_runner_->Schedule([this, packet] { send(packet); }); + if (async_) { + packet_queue_.emplace_back(data, len); + alarm_->Cancel(); + alarm_->Set(clock_->Now()); } else { - send(string(data, len)); + Send(QuicString(data, len)); } return static_cast<int>(len); } - void send(const string& data) { - DCHECK(dest_); - DCHECK(dest_->observer()); - dest_->observer()->OnTransportChannelReadPacket(data); - } - FakeTransportChannelObserver* observer() { return observer_; } void SetObserver(FakeTransportChannelObserver* observer) { @@ -292,14 +161,43 @@ void SetAsync(bool async) { async_ = async; } private: + class AlarmDelegate : public QuicAlarm::Delegate { + public: + explicit AlarmDelegate(FakeTransportChannel* channel) : channel_(channel) {} + + void OnAlarm() override { channel_->OnAlarm(); } + + private: + FakeTransportChannel* channel_; + }; + + void Send(const QuicString& data) { + DCHECK(dest_); + DCHECK(dest_->observer()); + dest_->observer()->OnTransportChannelReadPacket(data); + } + + void OnAlarm() override { + QUIC_LOG(WARNING) << "Sending packet: " << packet_queue_.front(); + Send(packet_queue_.front()); + packet_queue_.pop_front(); + + if (!packet_queue_.empty()) { + alarm_->Cancel(); + alarm_->Set(clock_->Now()); + } + } + // The writing destination of this channel. FakeTransportChannel* dest_ = nullptr; // The observer of this channel. Called when the received the data. FakeTransportChannelObserver* observer_ = nullptr; // If async, will send packets by running asynchronous tasks. bool async_ = false; - // Used to send data asynchronously. - FakeTaskRunner* task_runner_; + // If async, packets are queued here to send. + QuicDeque<QuicString> packet_queue_; + // Alarm used to send data asynchronously. + QuicArenaScopedPtr<QuicAlarm> alarm_; // The test clock. Used to ensure the RTT is not 0. MockClock* clock_; }; @@ -331,51 +229,52 @@ QuicPacketCount packets_to_lose_ = 0; }; -class FakeQuartcSessionDelegate : public QuartcSessionInterface::Delegate { +class FakeQuartcSessionDelegate : public QuartcSession::Delegate { public: - explicit FakeQuartcSessionDelegate( - QuartcStreamInterface::Delegate* stream_delegate) + explicit FakeQuartcSessionDelegate(QuartcStream::Delegate* stream_delegate) : stream_delegate_(stream_delegate) {} // Called when peers have established forward-secure encryption void OnCryptoHandshakeComplete() override { LOG(INFO) << "Crypto handshake complete!"; } // Called when connection closes locally, or remotely by peer. - void OnConnectionClosed(int error_code, bool from_remote) override { + void OnConnectionClosed(QuicErrorCode error_code, + const QuicString& error_details, + ConnectionCloseSource source) override { connected_ = false; } // Called when an incoming QUIC stream is created. - void OnIncomingStream(QuartcStreamInterface* quartc_stream) override { + void OnIncomingStream(QuartcStream* quartc_stream) override { last_incoming_stream_ = quartc_stream; last_incoming_stream_->SetDelegate(stream_delegate_); } - QuartcStreamInterface* incoming_stream() { return last_incoming_stream_; } + QuartcStream* incoming_stream() { return last_incoming_stream_; } bool connected() { return connected_; } private: - QuartcStreamInterface* last_incoming_stream_; + QuartcStream* last_incoming_stream_; bool connected_ = true; QuartcStream::Delegate* stream_delegate_; }; -class FakeQuartcStreamDelegate : public QuartcStreamInterface::Delegate { +class FakeQuartcStreamDelegate : public QuartcStream::Delegate { public: - void OnReceived(QuartcStreamInterface* stream, + void OnReceived(QuartcStream* stream, const char* data, size_t size) override { - received_data_[stream->stream_id()] += string(data, size); + received_data_[stream->id()] += QuicString(data, size); } - void OnClose(QuartcStreamInterface* stream) override {} + void OnClose(QuartcStream* stream) override {} - void OnBufferChanged(QuartcStreamInterface* stream) override {} + void OnBufferChanged(QuartcStream* stream) override {} - std::map<QuicStreamId, string> data() { return received_data_; } + std::map<QuicStreamId, QuicString> data() { return received_data_; } private: - std::map<QuicStreamId, string> received_data_; + std::map<QuicStreamId, QuicString> received_data_; }; class QuartcSessionForTest : public QuartcSession, @@ -383,7 +282,7 @@ public: QuartcSessionForTest(std::unique_ptr<QuicConnection> connection, const QuicConfig& config, - const string& remote_fingerprint_value, + const QuicString& remote_fingerprint_value, Perspective perspective, QuicConnectionHelperInterface* helper, QuicClock* clock, @@ -403,11 +302,11 @@ } // QuartcPacketWriter override. - void OnTransportChannelReadPacket(const string& data) override { + void OnTransportChannelReadPacket(const QuicString& data) override { OnTransportReceived(data.c_str(), data.length()); } - std::map<QuicStreamId, string> data() { return stream_delegate_->data(); } + std::map<QuicStreamId, QuicString> data() { return stream_delegate_->data(); } bool has_data() { return !data().empty(); } @@ -431,9 +330,9 @@ // Quic crashes if packets are sent at time 0, and the clock defaults to 0. clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000)); client_channel_ = - QuicMakeUnique<FakeTransportChannel>(&task_runner_, &clock_); + QuicMakeUnique<FakeTransportChannel>(&alarm_factory_, &clock_); server_channel_ = - QuicMakeUnique<FakeTransportChannel>(&task_runner_, &clock_); + QuicMakeUnique<FakeTransportChannel>(&alarm_factory_, &clock_); // Make the channel asynchronous so that two peer will not keep calling each // other when they exchange information. client_channel_->SetAsync(true); @@ -453,8 +352,7 @@ // The parameters are used to control whether the handshake will success or // not. - void CreateClientAndServerSessions(bool client_handshake_success = true, - bool server_handshake_success = true) { + void CreateClientAndServerSessions() { Init(); client_peer_ = CreateSession(Perspective::IS_CLIENT, std::move(client_writer_)); @@ -463,26 +361,6 @@ client_channel_->SetObserver(client_peer_.get()); server_channel_->SetObserver(server_peer_.get()); - - client_peer_->SetClientCryptoConfig(new QuicCryptoClientConfig( - std::unique_ptr<ProofVerifier>( - new FakeProofVerifier(client_handshake_success)), - TlsClientHandshaker::CreateSslCtx())); - - QuicCryptoServerConfig* server_config = new QuicCryptoServerConfig( - "TESTING", QuicRandom::GetInstance(), - std::unique_ptr<FakeProofSource>( - new FakeProofSource(server_handshake_success)), - TlsServerHandshaker::CreateSslCtx()); - // Provide server with serialized config string to prove ownership. - QuicCryptoServerConfig::ConfigOptions options; - std::unique_ptr<QuicServerConfigProtobuf> primary_config( - server_config->GenerateConfig(QuicRandom::GetInstance(), &clock_, - options)); - std::unique_ptr<CryptoHandshakeMessage> message( - server_config->AddConfig(std::move(primary_config), clock_.WallNow())); - - server_peer_->SetServerCryptoConfig(server_config); } std::unique_ptr<QuartcSessionForTest> CreateSession( @@ -490,7 +368,7 @@ std::unique_ptr<QuartcPacketWriter> writer) { std::unique_ptr<QuicConnection> quic_connection = CreateConnection(perspective, writer.get()); - string remote_fingerprint_value = "value"; + QuicString remote_fingerprint_value = "value"; QuicConfig config; return QuicMakeUnique<QuartcSessionForTest>( std::move(quic_connection), config, remote_fingerprint_value, @@ -501,22 +379,14 @@ QuartcPacketWriter* writer) { QuicIpAddress ip; ip.FromString("0.0.0.0"); - if (!alarm_factory_) { - // QuartcFactory is only used as an alarm factory. - QuartcFactoryConfig config; - config.clock = &quartc_clock_; - config.task_runner = &task_runner_; - alarm_factory_ = QuicMakeUnique<QuartcFactory>(config); - } - return QuicMakeUnique<QuicConnection>( 0, QuicSocketAddress(ip, 0), this /*QuicConnectionHelperInterface*/, - alarm_factory_.get(), writer, /*owns_writer=*/false, perspective, + &alarm_factory_, writer, /*owns_writer=*/false, perspective, CurrentSupportedVersions()); } // Runs all tasks scheduled in the next 200 ms. - void RunTasks() { task_runner_.Run(200); } + void RunTasks() { alarm_factory_.Run(200); } void StartHandshake() { server_peer_->StartCryptoHandshake(); @@ -532,23 +402,9 @@ ASSERT_TRUE(server_peer_->IsEncryptionEstablished()); ASSERT_TRUE(client_peer_->IsEncryptionEstablished()); - uint8_t server_key[kOutputKeyLength]; - uint8_t client_key[kOutputKeyLength]; - bool use_context = true; - bool server_success = server_peer_->ExportKeyingMaterial( - kExporterLabel, kExporterContext, kExporterContextLen, use_context, - server_key, kOutputKeyLength); - ASSERT_TRUE(server_success); - bool client_success = client_peer_->ExportKeyingMaterial( - kExporterLabel, kExporterContext, kExporterContextLen, use_context, - client_key, kOutputKeyLength); - ASSERT_TRUE(client_success); - EXPECT_EQ(0, memcmp(server_key, client_key, sizeof(server_key))); - // Now we can establish encrypted outgoing stream. - QuartcStreamInterface* outgoing_stream = - server_peer_->CreateOutgoingStream(kDefaultStreamParam); - QuicStreamId stream_id = outgoing_stream->stream_id(); + QuartcStream* outgoing_stream = server_peer_->CreateOutgoingDynamicStream(); + QuicStreamId stream_id = outgoing_stream->id(); ASSERT_NE(nullptr, outgoing_stream); EXPECT_TRUE(server_peer_->HasOpenDynamicStreams()); @@ -558,16 +414,16 @@ char kTestMessage[] = "Hello"; test::QuicTestMemSliceVector data( {std::make_pair(kTestMessage, strlen(kTestMessage))}); - outgoing_stream->Write(data.span(), kDefaultWriteParam); + outgoing_stream->WriteMemSlices(data.span(), /*fin=*/false); RunTasks(); // Wait for peer 2 to receive messages. ASSERT_TRUE(client_peer_->has_data()); - QuartcStreamInterface* incoming = + QuartcStream* incoming = client_peer_->session_delegate()->incoming_stream(); ASSERT_TRUE(incoming); - EXPECT_EQ(incoming->stream_id(), stream_id); + EXPECT_EQ(incoming->id(), stream_id); EXPECT_TRUE(client_peer_->HasOpenDynamicStreams()); EXPECT_EQ(client_peer_->data()[stream_id], kTestMessage); @@ -575,7 +431,7 @@ char kTestResponse[] = "Response"; test::QuicTestMemSliceVector response( {std::make_pair(kTestResponse, strlen(kTestResponse))}); - incoming->Write(response.span(), kDefaultWriteParam); + incoming->WriteMemSlices(response.span(), /*fin=*/false); RunTasks(); // Wait for peer 1 to receive messages. ASSERT_TRUE(server_peer_->has_data()); @@ -606,10 +462,9 @@ } protected: - std::unique_ptr<QuicAlarmFactory> alarm_factory_; - SimpleBufferAllocator buffer_allocator_; MockClock clock_; - MockQuartcClock quartc_clock_{&clock_}; + FakeAlarmFactory alarm_factory_{&clock_}; + SimpleBufferAllocator buffer_allocator_; std::unique_ptr<FakeTransportChannel> client_channel_; std::unique_ptr<FakeTransportChannel> server_channel_; @@ -619,8 +474,6 @@ std::unique_ptr<QuartcPacketWriter> server_writer_; std::unique_ptr<QuartcSessionForTest> client_peer_; std::unique_ptr<QuartcSessionForTest> server_peer_; - - FakeTaskRunner task_runner_{&clock_}; }; TEST_F(QuartcSessionTest, StreamConnection) { @@ -629,42 +482,19 @@ TestStreamConnection(); } -TEST_F(QuartcSessionTest, ClientRejection) { - CreateClientAndServerSessions(false /*client_handshake_success*/, - true /*server_handshake_success*/); +TEST_F(QuartcSessionTest, PreSharedKeyHandshake) { + CreateClientAndServerSessions(); + client_peer_->SetPreSharedKey("foo"); + server_peer_->SetPreSharedKey("foo"); StartHandshake(); - TestDisconnectAfterFailedHandshake(); -} - -TEST_F(QuartcSessionTest, ServerRejection) { - CreateClientAndServerSessions(true /*client_handshake_success*/, - false /*server_handshake_success*/); - StartHandshake(); - TestDisconnectAfterFailedHandshake(); + TestStreamConnection(); } // Test that data streams are not created before handshake. TEST_F(QuartcSessionTest, CannotCreateDataStreamBeforeHandshake) { CreateClientAndServerSessions(); - EXPECT_EQ(nullptr, server_peer_->CreateOutgoingStream(kDefaultStreamParam)); - EXPECT_EQ(nullptr, client_peer_->CreateOutgoingStream(kDefaultStreamParam)); -} - -TEST_F(QuartcSessionTest, CloseQuartcStream) { - CreateClientAndServerSessions(); - StartHandshake(); - ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed()); - ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed()); - QuartcStreamInterface* stream = - client_peer_->CreateOutgoingStream(kDefaultStreamParam); - ASSERT_NE(nullptr, stream); - - uint32_t id = stream->stream_id(); - EXPECT_FALSE(client_peer_->IsClosedStream(id)); - stream->SetDelegate(client_peer_->stream_delegate()); - stream->Close(); - RunTasks(); - EXPECT_TRUE(client_peer_->IsClosedStream(id)); + EXPECT_EQ(nullptr, server_peer_->CreateOutgoingDynamicStream()); + EXPECT_EQ(nullptr, client_peer_->CreateOutgoingDynamicStream()); } TEST_F(QuartcSessionTest, CancelQuartcStream) { @@ -673,11 +503,10 @@ ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed()); ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed()); - QuartcStreamInterface* stream = - client_peer_->CreateOutgoingStream(kDefaultStreamParam); + QuartcStream* stream = client_peer_->CreateOutgoingDynamicStream(); ASSERT_NE(nullptr, stream); - uint32_t id = stream->stream_id(); + uint32_t id = stream->id(); EXPECT_FALSE(client_peer_->IsClosedStream(id)); stream->SetDelegate(client_peer_->stream_delegate()); client_peer_->CancelStream(id); @@ -686,103 +515,19 @@ EXPECT_TRUE(client_peer_->IsClosedStream(id)); } -TEST_F(QuartcSessionTest, BundleWrites) { - CreateClientAndServerSessions(); - StartHandshake(); - ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed()); - ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed()); - - client_peer_->BundleWrites(); - QuartcStreamInterface* first = - client_peer_->CreateOutgoingStream(kDefaultStreamParam); - QuicStreamId first_id = first->stream_id(); - first->SetDelegate(client_peer_->stream_delegate()); - - char kFirstMessage[] = "Hello"; - test::QuicTestMemSliceVector first_data( - {std::make_pair(kFirstMessage, strlen(kFirstMessage))}); - first->Write(first_data.span(), kDefaultWriteParam); - RunTasks(); - - // Server should not receive any data until the client flushes writes. - EXPECT_FALSE(server_peer_->has_data()); - - QuartcStreamInterface* second = - client_peer_->CreateOutgoingStream(kDefaultStreamParam); - QuicStreamId second_id = second->stream_id(); - second->SetDelegate(client_peer_->stream_delegate()); - - char kSecondMessage[] = "World"; - test::QuicTestMemSliceVector second_data( - {std::make_pair(kSecondMessage, strlen(kSecondMessage))}); - second->Write(second_data.span(), kDefaultWriteParam); - RunTasks(); - - EXPECT_FALSE(server_peer_->has_data()); - - client_peer_->FlushWrites(); - RunTasks(); - - ASSERT_TRUE(server_peer_->has_data()); - EXPECT_EQ(server_peer_->data()[first_id], kFirstMessage); - EXPECT_EQ(server_peer_->data()[second_id], kSecondMessage); -} - -TEST_F(QuartcSessionTest, StopBundlingOnIncomingData) { - CreateClientAndServerSessions(); - StartHandshake(); - ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed()); - ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed()); - - client_peer_->BundleWrites(); - QuartcStreamInterface* first = - client_peer_->CreateOutgoingStream(kDefaultStreamParam); - QuicStreamId first_id = first->stream_id(); - first->SetDelegate(client_peer_->stream_delegate()); - - char kFirstMessage[] = "Hello"; - test::QuicTestMemSliceVector first_data( - {std::make_pair(kFirstMessage, strlen(kFirstMessage))}); - first->Write(first_data.span(), kDefaultWriteParam); - RunTasks(); - - // Server should not receive any data until the client flushes writes. - EXPECT_FALSE(server_peer_->has_data()); - - QuartcStreamInterface* second = - server_peer_->CreateOutgoingStream(kDefaultStreamParam); - QuicStreamId second_id = second->stream_id(); - second->SetDelegate(server_peer_->stream_delegate()); - - char kSecondMessage[] = "World"; - test::QuicTestMemSliceVector second_data( - {std::make_pair(kSecondMessage, strlen(kSecondMessage))}); - second->Write(second_data.span(), kDefaultWriteParam); - RunTasks(); - - ASSERT_TRUE(client_peer_->has_data()); - EXPECT_EQ(client_peer_->data()[second_id], kSecondMessage); - - // Server should receive data as well, since the client stops bundling to - // process incoming packets. - ASSERT_TRUE(server_peer_->has_data()); - EXPECT_EQ(server_peer_->data()[first_id], kFirstMessage); -} - TEST_F(QuartcSessionTest, WriterGivesPacketNumberToTransport) { CreateClientAndServerSessions(); StartHandshake(); ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed()); ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed()); - QuartcStreamInterface* stream = - client_peer_->CreateOutgoingStream(kDefaultStreamParam); + QuartcStream* stream = client_peer_->CreateOutgoingDynamicStream(); stream->SetDelegate(client_peer_->stream_delegate()); char kClientMessage[] = "Hello"; test::QuicTestMemSliceVector stream_data( {std::make_pair(kClientMessage, strlen(kClientMessage))}); - stream->Write(stream_data.span(), kDefaultWriteParam); + stream->WriteMemSlices(stream_data.span(), /*fin=*/false); RunTasks(); // The transport should see the latest packet number sent by QUIC. @@ -791,33 +536,6 @@ client_peer_->connection()->sent_packet_manager().GetLargestSentPacket()); } -TEST_F(QuartcSessionTest, GetStats) { - CreateClientAndServerSessions(); - StartHandshake(); - ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed()); - ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed()); - - QuicConnectionStats stats = server_peer_->GetStats(); - EXPECT_GT(stats.estimated_bandwidth, QuicBandwidth::Zero()); - EXPECT_GT(stats.srtt_us, 0); - EXPECT_GT(stats.packets_sent, 0u); - EXPECT_EQ(stats.packets_lost, 0u); -} - -TEST_F(QuartcSessionTest, DISABLED_PacketLossStats) { - CreateClientAndServerSessions(); - StartHandshake(); - ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed()); - ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed()); - - // Packet loss doesn't count until the handshake is done. - server_transport_->set_packets_to_lose(1); - TestStreamConnection(); - - QuicConnectionStats stats = server_peer_->GetStats(); - EXPECT_EQ(stats.packets_lost, 1u); -} - TEST_F(QuartcSessionTest, CloseConnection) { CreateClientAndServerSessions(); StartHandshake(); @@ -833,3 +551,4 @@ } // namespace } // namespace quic +#endif // !defined(OS_IOS)
diff --git a/net/third_party/quic/quartc/quartc_session_visitor_interface.h b/net/third_party/quic/quartc/quartc_session_visitor_interface.h deleted file mode 100644 index 7cd75c6..0000000 --- a/net/third_party/quic/quartc/quartc_session_visitor_interface.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright (c) 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_SESSION_VISITOR_INTERFACE_H_ -#define NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_SESSION_VISITOR_INTERFACE_H_ - -#include "net/third_party/quic/core/quic_connection.h" -#include "net/third_party/quic/platform/api/quic_export.h" - -namespace quic { - -// QuartcSessionVisitor observes internals of a Quartc/QUIC session for the -// purpose of gathering metrics or debug information. -class QUIC_EXPORT_PRIVATE QuartcSessionVisitor { - public: - virtual ~QuartcSessionVisitor() {} - - // Informs this visitor of a |QuicConnection| for the session. - // Called once when the visitor is attached to a QuartcSession, or when a new - // |QuicConnection| starts. - virtual void OnQuicConnection(QuicConnection* connection) {} - - // Called when a packet has been sent. - virtual void OnPacketSent(const SerializedPacket& serialized_packet, - QuicPacketNumber original_packet_number, - TransmissionType transmission_type, - QuicTime sent_time) {} - - // Called when an ack is received. - virtual void OnIncomingAck(const QuicAckFrame& ack_frame, - QuicTime ack_receive_time, - QuicPacketNumber largest_observed, - bool rtt_updated, - QuicPacketNumber least_unacked_sent_packet) {} - - // Called when a packet is lost. - virtual void OnPacketLoss(QuicPacketNumber lost_packet_number, - TransmissionType transmission_type, - QuicTime detection_time) {} - - // Called when a WindowUpdateFrame is received. - virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame, - const QuicTime& receive_time) {} - - // Called when version negotiation succeeds. - virtual void OnSuccessfulVersionNegotiation( - const ParsedQuicVersion& version) {} -}; - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_SESSION_VISITOR_INTERFACE_H_
diff --git a/net/third_party/quic/quartc/quartc_stream.cc b/net/third_party/quic/quartc/quartc_stream.cc index 8c628cf..6cbce4a 100644 --- a/net/third_party/quic/quartc/quartc_stream.cc +++ b/net/third_party/quic/quartc/quartc_stream.cc
@@ -50,39 +50,11 @@ delegate_->OnBufferChanged(this); } -uint32_t QuartcStream::stream_id() { - return id(); -} - -uint64_t QuartcStream::bytes_buffered() { - return BufferedDataBytes(); -} - -bool QuartcStream::fin_sent() { - return QuicStream::fin_sent(); -} - -int QuartcStream::stream_error() { - return QuicStream::stream_error(); -} - -void QuartcStream::Write(QuicMemSliceSpan data, const WriteParameters& param) { - WriteMemSlices(data, param.fin); -} - void QuartcStream::FinishWriting() { WriteOrBufferData(QuicStringPiece(nullptr, 0), true, nullptr); } -void QuartcStream::FinishReading() { - QuicStream::StopReading(); -} - -void QuartcStream::Close() { - QuicStream::session()->CloseStream(id()); -} - -void QuartcStream::SetDelegate(QuartcStreamInterface::Delegate* delegate) { +void QuartcStream::SetDelegate(Delegate* delegate) { if (delegate_) { LOG(WARNING) << "The delegate for Stream " << id() << " has already been set.";
diff --git a/net/third_party/quic/quartc/quartc_stream.h b/net/third_party/quic/quartc/quartc_stream.h index 7a7173e..830d45f 100644 --- a/net/third_party/quic/quartc/quartc_stream.h +++ b/net/third_party/quic/quartc/quartc_stream.h
@@ -8,13 +8,15 @@ #include "net/third_party/quic/core/quic_session.h" #include "net/third_party/quic/core/quic_stream.h" #include "net/third_party/quic/platform/api/quic_export.h" -#include "net/third_party/quic/quartc/quartc_stream_interface.h" +#include "net/third_party/quic/platform/api/quic_mem_slice_span.h" namespace quic { -// Implements a QuartcStreamInterface using a QuicStream. -class QUIC_EXPORT_PRIVATE QuartcStream : public QuicStream, - public QuartcStreamInterface { +// Sends and receives data with a particular QUIC stream ID, reliably and +// in-order. To send/receive data out of order, use separate streams. To +// send/receive unreliably, close a stream after reliability is no longer +// needed. +class QUIC_EXPORT_PRIVATE QuartcStream : public QuicStream { public: QuartcStream(QuicStreamId id, QuicSession* session); @@ -33,27 +35,43 @@ const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener) override; - // QuartcStreamInterface overrides. - uint32_t stream_id() override; + // QuartcStream interface methods. - uint64_t bytes_buffered() override; + // Marks this stream as finished writing. Asynchronously sends a FIN and + // closes the write-side. It is not necessary to call FinishWriting() if the + // last call to Write() sends a FIN. + void FinishWriting(); - bool fin_sent() override; + // Implemented by the user of the QuartcStream to receive incoming + // data and be notified of state changes. + class Delegate { + public: + virtual ~Delegate() {} - int stream_error() override; + // Called when the stream receives data. Called with |size| == 0 after all + // stream data has been delivered (once the stream receives a FIN bit). + // Note that the same packet may include both data and a FIN bit, causing + // this method to be called twice. + virtual void OnReceived(QuartcStream* stream, + const char* data, + size_t size) = 0; - void Write(QuicMemSliceSpan data, const WriteParameters& param) override; + // Called when the stream is closed, either locally or by the remote + // endpoint. Streams close when (a) fin bits are both sent and received, + // (b) Close() is called, or (c) the stream is reset. + // TODO(zhihuang) Creates a map from the integer error_code to WebRTC native + // error code. + virtual void OnClose(QuartcStream* stream) = 0; - void FinishWriting() override; + // Called when the contents of the stream's buffer changes. + virtual void OnBufferChanged(QuartcStream* stream) = 0; + }; - void FinishReading() override; - - void Close() override; - - void SetDelegate(QuartcStreamInterface::Delegate* delegate) override; + // The |delegate| is not owned by QuartcStream. + void SetDelegate(Delegate* delegate); private: - QuartcStreamInterface::Delegate* delegate_ = nullptr; + Delegate* delegate_ = nullptr; }; } // namespace quic
diff --git a/net/third_party/quic/quartc/quartc_stream_interface.h b/net/third_party/quic/quartc/quartc_stream_interface.h deleted file mode 100644 index 9f3f600..0000000 --- a/net/third_party/quic/quartc/quartc_stream_interface.h +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright (c) 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_STREAM_INTERFACE_H_ -#define NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_STREAM_INTERFACE_H_ - -#include <stddef.h> -#include <stdint.h> - -#include "net/third_party/quic/platform/api/quic_export.h" -#include "net/third_party/quic/platform/api/quic_mem_slice_span.h" - -namespace quic { - -// Sends and receives data with a particular QUIC stream ID, reliably and -// in-order. To send/receive data out of order, use separate streams. To -// send/receive unreliably, close a stream after reliability is no longer -// needed. -class QUIC_EXPORT_PRIVATE QuartcStreamInterface { - public: - virtual ~QuartcStreamInterface() {} - - // The QUIC stream ID. - virtual uint32_t stream_id() = 0; - - // The amount of data buffered on this stream. - virtual uint64_t bytes_buffered() = 0; - - // Return true if the FIN has been sent. Used by the outgoing streams to - // determine if all the data has been sent - virtual bool fin_sent() = 0; - - virtual int stream_error() = 0; - - struct WriteParameters { - // |fin| is set to be true when there is no more data need to be send - // through a particular stream. The receiving side will used it to determine - // if the sender finish sending data. - bool fin = false; - }; - - // Sends data reliably and in-order. Returns the amount sent. - // Does not buffer data. - virtual void Write(QuicMemSliceSpan data, const WriteParameters& param) = 0; - - // Marks this stream as finished writing. Asynchronously sends a FIN and - // closes the write-side. The stream will no longer call OnCanWrite(). - // It is not necessary to call FinishWriting() if the last call to Write() - // sends a FIN. - virtual void FinishWriting() = 0; - - // Marks this stream as finished reading. Further incoming data is discarded. - // The stream will no longer call OnReceived(). - // It is never necessary to call FinishReading(). The read-side closes when a - // FIN is received, regardless of whether FinishReading() has been called. - virtual void FinishReading() = 0; - - // Once Close is called, no more data can be sent, all buffered data will be - // dropped and no data will be retransmitted. - virtual void Close() = 0; - - // Implemented by the user of the QuartcStreamInterface to receive incoming - // data and be notified of state changes. - class Delegate { - public: - virtual ~Delegate() {} - - // Called when the stream receives the data. Called with |size| == 0 after - // all stream data has been delivered. - virtual void OnReceived(QuartcStreamInterface* stream, - const char* data, - size_t size) = 0; - - // Called when the stream is closed, either locally or by the remote - // endpoint. Streams close when (a) fin bits are both sent and received, - // (b) Close() is called, or (c) the stream is reset. - // TODO(zhihuang) Creates a map from the integer error_code to WebRTC native - // error code. - virtual void OnClose(QuartcStreamInterface* stream) = 0; - - // Called when the contents of the stream's buffer changes. - virtual void OnBufferChanged(QuartcStreamInterface* stream) = 0; - }; - - // The |delegate| is not owned by QuartcStream. - virtual void SetDelegate(Delegate* delegate) = 0; -}; - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_STREAM_INTERFACE_H_
diff --git a/net/third_party/quic/quartc/quartc_stream_test.cc b/net/third_party/quic/quartc/quartc_stream_test.cc index 66e3673..353990ec 100644 --- a/net/third_party/quic/quartc/quartc_stream_test.cc +++ b/net/third_party/quic/quartc/quartc_stream_test.cc
@@ -11,9 +11,9 @@ #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quic/platform/api/quic_test.h" #include "net/third_party/quic/platform/api/quic_test_mem_slice_vector.h" -#include "net/third_party/quic/quartc/quartc_clock_interface.h" #include "net/third_party/quic/quartc/quartc_factory.h" #include "net/third_party/quic/test_tools/mock_clock.h" +#include "net/third_party/quic/test_tools/quic_test_utils.h" #include "net/third_party/spdy/core/spdy_protocol.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -23,7 +23,6 @@ namespace { static const QuicStreamId kStreamId = 5; -static const QuartcStreamInterface::WriteParameters kDefaultParam; // MockQuicSession that does not create streams and writes data from // QuicStream to a string. @@ -31,7 +30,7 @@ public: MockQuicSession(QuicConnection* connection, const QuicConfig& config, - std::string* write_buffer) + QuicString* write_buffer) : QuicSession(connection, nullptr /*visitor*/, config), write_buffer_(write_buffer) {} @@ -92,7 +91,7 @@ private: // Stores written data from ReliableQuicStreamAdapter. - std::string* write_buffer_; + QuicString* write_buffer_; // Whether data is written to write_buffer_. bool writable_ = true; }; @@ -132,23 +131,23 @@ WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); } }; -class MockQuartcStreamDelegate : public QuartcStreamInterface::Delegate { +class MockQuartcStreamDelegate : public QuartcStream::Delegate { public: - MockQuartcStreamDelegate(int id, std::string* read_buffer) + MockQuartcStreamDelegate(int id, QuicString* read_buffer) : id_(id), read_buffer_(read_buffer) {} - void OnBufferChanged(QuartcStreamInterface* stream) override { - last_bytes_buffered_ = stream->bytes_buffered(); + void OnBufferChanged(QuartcStream* stream) override { + last_bytes_buffered_ = stream->BufferedDataBytes(); } - void OnReceived(QuartcStreamInterface* stream, + void OnReceived(QuartcStream* stream, const char* data, size_t size) override { - EXPECT_EQ(id_, stream->stream_id()); + EXPECT_EQ(id_, stream->id()); read_buffer_->append(data, size); } - void OnClose(QuartcStreamInterface* stream) override { closed_ = true; } + void OnClose(QuartcStream* stream) override { closed_ = true; } bool closed() { return closed_; } @@ -157,7 +156,7 @@ protected: uint32_t id_; // Data read by the QuicStream. - std::string* read_buffer_; + QuicString* read_buffer_; // Whether the QuicStream is closed. bool closed_ = false; @@ -174,9 +173,7 @@ ip.FromString("0.0.0.0"); bool owns_writer = true; - // We only use QuartcFactory for its role as an alarm factory. - QuartcFactoryConfig config; - alarm_factory_ = QuicMakeUnique<QuartcFactory>(config); + alarm_factory_ = QuicMakeUnique<test::MockAlarmFactory>(); connection_ = QuicMakeUnique<QuicConnection>( 0, QuicSocketAddress(ip, 0), this /*QuicConnectionHelperInterface*/, @@ -210,9 +207,9 @@ std::unique_ptr<MockQuartcStreamDelegate> mock_stream_delegate_; std::unique_ptr<MockQuicSession> session_; // Data written by the ReliableQuicStreamAdapterTest. - std::string write_buffer_; + QuicString write_buffer_; // Data read by the ReliableQuicStreamAdapterTest. - std::string read_buffer_; + QuicString read_buffer_; std::unique_ptr<QuicAlarmFactory> alarm_factory_; std::unique_ptr<QuicConnection> connection_; // Used to implement the QuicConnectionHelperInterface. @@ -225,7 +222,7 @@ CreateReliableQuicStream(); char message[] = "Foo bar"; test::QuicTestMemSliceVector data({std::make_pair(message, 7)}); - stream_->Write(data.span(), kDefaultParam); + stream_->WriteMemSlices(data.span(), /*fin=*/false); EXPECT_EQ("Foo bar", write_buffer_); } @@ -234,7 +231,7 @@ CreateReliableQuicStream(); char message[] = "Foo bar"; test::QuicTestMemSliceVector data({std::make_pair(message, 5)}); - stream_->Write(data.span(), kDefaultParam); + stream_->WriteMemSlices(data.span(), /*fin=*/false); EXPECT_EQ("Foo b", write_buffer_); } @@ -247,11 +244,11 @@ // The stream is not yet writable, so data will be buffered. session_->set_writable(false); - stream_->Write(data.span(), kDefaultParam); + stream_->WriteMemSlices(data.span(), /*fin=*/false); // Check that data is buffered. EXPECT_TRUE(stream_->HasBufferedData()); - EXPECT_EQ(7u, stream_->bytes_buffered()); + EXPECT_EQ(7u, stream_->BufferedDataBytes()); // Check that the stream told its delegate about the buffer change. EXPECT_EQ(7u, mock_stream_delegate_->last_bytes_buffered()); @@ -265,10 +262,10 @@ test::QuicTestMemSliceVector data1({std::make_pair(message1, 5)}); // More writes go into the buffer. - stream_->Write(data1.span(), kDefaultParam); + stream_->WriteMemSlices(data1.span(), /*fin=*/false); EXPECT_TRUE(stream_->HasBufferedData()); - EXPECT_EQ(12u, stream_->bytes_buffered()); + EXPECT_EQ(12u, stream_->BufferedDataBytes()); EXPECT_EQ(12u, mock_stream_delegate_->last_bytes_buffered()); EXPECT_EQ(0ul, write_buffer_.size()); @@ -277,7 +274,7 @@ stream_->OnCanWrite(); EXPECT_FALSE(stream_->HasBufferedData()); - EXPECT_EQ(0u, stream_->bytes_buffered()); + EXPECT_EQ(0u, stream_->BufferedDataBytes()); EXPECT_EQ(0u, mock_stream_delegate_->last_bytes_buffered()); EXPECT_EQ("Foo barxyzzy", write_buffer_); } @@ -317,10 +314,11 @@ EXPECT_EQ("Hello", read_buffer_); } -// Streams do not call OnReceived() after FinishReading(). -TEST_F(QuartcStreamTest, FinishReading) { +// Streams do not call OnReceived() after StopReading(). +// Note: this is tested here because Quartc relies on this behavior. +TEST_F(QuartcStreamTest, StopReading) { CreateReliableQuicStream(); - stream_->FinishReading(); + stream_->StopReading(); QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!"); stream_->OnStreamFrame(frame); @@ -348,10 +346,8 @@ QuicStreamFrame frame(kStreamId, true, 0, 0); stream_->OnStreamFrame(frame); - QuartcStreamInterface::WriteParameters param; - param.fin = true; test::QuicTestMemSliceVector data({}); - stream_->Write(data.span(), param); + stream_->WriteMemSlices(data.span(), /*fin=*/true); // Check that the OnClose() callback occurred. EXPECT_TRUE(mock_stream_delegate_->closed());
diff --git a/net/third_party/quic/quartc/quartc_task_runner_interface.h b/net/third_party/quic/quartc/quartc_task_runner_interface.h deleted file mode 100644 index b3560b3c..0000000 --- a/net/third_party/quic/quartc/quartc_task_runner_interface.h +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright (c) 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_TASK_RUNNER_INTERFACE_H_ -#define NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_TASK_RUNNER_INTERFACE_H_ - -#include <stdint.h> - -#include <memory> - -namespace quic { - -// Used by platform specific QuicAlarms. For example, WebRTC will use it to set -// and cancel an alarm. When setting an alarm, the task runner will schedule a -// task on rtc::Thread. When canceling an alarm, the canceler for that task will -// be called. -class QuartcTaskRunnerInterface { - public: - virtual ~QuartcTaskRunnerInterface() {} - - class Task { - public: - virtual ~Task() {} - - // Called when it's time to start the task. - virtual void Run() = 0; - }; - - // A handler used to cancel a scheduled task. In some cases, a task cannot - // be directly canceled with its pointer. For example, in WebRTC, the task - // will be scheduled on rtc::Thread. When canceling a task, its pointer cannot - // locate the scheduled task in the thread message queue. So when scheduling a - // task, an additional handler (ScheduledTask) will be returned. - class ScheduledTask { - public: - virtual ~ScheduledTask() {} - - // Cancels a scheduled task, meaning the task will not be run. - virtual void Cancel() = 0; - }; - - // Schedules a task, which will be run after the given delay. A ScheduledTask - // may be used to cancel the task. - virtual std::unique_ptr<ScheduledTask> Schedule(Task* task, - uint64_t delay_ms) = 0; -}; - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_QUARTC_QUARTC_TASK_RUNNER_INTERFACE_H_
diff --git a/net/url_request/url_request_ftp_job.cc b/net/url_request/url_request_ftp_job.cc index 8e5b990b..cebe3a8be 100644 --- a/net/url_request/url_request_ftp_job.cc +++ b/net/url_request/url_request_ftp_job.cc
@@ -46,7 +46,6 @@ priority_(DEFAULT_PRIORITY), proxy_resolution_service_( request_->context()->proxy_resolution_service()), - proxy_resolve_request_(NULL), http_response_info_(NULL), read_in_progress_(false), ftp_transaction_factory_(ftp_transaction_factory), @@ -129,8 +128,7 @@ void URLRequestFtpJob::Kill() { if (proxy_resolve_request_) { - proxy_resolution_service_->CancelRequest(proxy_resolve_request_); - proxy_resolve_request_ = nullptr; + proxy_resolve_request_.reset(); } if (ftp_transaction_) ftp_transaction_.reset(); @@ -282,7 +280,7 @@ LoadState URLRequestFtpJob::GetLoadState() const { if (proxy_resolve_request_) - return proxy_resolution_service_->GetLoadState(proxy_resolve_request_); + return proxy_resolve_request_->GetLoadState(); if (proxy_info_.is_direct()) { return ftp_transaction_ ? ftp_transaction_->GetLoadState() : LOAD_STATE_IDLE;
diff --git a/net/url_request/url_request_ftp_job.h b/net/url_request/url_request_ftp_job.h index 9b56e7c..1e701c96 100644 --- a/net/url_request/url_request_ftp_job.h +++ b/net/url_request/url_request_ftp_job.h
@@ -81,7 +81,7 @@ ProxyResolutionService* proxy_resolution_service_; ProxyInfo proxy_info_; - ProxyResolutionService::Request* proxy_resolve_request_; + std::unique_ptr<ProxyResolutionService::Request> proxy_resolve_request_; FtpRequestInfo ftp_request_info_; std::unique_ptr<FtpTransaction> ftp_transaction_;
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index 4b2b45f..a3585e47 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -2022,7 +2022,7 @@ // Before there's a proxy configuration, proxy requests should hang. net::ProxyInfo proxy_info; net::TestCompletionCallback test_callback; - net::ProxyResolutionService::Request* request = nullptr; + std::unique_ptr<net::ProxyResolutionService::Request> request = nullptr; ASSERT_EQ(net::ERR_IO_PENDING, proxy_resolution_service->ResolveProxy( GURL("http://bar/"), "GET", &proxy_info, test_callback.callback(), &request,
diff --git a/services/network/proxy_resolving_client_socket.cc b/services/network/proxy_resolving_client_socket.cc index 27d701b..145ba1ca 100644 --- a/services/network/proxy_resolving_client_socket.cc +++ b/services/network/proxy_resolving_client_socket.cc
@@ -37,7 +37,6 @@ : network_session_(network_session), socket_handle_(std::make_unique<net::ClientSocketHandle>()), ssl_config_(ssl_config), - proxy_resolve_request_(nullptr), url_(url), use_tls_(use_tls), net_log_(net::NetLogWithSource::Make(network_session_->net_log(), @@ -117,9 +116,7 @@ void ProxyResolvingClientSocket::Disconnect() { CloseSocket(true /*close_connection*/); if (proxy_resolve_request_) { - network_session_->proxy_resolution_service()->CancelRequest( - proxy_resolve_request_); - proxy_resolve_request_ = nullptr; + proxy_resolve_request_.reset(); } user_connect_callback_.Reset(); }
diff --git a/services/network/proxy_resolving_client_socket.h b/services/network/proxy_resolving_client_socket.h index d5e82b88..da4d179a 100644 --- a/services/network/proxy_resolving_client_socket.h +++ b/services/network/proxy_resolving_client_socket.h
@@ -127,7 +127,7 @@ std::unique_ptr<net::ClientSocketHandle> socket_handle_; const net::SSLConfig ssl_config_; - net::ProxyResolutionService::Request* proxy_resolve_request_; + std::unique_ptr<net::ProxyResolutionService::Request> proxy_resolve_request_; net::ProxyInfo proxy_info_; const GURL url_; const bool use_tls_;
diff --git a/services/network/public/cpp/network_ipc_param_traits.h b/services/network/public/cpp/network_ipc_param_traits.h index 76ecabe..f330a76c 100644 --- a/services/network/public/cpp/network_ipc_param_traits.h +++ b/services/network/public/cpp/network_ipc_param_traits.h
@@ -204,7 +204,6 @@ IPC_STRUCT_TRAITS_MEMBER(ssl_info) IPC_STRUCT_TRAITS_MEMBER(cors_exposed_header_names) IPC_STRUCT_TRAITS_MEMBER(async_revalidation_requested) - IPC_STRUCT_TRAITS_MEMBER(did_mime_sniff) IPC_STRUCT_TRAITS_END() IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::FetchResponseType,
diff --git a/services/network/public/cpp/resource_response.cc b/services/network/public/cpp/resource_response.cc index bfc4f4a..7b26664 100644 --- a/services/network/public/cpp/resource_response.cc +++ b/services/network/public/cpp/resource_response.cc
@@ -60,7 +60,6 @@ head.should_report_corb_blocking; new_response->head.async_revalidation_requested = head.async_revalidation_requested; - new_response->head.did_mime_sniff = head.did_mime_sniff; return new_response; }
diff --git a/services/network/public/cpp/resource_response_info.cc b/services/network/public/cpp/resource_response_info.cc index 1d06888d..343ab0a 100644 --- a/services/network/public/cpp/resource_response_info.cc +++ b/services/network/public/cpp/resource_response_info.cc
@@ -29,8 +29,7 @@ cert_status(0), did_service_worker_navigation_preload(false), should_report_corb_blocking(false), - async_revalidation_requested(false), - did_mime_sniff(false) {} + async_revalidation_requested(false) {} ResourceResponseInfo::ResourceResponseInfo(const ResourceResponseInfo& other) = default;
diff --git a/services/network/public/cpp/resource_response_info.h b/services/network/public/cpp/resource_response_info.h index 3c57609..a55dec1 100644 --- a/services/network/public/cpp/resource_response_info.h +++ b/services/network/public/cpp/resource_response_info.h
@@ -179,10 +179,6 @@ // possibly be set if the load_flags indicated SUPPORT_ASYNC_REVALIDATION. bool async_revalidation_requested; - // True if mime sniffing has been done. In that case, we don't need to do - // mime sniffing anymore. - bool did_mime_sniff; - // NOTE: When adding or changing fields here, also update // ResourceResponse::DeepCopy in resource_response.cc. };
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index a318975f..86d6409 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -794,7 +794,6 @@ // the mime type. However, even if it returns false, it returns a new type // that is probably better than the current one. response_->head.mime_type.assign(new_type); - response_->head.did_mime_sniff = true; } if (is_more_corb_sniffing_needed_) {
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc index 2751de8..68a4dcd3 100644 --- a/services/network/url_loader_unittest.cc +++ b/services/network/url_loader_unittest.cc
@@ -521,12 +521,6 @@ DCHECK(ran_); return client_.response_head().mime_type; } - - bool did_mime_sniff() const { - DCHECK(ran_); - return client_.response_head().did_mime_sniff; - } - const base::Optional<net::SSLInfo>& ssl_info() const { DCHECK(ran_); return client_.ssl_info(); @@ -733,7 +727,6 @@ TEST_F(URLLoaderTest, DoNotSniffUnlessSpecified) { EXPECT_EQ(net::OK, Load(test_server()->GetURL("/content-sniffer-test0.html"))); - EXPECT_FALSE(did_mime_sniff()); ASSERT_TRUE(mime_type().empty()); } @@ -741,22 +734,19 @@ set_sniff(); EXPECT_EQ(net::OK, Load(test_server()->GetURL("/content-sniffer-test0.html"))); - EXPECT_TRUE(did_mime_sniff()); ASSERT_EQ(std::string("text/html"), mime_type()); } TEST_F(URLLoaderTest, RespectNoSniff) { set_sniff(); EXPECT_EQ(net::OK, Load(test_server()->GetURL("/nosniff-test.html"))); - EXPECT_FALSE(did_mime_sniff()); ASSERT_TRUE(mime_type().empty()); } -TEST_F(URLLoaderTest, SniffTextPlainDoesNotResultInHTML) { +TEST_F(URLLoaderTest, DoNotSniffHTMLFromTextPlain) { set_sniff(); EXPECT_EQ(net::OK, Load(test_server()->GetURL("/content-sniffer-test1.html"))); - EXPECT_TRUE(did_mime_sniff()); ASSERT_EQ(std::string("text/plain"), mime_type()); } @@ -764,7 +754,6 @@ set_sniff(); EXPECT_EQ(net::OK, Load(test_server()->GetURL("/content-sniffer-test2.html"))); - EXPECT_FALSE(did_mime_sniff()); ASSERT_EQ(std::string("image/gif"), mime_type()); } @@ -772,7 +761,6 @@ set_sniff(); EXPECT_EQ(net::OK, Load(test_server()->GetURL("/content-sniffer-test4.html"))); - EXPECT_TRUE(did_mime_sniff()); ASSERT_EQ(std::string("text/plain"), mime_type()); } @@ -788,7 +776,6 @@ std::string body; EXPECT_EQ(net::OK, Load(MultipleWritesInterceptor::GetURL(), &body)); EXPECT_EQ(kBody, body); - EXPECT_TRUE(did_mime_sniff()); ASSERT_EQ(std::string("text/plain"), mime_type()); } @@ -803,7 +790,6 @@ EXPECT_LE(first.size() + second.size(), static_cast<uint32_t>(net::kMaxBytesToSniff)); LoadPacketsAndVerifyContents(first, second); - EXPECT_TRUE(did_mime_sniff()); ASSERT_EQ(std::string("application/octet-stream"), mime_type()); } @@ -816,7 +802,6 @@ EXPECT_GE(first.size() + second.size(), static_cast<uint32_t>(net::kMaxBytesToSniff)); LoadPacketsAndVerifyContents(first, second); - EXPECT_TRUE(did_mime_sniff()); ASSERT_EQ(std::string("application/octet-stream"), mime_type()); } @@ -826,7 +811,6 @@ set_sniff(); std::string first(net::kMaxBytesToSniff - 100, 'a'); LoadPacketsAndVerifyContents(first, std::string()); - EXPECT_TRUE(did_mime_sniff()); ASSERT_EQ(std::string("text/plain"), mime_type()); } @@ -835,7 +819,6 @@ set_sniff(); std::string first(net::kMaxBytesToSniff + 100, 'a'); LoadPacketsAndVerifyContents(first, std::string()); - EXPECT_TRUE(did_mime_sniff()); ASSERT_EQ(std::string("text/plain"), mime_type()); }
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc index dc8a3c3f..39699a5b 100644 --- a/storage/browser/quota/quota_database.cc +++ b/storage/browser/quota/quota_database.cc
@@ -45,24 +45,6 @@ const int kCommitIntervalMs = 30000; -enum OriginType { - // This enum is logged to UMA so only append to it - don't change - // the meaning of the existing values. - OTHER = 0, - NONE = 1, - GOOGLE_DURABLE = 2, - NON_GOOGLE_DURABLE = 3, - GOOGLE_UNLIMITED_EXTENSION = 4, - NON_GOOGLE_UNLIMITED_EXTENSION = 5, - IN_USE = 6, - - MAX_ORIGIN_TYPE -}; - -void HistogramOriginType(const OriginType& entry) { - UMA_HISTOGRAM_ENUMERATION("Quota.LRUOriginTypes", entry, MAX_ORIGIN_TYPE); -} - void LogDaysSinceLastAccess(base::Time this_time, const QuotaDatabase::OriginInfoTableEntry& entry) { base::TimeDelta time_since = this_time - std::max(entry.last_access_time, @@ -450,37 +432,29 @@ if (!LazyOpen(false)) return false; - const char* kSql = "SELECT origin FROM OriginInfoTable" - " WHERE type = ?" - " ORDER BY last_access_time ASC"; + static const char kSql[] = + "SELECT origin FROM OriginInfoTable" + " WHERE type = ?" + " ORDER BY last_access_time ASC"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindInt(0, static_cast<int>(type)); while (statement.Step()) { GURL url(statement.ColumnString(0)); - if (base::ContainsKey(exceptions, url)) { - HistogramOriginType(IN_USE); + if (base::ContainsKey(exceptions, url)) + continue; + + if (special_storage_policy && ( + special_storage_policy->IsStorageDurable(url) || + special_storage_policy->IsStorageUnlimited(url))) { continue; } - if (special_storage_policy) { - bool is_google = url.DomainIs("google.com"); - if (special_storage_policy->IsStorageDurable(url)) { - HistogramOriginType(is_google ? GOOGLE_DURABLE : NON_GOOGLE_DURABLE); - continue; - } - if (special_storage_policy->IsStorageUnlimited(url)) { - HistogramOriginType(is_google ? GOOGLE_UNLIMITED_EXTENSION - : NON_GOOGLE_UNLIMITED_EXTENSION); - continue; - } - } - HistogramOriginType(OTHER); + *origin = url; return true; } - HistogramOriginType(NONE); *origin = GURL(); return statement.Succeeded(); }
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 4ab245d..958f2eb 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -601,7 +601,6 @@ "script": "//tools/perf/process_perf_results.py" }, "name": "heap_profiling.mobile", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6337,7 +6336,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index f4f4487..2c29707 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -3074,7 +3074,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -19222,7 +19221,6 @@ { "isolate_name": "monochrome_apk_checker", "name": "monochrome_apk_checker", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -21893,7 +21891,6 @@ { "isolate_name": "components_perftests", "name": "components_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -21908,7 +21905,6 @@ { "isolate_name": "monochrome_apk_checker", "name": "monochrome_apk_checker", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -21927,7 +21923,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index 04d473c..2243bab 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -220,8 +220,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -932,8 +931,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -10115,7 +10113,6 @@ { "isolate_name": "monochrome_apk_checker", "name": "monochrome_apk_checker", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12985,8 +12982,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -13693,8 +13689,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -14371,8 +14366,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -15059,8 +15053,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -15757,8 +15750,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -16721,7 +16713,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -16729,7 +16720,6 @@ { "isolate_name": "components_perftests", "name": "components_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -16737,7 +16727,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -16745,7 +16734,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -16753,7 +16741,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -16761,7 +16748,6 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -16774,7 +16760,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -16783,7 +16768,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -16797,7 +16781,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -16814,7 +16797,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -24187,8 +24169,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 4d116cdf..c319d4d9 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -812,7 +812,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -820,7 +819,6 @@ { "isolate_name": "components_perftests", "name": "components_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -828,7 +826,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -836,7 +833,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -844,7 +840,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -852,7 +847,6 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -865,7 +859,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -874,7 +867,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -888,7 +880,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -898,7 +889,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1052,7 +1042,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -1066,7 +1055,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests_viz", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -1076,7 +1064,6 @@ { "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -1088,7 +1075,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests_viz", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -1576,7 +1562,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -1709,7 +1694,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -1773,8 +1757,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -1854,7 +1837,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -1883,7 +1865,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -1912,7 +1893,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -2989,7 +2969,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3015,7 +2994,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3463,7 +3441,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true @@ -3728,7 +3705,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -3990,7 +3966,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -4010,7 +3985,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -4254,8 +4228,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -4735,7 +4708,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -4743,7 +4715,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -4751,7 +4722,6 @@ { "isolate_name": "devtools_closure_compile", "name": "devtools_closure_compile", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -4759,7 +4729,6 @@ { "isolate_name": "devtools_eslint", "name": "devtools_eslint", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -4767,7 +4736,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -4789,7 +4757,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "site_per_process_webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -4804,7 +4771,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -4812,7 +4778,6 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -4825,7 +4790,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -4834,7 +4798,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -4848,7 +4811,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -4858,7 +4820,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -5587,7 +5548,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -5613,7 +5573,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -5639,7 +5598,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -5666,7 +5624,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -5694,7 +5651,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -5730,7 +5686,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -5756,7 +5711,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true,
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index adb2085..fe9ec4f 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -82,7 +82,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -178,7 +177,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -362,7 +360,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -458,7 +455,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -747,7 +743,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -771,7 +766,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -795,7 +789,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -819,7 +812,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -843,7 +835,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -871,7 +862,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -902,7 +892,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -938,7 +927,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -966,7 +954,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -990,7 +977,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1015,7 +1001,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1182,7 +1167,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1206,7 +1190,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1230,7 +1213,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1254,7 +1236,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1278,7 +1259,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1306,7 +1286,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1337,7 +1316,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1373,7 +1351,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -1401,7 +1378,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1425,7 +1401,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1450,7 +1425,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1545,7 +1519,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1568,7 +1541,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1591,7 +1563,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1614,7 +1585,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1637,7 +1607,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1664,7 +1633,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1694,7 +1662,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1729,7 +1696,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -1756,7 +1722,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1779,7 +1744,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1803,7 +1767,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1973,7 +1936,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1997,7 +1959,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2021,7 +1982,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2045,7 +2005,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2073,7 +2032,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2104,7 +2062,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2140,7 +2097,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -2168,7 +2124,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2192,7 +2147,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2217,7 +2171,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2419,7 +2372,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2443,7 +2395,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2467,7 +2418,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2491,7 +2441,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2515,7 +2464,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2543,7 +2491,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2574,7 +2521,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2610,7 +2556,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -2638,7 +2583,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2662,7 +2606,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2687,7 +2630,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2854,7 +2796,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2878,7 +2819,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2902,7 +2842,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2926,7 +2865,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2950,7 +2888,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2978,7 +2915,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3009,7 +2945,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3045,7 +2980,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -3073,7 +3007,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3097,7 +3030,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3122,7 +3054,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3399,7 +3330,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3422,7 +3352,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3445,7 +3374,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3468,7 +3396,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3495,7 +3422,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3525,7 +3451,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3560,7 +3485,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -3587,7 +3511,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3610,7 +3533,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3634,7 +3556,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3657,7 +3578,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3681,7 +3601,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3821,7 +3740,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3996,7 +3914,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4020,7 +3937,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4044,7 +3960,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4068,7 +3983,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4096,7 +4010,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4127,7 +4040,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4163,7 +4075,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -4191,7 +4102,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4215,7 +4125,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4240,7 +4149,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4266,7 +4174,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4291,7 +4198,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4316,7 +4222,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4482,7 +4387,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4505,7 +4409,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4528,7 +4431,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4551,7 +4453,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4578,7 +4479,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4608,7 +4508,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4643,7 +4542,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -4670,7 +4568,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4693,7 +4590,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4717,7 +4613,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4742,7 +4637,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4766,7 +4660,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4790,7 +4683,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4951,7 +4843,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4974,7 +4865,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4997,7 +4887,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5020,7 +4909,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5043,7 +4931,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5070,7 +4957,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5100,7 +4986,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5135,7 +5020,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -5162,7 +5046,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5185,7 +5068,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5209,7 +5091,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5234,7 +5115,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5260,7 +5140,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5284,7 +5163,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5308,7 +5186,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5559,7 +5436,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5581,7 +5457,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5603,7 +5478,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5625,7 +5499,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5651,7 +5524,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5680,7 +5552,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5714,7 +5585,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -5740,7 +5610,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5762,7 +5631,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5784,7 +5652,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5946,7 +5813,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5969,7 +5835,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -5992,7 +5857,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6015,7 +5879,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6042,7 +5905,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6072,7 +5934,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6107,7 +5968,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -6134,7 +5994,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6157,7 +6016,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6182,7 +6040,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6206,7 +6063,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6377,7 +6233,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6401,7 +6256,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6425,7 +6279,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6449,7 +6302,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6477,7 +6329,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6508,7 +6359,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6544,7 +6394,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -6572,7 +6421,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6596,7 +6444,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6622,7 +6469,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6647,7 +6493,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6827,7 +6672,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6852,7 +6696,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6877,7 +6720,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6902,7 +6744,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6931,7 +6772,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -6963,7 +6803,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7000,7 +6839,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -7029,7 +6867,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7054,7 +6891,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7081,7 +6917,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7107,7 +6942,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7331,7 +7165,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7359,7 +7192,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7387,7 +7219,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7415,7 +7246,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7450,7 +7280,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7490,7 +7319,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -7522,7 +7350,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7550,7 +7377,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7581,7 +7407,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7611,7 +7436,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7783,7 +7607,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7805,7 +7628,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7827,7 +7649,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7849,7 +7670,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7875,7 +7695,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7904,7 +7723,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7938,7 +7756,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -7964,7 +7781,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -7986,7 +7802,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8010,7 +7825,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8033,7 +7847,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8196,7 +8009,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8220,7 +8032,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8244,7 +8055,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8268,7 +8078,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8296,7 +8105,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8327,7 +8135,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8363,7 +8170,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -8391,7 +8197,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8415,7 +8220,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8439,7 +8243,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8604,7 +8407,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8628,7 +8430,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8652,7 +8453,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8676,7 +8476,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8704,7 +8503,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8735,7 +8533,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8771,7 +8568,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -8799,7 +8595,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8823,7 +8618,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8847,7 +8641,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9033,7 +8826,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9057,7 +8849,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9081,7 +8872,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9105,7 +8895,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9133,7 +8922,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9164,7 +8952,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9200,7 +8987,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -9228,7 +9014,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9252,7 +9037,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9278,7 +9062,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9303,7 +9086,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9489,7 +9271,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9513,7 +9294,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9537,7 +9317,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9561,7 +9340,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9589,7 +9367,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9620,7 +9397,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9656,7 +9432,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -9684,7 +9459,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9708,7 +9482,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9734,7 +9507,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -9759,7 +9531,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10035,7 +9806,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10059,7 +9829,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10083,7 +9852,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10107,7 +9875,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10135,7 +9902,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10166,7 +9932,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10202,7 +9967,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -10230,7 +9994,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10254,7 +10017,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10280,7 +10042,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10305,7 +10066,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10403,7 +10163,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10428,7 +10187,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10452,7 +10210,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10540,7 +10297,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10567,7 +10323,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10592,7 +10347,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10616,7 +10370,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10721,7 +10474,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10745,7 +10497,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10859,7 +10610,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -10885,7 +10635,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11001,7 +10750,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11222,7 +10970,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11247,7 +10994,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11271,7 +11017,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11295,7 +11040,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11319,7 +11063,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11343,7 +11086,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11683,7 +11425,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11719,7 +11460,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11748,7 +11488,6 @@ ], "isolate_name": "command_buffer_perftests", "name": "passthrough_command_buffer_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11777,7 +11516,6 @@ ], "isolate_name": "command_buffer_perftests", "name": "validating_command_buffer_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11811,7 +11549,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11844,7 +11581,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11877,7 +11613,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11910,7 +11645,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -11943,7 +11677,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12257,7 +11990,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12280,7 +12012,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12303,7 +12034,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12326,7 +12056,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12353,7 +12082,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12383,7 +12111,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12418,7 +12145,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -12445,7 +12171,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12468,7 +12193,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12492,7 +12216,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12515,7 +12238,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12539,7 +12261,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12563,7 +12284,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12587,7 +12307,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12611,7 +12330,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12895,7 +12613,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12918,7 +12635,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12941,7 +12657,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12964,7 +12679,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -12991,7 +12705,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13021,7 +12734,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13056,7 +12768,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -13083,7 +12794,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13106,7 +12816,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13130,7 +12839,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13155,7 +12863,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13179,7 +12886,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13203,7 +12909,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13227,7 +12932,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13255,7 +12959,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "noop_sleep_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13560,7 +13263,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13583,7 +13285,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13606,7 +13307,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13629,7 +13329,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13656,7 +13355,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13686,7 +13384,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13721,7 +13418,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -13748,7 +13444,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13771,7 +13466,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13795,7 +13489,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13820,7 +13513,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13844,7 +13536,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13868,7 +13559,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13892,7 +13582,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13916,7 +13605,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -13940,7 +13628,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14414,7 +14101,6 @@ ], "isolate_name": "angle_perftests", "name": "angle_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14446,7 +14132,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14478,7 +14163,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14510,7 +14194,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14542,7 +14225,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14578,7 +14260,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14617,7 +14298,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14646,7 +14326,6 @@ ], "isolate_name": "command_buffer_perftests", "name": "passthrough_command_buffer_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14690,7 +14369,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -14726,7 +14404,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14758,7 +14435,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14787,7 +14463,6 @@ ], "isolate_name": "command_buffer_perftests", "name": "validating_command_buffer_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14820,7 +14495,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14854,7 +14528,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14889,7 +14562,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14924,7 +14596,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14957,7 +14628,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -14990,7 +14660,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15023,7 +14692,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15056,7 +14724,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15089,7 +14756,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15340,7 +15006,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15364,7 +15029,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15647,7 +15311,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15670,7 +15333,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15693,7 +15355,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15716,7 +15377,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15743,7 +15403,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15773,7 +15432,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15808,7 +15466,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -15835,7 +15492,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15858,7 +15514,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15882,7 +15537,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15905,7 +15559,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15929,7 +15582,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15953,7 +15605,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -15977,7 +15628,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16280,7 +15930,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16303,7 +15952,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16326,7 +15974,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16349,7 +15996,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16376,7 +16022,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16406,7 +16051,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16441,7 +16085,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -16468,7 +16111,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16491,7 +16133,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16515,7 +16156,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16540,7 +16180,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16564,7 +16203,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16588,7 +16226,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16612,7 +16249,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -16636,7 +16272,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17083,7 +16718,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17115,7 +16749,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17147,7 +16780,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17179,7 +16811,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17215,7 +16846,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17254,7 +16884,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17298,7 +16927,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -17334,7 +16962,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17366,7 +16993,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17399,7 +17025,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17433,7 +17058,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17466,7 +17090,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17499,7 +17122,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17532,7 +17154,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17565,7 +17186,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17598,7 +17218,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17952,7 +17571,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17975,7 +17593,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -17998,7 +17615,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18021,7 +17637,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18048,7 +17663,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18078,7 +17692,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18113,7 +17726,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -18140,7 +17752,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18163,7 +17774,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18187,7 +17797,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18212,7 +17821,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18236,7 +17844,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d11_validating_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18260,7 +17867,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18284,7 +17890,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_d3d9_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18308,7 +17913,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_gl_passthrough_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -18332,7 +17936,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [
diff --git a/testing/buildbot/chromium.gpu.json b/testing/buildbot/chromium.gpu.json index c7fbadcd..7e441b26 100644 --- a/testing/buildbot/chromium.gpu.json +++ b/testing/buildbot/chromium.gpu.json
@@ -14,7 +14,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -37,7 +36,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -60,7 +58,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -83,7 +80,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -110,7 +106,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -140,7 +135,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -175,7 +169,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -202,7 +195,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -225,7 +217,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -249,7 +240,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -337,7 +327,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -360,7 +349,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -383,7 +371,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -406,7 +393,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -433,7 +419,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -463,7 +448,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -498,7 +482,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -525,7 +508,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -548,7 +530,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -572,7 +553,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -595,7 +575,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -698,7 +677,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -721,7 +699,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -744,7 +721,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -767,7 +743,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -794,7 +769,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -824,7 +798,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -859,7 +832,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -886,7 +858,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -909,7 +880,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -933,7 +903,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -956,7 +925,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1033,7 +1001,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1055,7 +1022,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1077,7 +1043,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1099,7 +1064,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1125,7 +1089,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1154,7 +1117,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1188,7 +1150,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -1214,7 +1175,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1236,7 +1196,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1258,7 +1217,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1353,7 +1311,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1375,7 +1332,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1397,7 +1353,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1419,7 +1374,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1445,7 +1399,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1474,7 +1427,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1508,7 +1460,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -1534,7 +1485,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1556,7 +1506,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1578,7 +1527,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1660,7 +1608,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1684,7 +1631,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1708,7 +1654,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1732,7 +1677,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1760,7 +1704,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1791,7 +1734,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1827,7 +1769,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -1855,7 +1796,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1879,7 +1819,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1903,7 +1842,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2008,7 +1946,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2032,7 +1969,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2056,7 +1992,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2080,7 +2015,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2108,7 +2042,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2139,7 +2072,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2175,7 +2107,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -2203,7 +2134,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2227,7 +2157,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2251,7 +2180,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2391,7 +2319,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2414,7 +2341,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2437,7 +2363,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2460,7 +2385,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2487,7 +2411,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2517,7 +2440,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2552,7 +2474,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -2579,7 +2500,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2602,7 +2522,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2626,7 +2545,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2649,7 +2567,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2871,7 +2788,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2903,7 +2819,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2935,7 +2850,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2967,7 +2881,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3003,7 +2916,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "info_collection_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3042,7 +2954,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3086,7 +2997,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -3122,7 +3032,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3154,7 +3063,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3187,7 +3095,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "viz_screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -3219,7 +3126,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [
diff --git a/testing/buildbot/chromium.json b/testing/buildbot/chromium.json index 3763f70..fcdd1ed 100644 --- a/testing/buildbot/chromium.json +++ b/testing/buildbot/chromium.json
@@ -50,5 +50,60 @@ "script": "checkbins.py" } ] + }, + "android-rel": { + "additional_compile_targets": [ + "all" + ] + }, + "linux-rel": { + "additional_compile_targets": [ + "all" + ], + "scripts": [ + { + "args": [ + "linux-release-64/sizes" + ], + "name": "sizes", + "script": "sizes.py" + } + ] + }, + "mac-rel": { + "additional_compile_targets": [ + "all" + ], + "scripts": [ + { + "args": [ + "mac-release/sizes" + ], + "name": "sizes", + "script": "sizes.py" + } + ] + }, + "win-rel": { + "additional_compile_targets": [ + "all" + ], + "scripts": [ + { + "name": "checkbins", + "script": "checkbins.py" + } + ] + }, + "win32-rel": { + "additional_compile_targets": [ + "all" + ], + "scripts": [ + { + "name": "checkbins", + "script": "checkbins.py" + } + ] } }
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 67ade18..4f55a25 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -792,7 +792,6 @@ "script": "//tools/perf/process_perf_results.py" }, "name": "memory.leak_detection", - "only_retry_failed_tests": true, "override_compile_targets": [ "performance_test_suite" ], @@ -1047,8 +1046,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -1528,7 +1526,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1536,7 +1533,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1544,7 +1540,6 @@ { "isolate_name": "devtools_closure_compile", "name": "devtools_closure_compile", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1552,7 +1547,6 @@ { "isolate_name": "devtools_eslint", "name": "devtools_eslint", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1560,7 +1554,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1582,7 +1575,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "site_per_process_webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -1597,7 +1589,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1609,7 +1600,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -1622,7 +1612,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -1631,7 +1620,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1645,7 +1633,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -1660,7 +1647,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1900,8 +1886,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -2379,7 +2364,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2387,7 +2371,6 @@ { "isolate_name": "devtools_closure_compile", "name": "devtools_closure_compile", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2395,7 +2378,6 @@ { "isolate_name": "devtools_eslint", "name": "devtools_eslint", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2403,7 +2385,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2411,7 +2392,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2423,7 +2403,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -2436,7 +2415,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -2445,7 +2423,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2462,7 +2439,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -2477,7 +2453,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3074,7 +3049,6 @@ { "isolate_name": "devtools_closure_compile", "name": "devtools_closure_compile", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3082,7 +3056,6 @@ { "isolate_name": "devtools_eslint", "name": "devtools_eslint", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3090,7 +3063,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3098,7 +3070,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3109,7 +3080,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -3118,7 +3088,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3126,7 +3095,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3533,8 +3501,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -4369,7 +4336,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4382,7 +4348,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4395,7 +4360,6 @@ { "isolate_name": "devtools_closure_compile", "name": "devtools_closure_compile", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4408,7 +4372,6 @@ { "isolate_name": "devtools_eslint", "name": "devtools_eslint", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4421,7 +4384,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4448,7 +4410,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "site_per_process_webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -4463,7 +4424,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4480,7 +4440,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4498,7 +4457,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4512,7 +4470,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4531,7 +4488,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -4546,7 +4502,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index bbfeeee..61414b2 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -495,7 +495,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -503,7 +502,6 @@ { "isolate_name": "components_perftests", "name": "components_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -511,7 +509,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -519,7 +516,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -527,7 +523,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -538,7 +533,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -551,7 +545,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -560,7 +553,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -574,7 +566,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -590,7 +581,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1103,7 +1093,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1111,7 +1100,6 @@ { "isolate_name": "components_perftests", "name": "components_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1119,7 +1107,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1127,7 +1114,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1135,7 +1121,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1146,7 +1131,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -1159,7 +1143,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -1168,7 +1151,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1182,7 +1164,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -1198,7 +1179,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2180,7 +2160,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2194,7 +2173,6 @@ { "isolate_name": "components_perftests", "name": "components_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2208,7 +2186,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2222,7 +2199,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2236,7 +2212,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2253,7 +2228,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2272,7 +2246,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2287,7 +2260,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2307,7 +2279,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -2324,7 +2295,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2844,7 +2814,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2852,7 +2821,6 @@ { "isolate_name": "components_perftests", "name": "components_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2860,7 +2828,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2868,7 +2835,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2876,7 +2842,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2887,7 +2852,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -2896,7 +2860,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2911,7 +2874,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -2928,7 +2890,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3444,7 +3405,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3452,7 +3412,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3471,7 +3430,6 @@ "script": "//tools/perf/process_perf_results.py" }, "name": "performance_test_suite", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -3481,7 +3439,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3492,7 +3449,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -3501,7 +3457,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3518,7 +3473,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -3528,7 +3482,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true }
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 268426e2..f8b0cd8 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -3680,8 +3680,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -4305,7 +4304,7 @@ "name": "viz_browser_tests", "swarming": { "can_use_on_swarming_builders": true, - "shards": 20 + "shards": 30 }, "test": "browser_tests" }, @@ -5628,8 +5627,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": {
diff --git a/testing/buildbot/chromium.swarm.json b/testing/buildbot/chromium.swarm.json index 59a04d37..b2e0d7a 100644 --- a/testing/buildbot/chromium.swarm.json +++ b/testing/buildbot/chromium.swarm.json
@@ -696,7 +696,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -717,7 +716,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [
diff --git a/testing/buildbot/chromium.webkit.json b/testing/buildbot/chromium.webkit.json index b2a5531..bb5c3c4 100644 --- a/testing/buildbot/chromium.webkit.json +++ b/testing/buildbot/chromium.webkit.json
@@ -19,7 +19,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -51,7 +50,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -83,7 +81,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -111,7 +108,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -139,7 +135,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true,
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 8a689e9..c70b406 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -651,7 +651,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -659,7 +658,6 @@ { "isolate_name": "components_perftests", "name": "components_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -667,7 +665,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -675,7 +672,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -683,7 +679,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -691,7 +686,6 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -704,7 +698,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -713,7 +706,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -721,7 +713,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -1394,7 +1385,6 @@ { "isolate_name": "mini_installer_tests", "name": "mini_installer_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -2016,7 +2006,6 @@ "experiment_percentage": 100, "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2024,7 +2013,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2044,7 +2032,6 @@ "script": "//tools/perf/process_perf_results.py" }, "name": "performance_test_suite", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -2054,7 +2041,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2065,7 +2051,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -2074,7 +2059,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2082,7 +2066,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2736,7 +2719,6 @@ ], "isolate_name": "chromedriver_py_tests", "name": "chromedriver_py_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2744,7 +2726,6 @@ { "isolate_name": "components_perftests", "name": "components_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2752,7 +2733,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2760,7 +2740,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2768,7 +2747,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2776,7 +2754,6 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -2789,7 +2766,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -2798,7 +2774,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -2812,7 +2787,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -2822,7 +2796,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3501,7 +3474,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3509,7 +3481,6 @@ { "isolate_name": "metrics_python_tests", "name": "metrics_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3528,7 +3499,6 @@ "script": "//tools/perf/process_perf_results.py" }, "name": "performance_test_suite", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -3538,7 +3508,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3550,7 +3519,6 @@ "experiment_percentage": 100, "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -3563,7 +3531,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -3572,7 +3539,6 @@ { "isolate_name": "views_perftests", "name": "views_perftests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -3592,7 +3558,6 @@ "script": "//third_party/blink/tools/merge_web_test_results.py" }, "name": "webkit_layout_tests", - "only_retry_failed_tests": true, "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -3607,7 +3572,6 @@ { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true }
diff --git a/testing/buildbot/client.v8.chromium.json b/testing/buildbot/client.v8.chromium.json index dce3ac84..78e1271 100644 --- a/testing/buildbot/client.v8.chromium.json +++ b/testing/buildbot/client.v8.chromium.json
@@ -65,8 +65,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -225,7 +224,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -233,7 +231,6 @@ { "isolate_name": "devtools_closure_compile", "name": "devtools_closure_compile", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -241,7 +238,6 @@ { "isolate_name": "devtools_eslint", "name": "devtools_eslint", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -249,7 +245,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -260,7 +255,6 @@ ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "hard_timeout": 960, @@ -273,7 +267,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4 @@ -345,8 +338,7 @@ }, { "args": [ - "--site-per-process", - "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" + "--site-per-process" ], "name": "site_per_process_content_browsertests", "swarming": { @@ -506,7 +498,6 @@ { "isolate_name": "content_shell_crash_test", "name": "content_shell_crash_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -514,7 +505,6 @@ { "isolate_name": "devtools_closure_compile", "name": "devtools_closure_compile", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -522,7 +512,6 @@ { "isolate_name": "devtools_eslint", "name": "devtools_eslint", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -530,7 +519,6 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -541,7 +529,6 @@ ], "isolate_name": "telemetry_unittests", "name": "telemetry_unittests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "shards": 4
diff --git a/testing/buildbot/client.v8.fyi.json b/testing/buildbot/client.v8.fyi.json index 184a79e..4789212 100644 --- a/testing/buildbot/client.v8.fyi.json +++ b/testing/buildbot/client.v8.fyi.json
@@ -14,7 +14,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -37,7 +36,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -60,7 +58,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -83,7 +80,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -113,7 +109,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -148,7 +143,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -175,7 +169,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -198,7 +191,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -222,7 +214,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -250,7 +241,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -273,7 +263,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -296,7 +285,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -319,7 +307,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -349,7 +336,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -384,7 +370,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -411,7 +396,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -434,7 +418,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -459,7 +442,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -483,7 +465,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -511,7 +492,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -534,7 +514,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -557,7 +536,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -580,7 +558,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -610,7 +587,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -645,7 +621,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -672,7 +647,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -695,7 +669,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -720,7 +693,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -744,7 +716,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -772,7 +743,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -794,7 +764,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -816,7 +785,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -838,7 +806,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -867,7 +834,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -901,7 +867,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -927,7 +892,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -949,7 +913,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -973,7 +936,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -996,7 +958,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1078,7 +1039,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "context_lost_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1101,7 +1061,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "depth_capture_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1124,7 +1083,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "gpu_process_launch_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1147,7 +1105,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "hardware_accelerated_feature_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1177,7 +1134,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "maps_pixel_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1212,7 +1168,6 @@ "non_precommit_args": [ "--upload-refimg-to-cloud-storage" ], - "only_retry_failed_tests": true, "precommit_args": [ "--download-refimg-from-cloud-storage" ], @@ -1239,7 +1194,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "screenshot_sync_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1262,7 +1216,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "trace_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1287,7 +1240,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl2_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1311,7 +1263,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "webgl_conformance_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 21fc4793..d21a5271 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -39,7 +39,6 @@ data = [ "//testing/buildbot/filters/cast-linux.content_browsertests.filter", "//testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter", - "//testing/buildbot/filters/site-per-process.content_browsertests.filter", ] }
diff --git a/testing/buildbot/filters/README.md b/testing/buildbot/filters/README.md index fb79b59e..f8a82b4 100644 --- a/testing/buildbot/filters/README.md +++ b/testing/buildbot/filters/README.md
@@ -3,9 +3,9 @@ ## Summary This directory contains files that list tests that are not yet ready to run in a -particular mode. For example - the `site-per-process.content_browsertests.filter` file -lists tests that should be excluded when running `content_browsertests` in -`--site-per-process` mode. +particular mode. For example - the `cast-linux.content_browsertests.filter` file +lists tests that should be excluded when running `content_browsertests` on the +Cast device or bot (e.g. on 'Cast Linux). ## File syntax @@ -49,8 +49,7 @@ ```bash $ out/dbg/content_browsertests \ - --site-per-process \ - --test-launcher-filter-file=testing/buildbot/filters/site-per-process.content_browsertests.filter + --test-launcher-filter-file=testing/buildbot/filters/foo.content_browsertests.filter ``` When running tests on Android, the test filter file can also be specified using @@ -58,8 +57,7 @@ ```bash $ out/android/bin/run_content_browsertests \ - --site-per-process \ - --test-launcher-filter-file=testing/buildbot/filters/site-per-process.content_browsertests.filter + --test-launcher-filter-file=testing/buildbot/filters/foo.content_browsertests.filter ``` ## Applicability
diff --git a/testing/buildbot/filters/site-per-process.content_browsertests.filter b/testing/buildbot/filters/site-per-process.content_browsertests.filter deleted file mode 100644 index 4719bc6..0000000 --- a/testing/buildbot/filters/site-per-process.content_browsertests.filter +++ /dev/null
@@ -1,6 +0,0 @@ -# crbug.com/417518: Get tests working with --site-per-process --NavigationControllerBrowserTest.ReloadOriginalRequest - -# Untriaged. --LoaderBrowserTest.CookieSameSiteStrictOpenNewNamedWindowTwice -
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py index 29e698f..29bde5e 100755 --- a/testing/buildbot/generate_buildbot_json.py +++ b/testing/buildbot/generate_buildbot_json.py
@@ -500,9 +500,6 @@ self.initialize_args_for_test(result, tester_config) result = self.update_and_cleanup_test(result, test_name, tester_name) self.add_common_test_properties(result, tester_config) - - # TODO(martiniss): Remove this. https://crbug.com/533481 - result['only_retry_failed_tests'] = True return result def generate_script_test(self, waterfall, tester_name, tester_config, @@ -751,6 +748,12 @@ 'WebKit Linux layout_ng Dummy Builder', 'WebKit Linux root_layer_scrolls Dummy Builder', 'WebKit Linux slimming_paint_v2 Dummy Builder', + #chromium + 'android-rel', + 'linux-rel', + 'mac-rel', + 'win32-rel', + 'win-rel', ] def check_input_file_consistency(self):
diff --git a/testing/buildbot/generate_buildbot_json_unittest.py b/testing/buildbot/generate_buildbot_json_unittest.py index 0e5fc430..8ffc29a3 100755 --- a/testing/buildbot/generate_buildbot_json_unittest.py +++ b/testing/buildbot/generate_buildbot_json_unittest.py
@@ -804,7 +804,6 @@ { "isolate_name": "foo_test", "name": "foo_test", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true } @@ -926,7 +925,6 @@ ], "isolate_name": "telemetry_gpu_integration_test", "name": "foo_tests", - "only_retry_failed_tests": true, "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index a4d57c4..04f381d 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -257,6 +257,8 @@ 'remove_from': [ 'Linux x64', 'Mac', + 'linux-rel', + 'mac-rel', ], }, 'chrome_public_test_apk': { @@ -1079,9 +1081,21 @@ 'remove_from': [ 'Win', 'Win x64', + 'win32-rel', + 'win-rel', ], 'modifications': { # chromium + 'mac-rel': { + 'args': [ + 'mac-release/sizes', + ], + }, + 'linux-rel': { + 'args': [ + 'linux-release-64/sizes', + ], + }, 'Mac': { 'args': [ 'mac-release/sizes', @@ -1428,7 +1442,7 @@ # These are very slow on the ASAN trybot for some reason. # crbug.com/794372 'swarming': { - 'shards': 20, + 'shards': 30, }, }, },
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 554c28d..94e6ec2 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -811,8 +811,7 @@ }, 'site_per_process_content_browsertests': { 'args': [ - '--site-per-process', - '--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter' + '--site-per-process' ], 'test': 'content_browsertests', }, @@ -1938,8 +1937,7 @@ }, 'site_per_process_content_browsertests': { 'args': [ - '--site-per-process', - '--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter' + '--site-per-process' ], 'test': 'content_browsertests', },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index d524263..a82ac762 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -12,6 +12,43 @@ { 'name': 'chromium', 'machines': { + 'linux-rel': { + 'additional_compile_targets': [ + 'all', + ], + 'test_suites': { + 'scripts': 'public_build_scripts', + }, + }, + 'mac-rel': { + 'additional_compile_targets': [ + 'all', + ], + 'test_suites': { + 'scripts': 'public_build_scripts', + }, + }, + 'win32-rel': { + 'additional_compile_targets': [ + 'all', + ], + 'test_suites': { + 'scripts': 'public_build_scripts', + }, + }, + 'win-rel': { + 'additional_compile_targets': [ + 'all', + ], + 'test_suites': { + 'scripts': 'public_build_scripts', + }, + }, + 'android-rel': { + 'additional_compile_targets': [ + 'all', + ], + }, 'Linux x64': { 'additional_compile_targets': [ 'all',
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index a346fb4..21341b4d 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1719,6 +1719,10 @@ # ====== Out of Blink CORS related tests END ====== +crbug.com/771118 virtual/service-worker-servicification/external/wpt/service-workers/service-worker/mime-sniffing.https.html [ Failure ] +crbug.com/771118 virtual/outofblink-cors/external/wpt/service-workers/service-worker/mime-sniffing.https.html [ Failure ] +crbug.com/771118 virtual/outofblink-cors-ns/external/wpt/service-workers/service-worker/mime-sniffing.https.html [ Failure ] + crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht [ Failure ] crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht [ Failure ] crbug.com/492664 [ Mac ] external/wpt/css/css-writing-modes/bidi-embed-002.html [ Failure ] @@ -4868,3 +4872,6 @@ crbug.com/824539 [ Android ] tables/mozilla_expected_failures/bugs/bug2479-5.html [ Failure ] crbug.com/824539 [ Android ] transforms/transformed-caret.html [ Failure ] crbug.com/824539 [ Android ] virtual/layout_ng/fast/block/margin-collapse/019.html [ Failure ] + +# Sheriff 2018-07-30 +crbug.com/866166 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-control-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-control-expected.txt index 47d8cccf..909f48ff 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-control-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-control-expected.txt
@@ -1,55 +1,53 @@ Verifies viewport correctly shows and hides messages while logging and scrolling. Logging 100 messages -activeCountAbove: 6, activeCountBelow: 8 -smallCount: 3, visibleCount: 11, maxActiveCount: 25, minActiveCount: 21 Running: addSmallCount -Logging 3 messages +Logging smallCount messages Are there smallCount items in DOM? true Are there smallCount items visible? true Running: addMoreThanVisibleCount -Logging 12 messages +Logging visibleCount + 1 messages Are there visibleCount + 1 items in DOM? true Are there visibleCount items visible? true Running: addMaxActiveCount -Logging 25 messages +Logging maxActiveCount messages Are there maxActiveCount items in DOM? true Are there visibleCount items visible? true Running: addMoreThanMaxActiveCount -Logging 28 messages +Logging maxActiveCount + smallCount messages Are there maxActiveCount items in DOM? true Are there visibleCount items visible? true Running: scrollToBottomInPartialActiveWindow -Logging 15 messages +Logging visiblePlusHalfExtraRows messages Were no items added? true Were no items removed? true Are there visiblePlusHalfExtraRows items in DOM? true Running: scrollToBottomInMoreThanActiveWindow -Logging 26 messages +Logging maxActiveCount + 1 messages Were some items added? true Were some items removed? true Running: shouldNotReconnectExistingElementsToDOM -Logging 3 messages -Logging 3 messages +Logging smallCount messages +Logging smallCount messages Were smallCount * 2 items added? true Were 0 items removed? true Running: logRepeatingMessages -Logging 11 messages +Logging visibleCount messages Were 1 items added? true Were 0 items removed? true Are there 1 items in DOM? true Are there 1 items visible? true Running: reorderingMessages -Logging 3 messages +Logging smallCount messages Swapping messages 0 and 1 Were no items added? true Were no items removed? true
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-control.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-control.js index a268064..a438ba2d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-control.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-control.js
@@ -28,7 +28,7 @@ const smallCount = 3; // Measure visible/active ranges. - await logMessages(100); + await logMessages(100, false, '100'); viewport.forceScrollItemToBeFirst(50); var {first, last, count} = ConsoleTestRunner.visibleIndices(); var visibleCount = count; @@ -38,8 +38,6 @@ var minActiveCount = 2 * (first - viewport._firstActiveIndex - 1) + visibleCount; var activeCountAbove = first - viewport._firstActiveIndex; var activeCountBelow = viewport._lastActiveIndex - last; - TestRunner.addResult(`activeCountAbove: ${activeCountAbove}, activeCountBelow: ${activeCountBelow}`); - TestRunner.addResult(`smallCount: ${smallCount}, visibleCount: ${visibleCount}, maxActiveCount: ${maxActiveCount}, minActiveCount: ${minActiveCount}`); var wasAddedToDOM = new Set(); var wasRemovedFromDOM = new Set(); @@ -57,8 +55,8 @@ wasRemovedFromDOM.clear(); } - function logMessages(count, repeating) { - TestRunner.addResult('Logging ' + count + ' messages'); + function logMessages(count, repeating, message) { + TestRunner.addResult('Logging ' + message + ' messages'); return new Promise(resolve => { var awaitingMessagesCount = count; function messageAdded() { @@ -125,7 +123,7 @@ TestRunner.runTestSuite([ async function addSmallCount(next) { reset(); - await logMessages(smallCount, false); + await logMessages(smallCount, false, 'smallCount'); viewport.forceScrollItemToBeFirst(0); assertDOMCount('smallCount', smallCount); assertVisibleCount('smallCount', smallCount); @@ -134,7 +132,7 @@ async function addMoreThanVisibleCount(next) { reset(); - await logMessages(visibleCount + 1, false); + await logMessages(visibleCount + 1, false, 'visibleCount + 1'); viewport.forceScrollItemToBeFirst(0); assertDOMCount('visibleCount + 1', visibleCount + 1); assertVisibleCount('visibleCount', visibleCount); @@ -143,7 +141,7 @@ async function addMaxActiveCount(next) { reset(); - await logMessages(maxActiveCount, false); + await logMessages(maxActiveCount, false, 'maxActiveCount'); viewport.forceScrollItemToBeFirst(0); assertDOMCount('maxActiveCount', maxActiveCount); assertVisibleCount('visibleCount', visibleCount); @@ -152,7 +150,7 @@ async function addMoreThanMaxActiveCount(next) { reset(); - await logMessages(maxActiveCount + smallCount, false); + await logMessages(maxActiveCount + smallCount, false, 'maxActiveCount + smallCount'); viewport.forceScrollItemToBeFirst(0); assertDOMCount('maxActiveCount', maxActiveCount); assertVisibleCount('visibleCount', visibleCount); @@ -163,7 +161,7 @@ reset(); // Few enough messages so that they all fit in DOM. var visiblePlusHalfExtraRows = visibleCount + Math.floor((minActiveCount - visibleCount) / 2) - 1; - await logMessages(visiblePlusHalfExtraRows, false); + await logMessages(visiblePlusHalfExtraRows, false, 'visiblePlusHalfExtraRows'); viewport.forceScrollItemToBeFirst(0); resetShowHideCounts(); // Set scrollTop above the bottom. @@ -177,7 +175,7 @@ async function scrollToBottomInMoreThanActiveWindow(next) { reset(); - await logMessages(maxActiveCount + 1, false); + await logMessages(maxActiveCount + 1, false, 'maxActiveCount + 1'); viewport.forceScrollItemToBeFirst(0); resetShowHideCounts(); // Set scrollTop above the bottom. @@ -190,15 +188,15 @@ async function shouldNotReconnectExistingElementsToDOM(next) { reset(); - await logMessages(smallCount, false); - await logMessages(smallCount, false); + await logMessages(smallCount, false, 'smallCount'); + await logMessages(smallCount, false, 'smallCount'); assertCountAddedRemoved('smallCount * 2', smallCount * 2, '0', 0); next(); }, async function logRepeatingMessages(next) { reset(); - await logMessages(visibleCount, true); + await logMessages(visibleCount, true, 'visibleCount'); assertCountAddedRemoved('1', 1, '0', 0); assertDOMCount('1', 1); assertVisibleCount('1', 1); @@ -207,7 +205,7 @@ async function reorderingMessages(next) { reset(); - await logMessages(smallCount, false); + await logMessages(smallCount, false, 'smallCount'); resetShowHideCounts(); TestRunner.addResult('Swapping messages 0 and 1'); var temp = consoleView._visibleViewMessages[0];
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-indices-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-indices-expected.txt index 13aa580..8386edae 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-indices-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-indices-expected.txt
@@ -2,36 +2,44 @@ Running: testEmptyViewport -Calculated visible range: -1 to -1, Total: 0 -Actual visible range: -1 to -1, Total: 0 -Active range: -1 to -1, Total: 0 - +Expected and actual visible ranges match Running: testFirstLastVisibleIndices -Logging 100 messages +Logging 100 Normal messages Force item to be first: 0 -Calculated visible range: 0 to 10, Total: 11 -Actual visible range: 0 to 10, Total: 11 -Active range: 0 to 24, Total: 25 - +Expected and actual visible ranges match Force item to be first: 1 -Calculated visible range: 1 to 11, Total: 11 -Actual visible range: 1 to 11, Total: 11 -Active range: 0 to 24, Total: 25 - +Expected and actual visible ranges match Scroll a bit down: 15px -Calculated visible range: 1 to 12, Total: 12 -Actual visible range: 1 to 12, Total: 12 -Active range: 0 to 24, Total: 25 - +Expected and actual visible ranges match Force item to be last: 50 -Calculated visible range: 40 to 50, Total: 11 -Actual visible range: 40 to 50, Total: 11 -Active range: 35 to 59, Total: 25 - +Expected and actual visible ranges match Force item to be last: 99 -Calculated visible range: 89 to 99, Total: 11 -Actual visible range: 89 to 99, Total: 11 -Active range: 84 to 99, Total: 16 +Expected and actual visible ranges match +Running: testMultilineMessages +Logging 100 Multiline messages +Force item to be first: 0 +Expected and actual visible ranges match +Force item to be first: 1 +Expected and actual visible ranges match +Scroll a bit down: 15px +Expected and actual visible ranges match +Force item to be last: 50 +Expected and actual visible ranges match +Force item to be last: 99 +Expected and actual visible ranges match + +Running: testSlightlyBiggerMessages +Logging 100 SlightlyBigger messages +Force item to be first: 0 +Expected and actual visible ranges match +Force item to be first: 1 +Expected and actual visible ranges match +Scroll a bit down: 15px +Expected and actual visible ranges match +Force item to be last: 50 +Expected and actual visible ranges match +Force item to be last: 99 +Expected and actual visible ranges match
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-indices.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-indices.js index 6fac148..2a4d8cc 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-indices.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-indices.js
@@ -7,12 +7,24 @@ await TestRunner.loadModule('console_test_runner'); await TestRunner.showPanel('console'); await TestRunner.evaluateInPagePromise(` - function addMessages(count) + function addNormalMessages(count) { for (var i = 0; i < count; ++i) console.log("Message #" + i); } + function addMultilineMessages(count) + { + for (var i = 0; i < count; ++i) + console.log("Message\\n#" + i); + } + + function addSlightlyBiggerMessages(count) + { + for (var i = 0; i < count; ++i) + console.log('%cMessage #' + i, 'padding-bottom: 1px'); + } + //# sourceURL=console-viewport-indices.js `); @@ -20,8 +32,8 @@ var consoleView = Console.ConsoleView.instance(); var viewport = consoleView._viewport; - function logMessages(count) { - TestRunner.addResult('Logging ' + count + ' messages'); + function logMessages(count, type) { + TestRunner.addResult(`Logging ${count} ${type} messages`); return new Promise(resolve => { var awaitingMessagesCount = count; function messageAdded() { @@ -33,7 +45,7 @@ } } ConsoleTestRunner.addConsoleSniffer(messageAdded, false); - TestRunner.evaluateInPage(String.sprintf('addMessages(%d)', count)); + TestRunner.evaluateInPage(String.sprintf(`add${type}Messages(%d)`, count)); }); } @@ -43,15 +55,25 @@ var calculatedFirst = viewport.firstVisibleIndex(); var calculatedLast = viewport.lastVisibleIndex(); var calculatedTotal = calculatedFirst === -1 ? 0 : (calculatedLast - calculatedFirst + 1); - TestRunner.addResult(`Calculated visible range: ${calculatedFirst} to ${calculatedLast}, Total: ${calculatedTotal} -Actual visible range: ${first} to ${last}, Total: ${count} -Active range: ${viewport._firstActiveIndex} to ${viewport._lastActiveIndex}, Total: ${activeTotal}\n`); if (calculatedFirst !== first || calculatedLast !== last) { TestRunner.addResult('TEST ENDED IN ERROR: viewport is calculated incorrect visible indices!'); + TestRunner.addResult(`Calculated visible range: ${calculatedFirst} to ${calculatedLast}, Total: ${calculatedTotal} +Actual visible range: ${first} to ${last}, Total: ${count}`); TestRunner.completeTest(); + } else { + TestRunner.addResult(`Expected and actual visible ranges match`); } } + function forceItemAndDump(index, first) { + TestRunner.addResult(`Force item to be ${first ? 'first' : 'last'}: ${index}`); + if (first) + viewport.forceScrollItemToBeFirst(index); + else + viewport.forceScrollItemToBeLast(index); + dumpVisibleIndices(); + } + TestRunner.runTestSuite([ async function testEmptyViewport(next) { Console.ConsoleView.clearConsole(); @@ -61,7 +83,7 @@ async function testFirstLastVisibleIndices(next) { Console.ConsoleView.clearConsole(); - await logMessages(100, false); + await logMessages(100, 'Normal'); forceItemAndDump(0, true); forceItemAndDump(1, true); @@ -75,15 +97,42 @@ forceItemAndDump(50, false); forceItemAndDump(99, false); next(); + }, - function forceItemAndDump(index, first) { - TestRunner.addResult(`Force item to be ${first ? 'first' : 'last'}: ${index}`); - if (first) - viewport.forceScrollItemToBeFirst(index); - else - viewport.forceScrollItemToBeLast(index); - dumpVisibleIndices(); - } + async function testMultilineMessages(next) { + Console.ConsoleView.clearConsole(); + await logMessages(100, 'Multiline'); + + forceItemAndDump(0, true); + forceItemAndDump(1, true); + + var lessThanOneRowHeight = consoleView.minimumRowHeight() - 1; + TestRunner.addResult(`Scroll a bit down: ${lessThanOneRowHeight}px`); + viewport.element.scrollTop += lessThanOneRowHeight; + viewport.refresh(); + dumpVisibleIndices(); + + forceItemAndDump(50, false); + forceItemAndDump(99, false); + next(); + }, + + async function testSlightlyBiggerMessages(next) { + Console.ConsoleView.clearConsole(); + await logMessages(100, 'SlightlyBigger'); + + forceItemAndDump(0, true); + forceItemAndDump(1, true); + + var lessThanOneRowHeight = consoleView.minimumRowHeight() - 1; + TestRunner.addResult(`Scroll a bit down: ${lessThanOneRowHeight}px`); + viewport.element.scrollTop += lessThanOneRowHeight; + viewport.refresh(); + dumpVisibleIndices(); + + forceItemAndDump(50, false); + forceItemAndDump(99, false); + next(); } ]); })();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-selection-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-selection-expected.txt index a7ad4e1..d4493c7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-selection-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-selection-expected.txt
@@ -5,13 +5,11 @@ Selected text:<<<EOL nsole EOL -first visible message index: 75 Running: testReversedSelectionSingleLineText Selected text:<<<EOL nsole EOL -first visible message index: 75 Running: testSelectionMultiLineText Selected text:<<<EOL @@ -19,51 +17,39 @@ console-viewport-selection.js:13 Message #75 console EOL -first visible message index: 74 Running: testSimpleVisibleSelection anchor = {item: 72, offset: 6}, head = {item: 77, offset: 6} -first visible message index: 72 Running: testHalfScrollSelectionUp anchor = {item: 72, offset: 6}, head = {item: 77, offset: 6} -first visible message index: 75 Running: testHalfScrollSelectionDown anchor = {item: 72, offset: 6}, head = {item: 77, offset: 6} -first visible message index: 65 Running: testScrollSelectionAwayUp anchor = {item: 72, offset: 6}, head = {item: 77, offset: 6} -first visible message index: 0 Running: testScrollSelectionAwayDown anchor = {item: 72, offset: 6}, head = {item: 77, offset: 6} -first visible message index: 140 Running: testShiftClickSelectionOver anchor = {item: 72, offset: 6}, head = {item: 10, offset: 0} -first visible message index: 5 Running: testShiftClickSelectionBelow anchor = {item: 72, offset: 6}, head = {item: 140, offset: 0} -first visible message index: 135 Running: testRemoveSelection anchor = null, head = null -first visible message index: 135 Running: testReversedVisibleSelection anchor = {item: 76, offset: 6}, head = {item: 71, offset: 6} -first visible message index: 71 Running: testShiftClickReversedSelectionOver anchor = {item: 76, offset: 6}, head = {item: 10, offset: 0} -first visible message index: 5 Running: testShiftClickReversedSelectionBelow anchor = {item: 76, offset: 6}, head = {item: 140, offset: 0} -first visible message index: 135 Running: testZeroOffsetSelection Selected text: world
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-selection.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-selection.js index 279eee3d..1d2a7be9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-selection.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-selection.js
@@ -31,49 +31,42 @@ viewportMessagesCount = viewport.lastVisibleIndex() - viewport.firstVisibleIndex() + 1; selectMessages(middleMessage, 2, middleMessage, 7); dumpSelectionText(); - dumpViewportRenderedItems(); next(); }, function testReversedSelectionSingleLineText(next) { selectMessages(middleMessage, 7, middleMessage, 2); dumpSelectionText(); - dumpViewportRenderedItems(); next(); }, function testSelectionMultiLineText(next) { selectMessages(middleMessage - 1, 4, middleMessage + 1, 7); dumpSelectionText(); - dumpViewportRenderedItems(); next(); }, function testSimpleVisibleSelection(next) { selectMessages(middleMessage - 3, 6, middleMessage + 2, 6); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, function testHalfScrollSelectionUp(next) { viewport.forceScrollItemToBeFirst(middleMessage); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, function testHalfScrollSelectionDown(next) { viewport.forceScrollItemToBeLast(middleMessage); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, function testScrollSelectionAwayUp(next) { viewport.forceScrollItemToBeFirst(0); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, @@ -81,21 +74,18 @@ consoleView._immediatelyScrollToBottom(); viewport.refresh(); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, function testShiftClickSelectionOver(next) { emulateShiftClickOnMessage(minimumViewportMessagesCount); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, function testShiftClickSelectionBelow(next) { emulateShiftClickOnMessage(messagesCount - minimumViewportMessagesCount); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, @@ -103,28 +93,24 @@ var selection = window.getSelection(); selection.removeAllRanges(); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, function testReversedVisibleSelection(next) { selectMessages(middleMessage + 1, 6, middleMessage - 4, 6); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, function testShiftClickReversedSelectionOver(next) { emulateShiftClickOnMessage(minimumViewportMessagesCount); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, function testShiftClickReversedSelectionBelow(next) { emulateShiftClickOnMessage(messagesCount - minimumViewportMessagesCount); dumpSelectionModel(); - dumpViewportRenderedItems(); next(); }, @@ -210,13 +196,6 @@ TestRunner.addResult('Selected text:<<<EOL\n' + text + '\nEOL'); } - function dumpViewportRenderedItems() { - viewport.refresh(); - var firstVisibleIndex = viewport.firstVisibleIndex(); - var lastVisibleIndex = viewport.lastVisibleIndex(); - TestRunner.addResult('first visible message index: ' + firstVisibleIndex); - } - function emulateShiftClickOnMessage(messageIndex) { viewport.refresh(); var selection = window.getSelection();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object-expected.txt index cbaedeb..9207921 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object-expected.txt
@@ -8,5 +8,6 @@ value : null } } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/emulation/emulation-oopifs-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/emulation/emulation-oopifs-expected.txt index 56c8f05..e2cd4da 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/emulation/emulation-oopifs-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/emulation/emulation-oopifs-expected.txt
@@ -6,6 +6,7 @@ id : <number> result : { } + sessionId : <string> } screen.width: 1402
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/iframe-no-src-execution-contexts-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/iframe-no-src-execution-contexts-expected.txt index 9fd70643..9efadbe 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/iframe-no-src-execution-contexts-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/iframe-no-src-execution-contexts-expected.txt
@@ -12,6 +12,7 @@ origin : http://devtools.test:8000 } } + sessionId : <string> } { method : Runtime.executionContextCreated @@ -26,5 +27,6 @@ origin : http://devtools.test:8000 } } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/mixed-content-execution-contexts-1-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/mixed-content-execution-contexts-1-expected.txt index 0f8dadd..009a0e19 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/mixed-content-execution-contexts-1-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/mixed-content-execution-contexts-1-expected.txt
@@ -12,6 +12,7 @@ origin : https://devtools.test:8443 } } + sessionId : <string> } { method : Runtime.executionContextCreated @@ -26,5 +27,6 @@ origin : https://devtools.test:8443 } } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/mixed-content-execution-contexts-2-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/mixed-content-execution-contexts-2-expected.txt index 0b7b72db..0cab96b 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/mixed-content-execution-contexts-2-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/mixed-content-execution-contexts-2-expected.txt
@@ -12,6 +12,7 @@ origin : https://devtools.test:8443 } } + sessionId : <string> } { method : Runtime.executionContextCreated @@ -26,5 +27,6 @@ origin : https://devtools.test:8443 } } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-blocking-xorigin-iframe.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-blocking-xorigin-iframe.js index 739ddd96..d1c264d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-blocking-xorigin-iframe.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-blocking-xorigin-iframe.js
@@ -4,7 +4,7 @@ await session.protocol.Network.clearBrowserCache(); await session.protocol.Network.setCacheDisabled({cacheDisabled: true}); - await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true}); + await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true, flatten: true}); let interceptionLog = []; function onRequestIntercepted(dp, e) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/navigate-204-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/navigate-204-expected.txt index 7529379..80c99ba 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/navigate-204-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/navigate-204-expected.txt
@@ -6,5 +6,6 @@ frameId : <string> loaderId : <string> } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/page-navigatedWithinDocument-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/page-navigatedWithinDocument-expected.txt index 41e6e6a6..84531bf 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/page-navigatedWithinDocument-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/page-navigatedWithinDocument-expected.txt
@@ -6,6 +6,7 @@ frameId : <string> url : http://127.0.0.1:8000/inspector-protocol/resources/inspector-protocol-page.html#foo } + sessionId : <string> } -- Test Page.navigate() to another anchor URL -- { @@ -14,6 +15,7 @@ frameId : <string> url : http://127.0.0.1:8000/inspector-protocol/resources/inspector-protocol-page.html#bar } + sessionId : <string> } -- Test history.pushState() -- { @@ -22,6 +24,7 @@ frameId : <string> url : http://127.0.0.1:8000/inspector-protocol/resources/wow.html } + sessionId : <string> } -- Test history.replaceState() -- { @@ -30,6 +33,7 @@ frameId : <string> url : http://127.0.0.1:8000/replaced.html } + sessionId : <string> } -- Test history.back() -- { @@ -38,6 +42,7 @@ frameId : <string> url : http://127.0.0.1:8000/inspector-protocol/resources/inspector-protocol-page.html#bar } + sessionId : <string> } -- Test history.forward() -- { @@ -46,5 +51,6 @@ frameId : <string> url : http://127.0.0.1:8000/replaced.html } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js index 7d9fb8a..d6d42b5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js
@@ -10,6 +10,7 @@ this._log = log; this._completeTest = completeTest; this._fetch = fetch; + this._browserSession = new TestRunner.Session(this, ''); } startDumpingProtocolMessages() { @@ -26,7 +27,7 @@ this._log.call(null, item); } - _logObject(object, title, stabilizeNames = ['id', 'nodeId', 'objectId', 'scriptId', 'timestamp', 'backendNodeId', 'parentId', 'frameId', 'loaderId', 'baseURL', 'documentURL', 'styleSheetId', 'executionContextId', 'targetId', 'browserContextId']) { + _logObject(object, title, stabilizeNames = ['id', 'nodeId', 'objectId', 'scriptId', 'timestamp', 'backendNodeId', 'parentId', 'frameId', 'loaderId', 'baseURL', 'documentURL', 'styleSheetId', 'executionContextId', 'targetId', 'browserContextId', 'sessionId']) { var lines = []; function dumpValue(value, prefix, prefixWithName) { @@ -78,7 +79,7 @@ } url(relative) { - if (relative.startsWith('http://') || relative.startsWith('https://')) + if (relative.startsWith('http://') || relative.startsWith('https://') || relative.startsWith('file://')) return relative; return this._targetBaseURL + relative; } @@ -130,29 +131,43 @@ return eval(`${source}\n//# sourceURL=${url}`); }; - async createPage() { - var targetId = (await DevToolsAPI._sendCommandOrDie('Target.createTarget', {url: 'about:blank'})).targetId; - await DevToolsAPI._sendCommandOrDie('Target.activateTarget', {targetId}); - var page = new TestRunner.Page(this, targetId); - var dummyURL = DevToolsHost.dummyPageURL; - if (!dummyURL) { - dummyURL = window.location.href; - dummyURL = dummyURL.substring(0, dummyURL.indexOf('inspector-protocol-test.html')) + 'inspector-protocol-page.html'; + browserP() { + return this._browserSession.protocol; + } + + async createPage(options) { + options = options || {}; + const browserProtocol = this._browserSession.protocol; + const params = {url: 'about:blank'}; + if (options.width) + params.width = options.width; + if (options.height) + params.height = options.height; + if (options.enableBeginFrameControl) + params.enableBeginFrameControl = true; + if (options.createContext) { + const browserContextId = (await browserProtocol.Target.createBrowserContext()).result.browserContextId; + options.browserContextId = browserContextId; } - await page._navigate(dummyURL); + const targetId = (await browserProtocol.Target.createTarget(params)).result.targetId; + const page = new TestRunner.Page(this, targetId); + let url = options.url || DevToolsHost.dummyPageURL; + if (!url) { + url = window.location.href; + url = url.substring(0, url.indexOf('inspector-protocol-test.html')) + 'inspector-protocol-page.html'; + } + await page.navigate(url); return page; } - async _start(description, html, url) { + async _start(description, options) { try { if (!description) throw new Error('Please provide a description for the test!'); this.log(description); - var page = await this.createPage(); - if (url) - await page.navigate(url); - if (html) - await page.loadHTML(html); + var page = await this.createPage(options); + if (options.html) + await page.loadHTML(options.html); var session = await page.createSession(); return { page: page, session: session, dp: session.protocol }; } catch (e) { @@ -160,16 +175,29 @@ } }; - startBlank(description) { - return this._start(description, null, null); + startBlank(description, options) { + return this._start(description, options || {}); } - startHTML(html, description) { - return this._start(description, html, null); + startHTML(html, description, options) { + options = options || {}; + options.html = html; + return this._start(description, options); } - startURL(url, description) { - return this._start(description, null, url); + startURL(url, description, options) { + options = options || {}; + options.url = url; + return this._start(description, options); + } + + startWithFrameControl(description, options) { + options = options || {}; + options.width = options.width || 800; + options.height = options.height || 600; + options.createContext = true; + options.enableBeginFrameControl = true; + return this._start(description, options); } async logStackTrace(debuggers, stackTrace, debuggerId) { @@ -210,10 +238,9 @@ } async createSession() { - var sessionId = (await DevToolsAPI._sendCommandOrDie('Target.attachToTarget', {targetId: this._targetId})).sessionId; - var session = new TestRunner.Session(this._testRunner, sessionId); - DevToolsAPI._sessions.set(sessionId, session); - return session; + let dp = this._testRunner._browserSession.protocol; + const sessionId = (await dp.Target.attachToTarget({targetId: this._targetId, flatten: true})).result.sessionId; + return new TestRunner.Session(this._testRunner, sessionId); } navigate(url) { @@ -239,63 +266,27 @@ this._testRunner = testRunner; this._sessionId = sessionId; this._requestId = 0; - this._dispatchTable = new Map(); this._eventHandlers = new Map(); this.protocol = this._setupProtocol(); - this._childSessions = null; - this._parentSession = null; + this._parentSessionId = null; + DevToolsAPI._sessions.set(sessionId, this); } async disconnect() { - await DevToolsAPI._sendCommandOrDie('Target.detachFromTarget', {sessionId: this._sessionId}); - if (this._parentSession) - this._parentSession._childSessions.delete(this._sessionId); - else - DevToolsAPI._sessions.delete(this._sessionId); + await DevToolsAPI._sendCommandOrDie(this._parentSessionId, 'Target.detachFromTarget', {sessionId: this._sessionId}); } createChild(sessionId) { - if (!this._childSessions) { - this._childSessions = new Map(); - this.protocol.Target.onReceivedMessageFromTarget(event => this._dispatchMessageFromTarget(event)); - } - let session = new TestRunner.Session(this._testRunner, sessionId); - this._childSessions.set(sessionId, session); - session._parentSession = this; + const session = new TestRunner.Session(this._testRunner, sessionId); + session._parentSessionId = this._sessionId; return session; } - async createTargetInNewContext(width, height, url, enableBeginFrameControl) { - const browserContextId = (await this.protocol.Target.createBrowserContext()) - .result.browserContextId; - const targetId = (await this.protocol.Target.createTarget( - {url, browserContextId, width, height, enableBeginFrameControl})) - .result.targetId; - const sessionId = (await this.protocol.Target.attachToTarget({targetId})) - .result.sessionId; - return this.createChild(sessionId); - } - - _dispatchMessageFromTarget(event) { - var session = this._childSessions.get(event.params.sessionId); - if (session) - session._dispatchMessage(JSON.parse(event.params.message)); - } - - sendRawCommand(requestId, message) { - if (this._parentSession) - this._parentSession.sendCommand('Target.sendMessageToTarget', {sessionId: this._sessionId, message: message}); - else - DevToolsAPI._sendCommandOrDie('Target.sendMessageToTarget', {sessionId: this._sessionId, message: message}); - return new Promise(f => this._dispatchTable.set(requestId, f)); - } - sendCommand(method, params) { var requestId = ++this._requestId; - var messageObject = {'id': requestId, 'method': method, 'params': params}; if (this._testRunner._dumpInspectorProtocolMessages) - this._testRunner.log(`frontend => backend: ${JSON.stringify(messageObject)}`); - return this.sendRawCommand(requestId, JSON.stringify(messageObject)); + this._testRunner.log(`frontend => backend: ${JSON.stringify({method, params, sessionId: this._sessionId})}`); + return DevToolsAPI._sendCommand(this._sessionId, method, params); } async evaluate(code, ...args) { @@ -340,17 +331,9 @@ _dispatchMessage(message) { if (this._testRunner._dumpInspectorProtocolMessages) this._testRunner.log(`backend => frontend: ${JSON.stringify(message)}`); - if (typeof message.id === 'number') { - var handler = this._dispatchTable.get(message.id); - if (handler) { - this._dispatchTable.delete(message.id); - handler(message); - } - } else { - var eventName = message.method; - for (var handler of (this._eventHandlers.get(eventName) || [])) - handler(message); - } + var eventName = message.method; + for (var handler of (this._eventHandlers.get(eventName) || [])) + handler(message); } _setupProtocol() { @@ -505,32 +488,31 @@ if (handler) { DevToolsAPI._dispatchTable.delete(messageId); handler(messageObject); + } else { + DevToolsAPI._die(`Unexpected result id ${messageId}`); } } else { - var eventName = messageObject.method; - if (eventName === 'Target.receivedMessageFromTarget') { - var sessionId = messageObject.params.sessionId; - var message = messageObject.params.message; - var session = DevToolsAPI._sessions.get(sessionId); - if (session) - session._dispatchMessage(JSON.parse(message)); - } + var session = DevToolsAPI._sessions.get(messageObject.sessionId); + if (session) + session._dispatchMessage(messageObject); } } catch(e) { DevToolsAPI._die(`Exception when dispatching message\n${JSON.stringify(messageObject)}`, e); } }; -DevToolsAPI._sendCommand = function(method, params) { +DevToolsAPI._sendCommand = function(sessionId, method, params) { var requestId = ++DevToolsAPI._requestId; var messageObject = {'id': requestId, 'method': method, 'params': params}; + if (sessionId) + messageObject.sessionId = sessionId; var embedderMessage = {'id': ++DevToolsAPI._embedderMessageId, 'method': 'dispatchProtocolMessage', 'params': [JSON.stringify(messageObject)]}; DevToolsHost.sendMessageToEmbedder(JSON.stringify(embedderMessage)); return new Promise(f => DevToolsAPI._dispatchTable.set(requestId, f)); }; -DevToolsAPI._sendCommandOrDie = function(method, params) { - return DevToolsAPI._sendCommand(method, params).then(message => { +DevToolsAPI._sendCommandOrDie = function(sessionId, method, params) { + return DevToolsAPI._sendCommand(sessionId, method, params).then(message => { if (message.error) DevToolsAPI._die('Error communicating with harness', new Error(JSON.stringify(message.error))); return message.result;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime/runtime-evaluate-silent-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime/runtime-evaluate-silent-expected.txt index 7ced510..653eca4 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime/runtime-evaluate-silent-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime/runtime-evaluate-silent-expected.txt
@@ -10,6 +10,7 @@ value : false } } + sessionId : <string> } UseCounter should be unsilenced when unmuted { @@ -20,5 +21,6 @@ value : true } } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/target-expose-devtools-protocol.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/target-expose-devtools-protocol.js index 816c707..1cd557cc 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/target-expose-devtools-protocol.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/target-expose-devtools-protocol.js
@@ -1,7 +1,7 @@ (async function(testRunner) { // 1. Create a page, connect to it and use browser connection to grant it a remote debugging capability. const {page, session, dp} = await testRunner.startBlank('Verify that exposing devtools protocol yields a functional protocol.'); - await DevToolsAPI._sendCommandOrDie('Target.exposeDevToolsProtocol', {targetId: page._targetId, bindingName: 'cdp'}); + await testRunner.browserP().Target.exposeDevToolsProtocol({targetId: page._targetId, bindingName: 'cdp'}); // 2. To avoid implementing a protocol client in test, use target domain to validate protocol binding. await dp.Target.setDiscoverTargets({discover: true});
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger.js index bfc0bfe..db72be1e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger.js
@@ -2,7 +2,7 @@ var {page, session, dp} = await testRunner.startBlank( `Tests that waitForDebuggerOnStart works with out-of-process iframes.`); - await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true}); + await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true, flatten: true}); await dp.Page.enable(); dp.Network.enable();
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-dom-mutation-violations-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-dom-mutation-violations-expected.txt index 119cf79b..8434c51 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-dom-mutation-violations-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-dom-mutation-violations-expected.txt
@@ -21,5 +21,6 @@ timestamp : <number> } } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-memory-setter-in-strict-mode-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-memory-setter-in-strict-mode-expected.txt index 3984939..cc7ae8a5 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-memory-setter-in-strict-mode-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-memory-setter-in-strict-mode-expected.txt
@@ -6,5 +6,6 @@ type : undefined } } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames-expected.txt index 2ab63df..3a9ad7c4 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames-expected.txt
@@ -144,5 +144,6 @@ ] parentId : <number> } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt index 4f27c26..54a39d9f 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt
@@ -292,5 +292,6 @@ xmlVersion : } } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setOuterHTML-detached-document-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setOuterHTML-detached-document-expected.txt index 65397911..b97ff83 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setOuterHTML-detached-document-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setOuterHTML-detached-document-expected.txt
@@ -3,5 +3,6 @@ id : <number> result : { } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setOuterHTML-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setOuterHTML-expected.txt index bc037ccb..2610ff3 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setOuterHTML-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setOuterHTML-expected.txt
@@ -4,5 +4,6 @@ result : { outerHTML : <body><div>Привет мир 1</div> <div>Привет мир 2</div> </body> } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchTouchEvent-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchTouchEvent-expected.txt index 2ad2a30d..976ac48 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchTouchEvent-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchTouchEvent-expected.txt
@@ -301,6 +301,7 @@ message : Must send a TouchStart first to start a new touch. } id : <number> + sessionId : <string> } @@ -318,6 +319,7 @@ message : TouchStart and TouchMove must have at least one touch point. } id : <number> + sessionId : <string> } @@ -360,6 +362,7 @@ message : TouchEnd and TouchCancel must not have any touch points. } id : <number> + sessionId : <string> } @@ -379,6 +382,7 @@ message : TouchEnd and TouchCancel must not have any touch points. } id : <number> + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/json-parse-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/json-parse-expected.txt deleted file mode 100644 index 5d527c01..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/json-parse-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -Tests that backend correctly handles unicode in messages -{ - id : <number> - result : { - result : { - type : string - value : Привет мир - } - } -} -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/json-parse.js b/third_party/WebKit/LayoutTests/inspector-protocol/json-parse.js deleted file mode 100644 index f6d26bbc..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/json-parse.js +++ /dev/null
@@ -1,13 +0,0 @@ -(async function(testRunner) { - var {page, session, dp} = await testRunner.startBlank('Tests that backend correctly handles unicode in messages'); - - var requestId = 100500; - var command = { - 'method': 'Runtime.evaluate', - 'params': {expression: '\'!!!\''}, - 'id': requestId - }; - var message = JSON.stringify(command).replace('!!!', '\\u041F\\u0440\\u0438\\u0432\\u0435\\u0442 \\u043C\\u0438\\u0440'); - testRunner.log(await session.sendRawCommand(requestId, message)); - testRunner.completeTest(); -})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/page/pageNavigateToFragment-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/page/pageNavigateToFragment-expected.txt index 90e7b564..51070b2 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/page/pageNavigateToFragment-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/page/pageNavigateToFragment-expected.txt
@@ -5,6 +5,7 @@ frameId : <string> loaderId : <string> } + sessionId : <string> } { id : <number> @@ -12,5 +13,6 @@ frameId : <string> loaderId : <string> } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/page/terminate-execution-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/page/terminate-execution-expected.txt index 155491ea..d9e1603 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/page/terminate-execution-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/page/terminate-execution-expected.txt
@@ -3,6 +3,7 @@ id : <number> result : { } + sessionId : <string> } { error : { @@ -10,5 +11,6 @@ message : Execution was terminated } id : <number> + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-handle-navigate-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-handle-navigate-expected.txt index 7b3e6eb..10bfb57 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-handle-navigate-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-handle-navigate-expected.txt
@@ -6,6 +6,7 @@ message : Cannot find context with specified id } id : <number> + sessionId : <string> } Got new context: true { @@ -14,6 +15,7 @@ message : Cannot find context with specified id } id : <number> + sessionId : <string> } Got new context: true { @@ -22,5 +24,6 @@ message : Cannot find context with specified id } id : <number> + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-return-by-value-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-return-by-value-expected.txt index 4a0b044..d896cdd 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-return-by-value-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-return-by-value-expected.txt
@@ -7,6 +7,7 @@ message : Object couldn't be returned by value } id : <number> + sessionId : <string> } Running test: testObjectWithChain @@ -16,5 +17,6 @@ message : Object reference chain is too long } id : <number> + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-with-context-id-equal-zero-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-with-context-id-equal-zero-expected.txt index f3f69e0..ee5e034 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-with-context-id-equal-zero-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-with-context-id-equal-zero-expected.txt
@@ -5,5 +5,6 @@ message : Cannot find context with specified id } id : <number> + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-without-enabling-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-without-enabling-expected.txt index c624a3f..e745a30 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-without-enabling-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-without-enabling-expected.txt
@@ -5,5 +5,6 @@ message : Cannot find context with specified id } id : <number> + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-install-binding-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-install-binding-expected.txt index 33ffbf5..7aa62e3 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-install-binding-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-install-binding-expected.txt
@@ -4,6 +4,7 @@ id : <number> result : { } + sessionId : <string> } Add script to replace console.debug with binding on load.. Add iframe with console.debug call.. @@ -14,6 +15,7 @@ name : send payload : payload } + sessionId : <string> } Navigate to page with console.debug.. { @@ -23,5 +25,6 @@ name : send payload : payload } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-shouldnt-crash-after-inspected-context-destroyed-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-shouldnt-crash-after-inspected-context-destroyed-expected.txt index 16f83b8..70b5a3c 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-shouldnt-crash-after-inspected-context-destroyed-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-shouldnt-crash-after-inspected-context-destroyed-expected.txt
@@ -6,5 +6,6 @@ type : undefined } } + sessionId : <string> }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/sessions/log-entry-added-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/sessions/log-entry-added-expected.txt index 8ad4ccd4..49336920 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/sessions/log-entry-added-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/sessions/log-entry-added-expected.txt
@@ -24,6 +24,7 @@ timestamp : <number> } } + sessionId : <string> } Enabling logging in session2 Triggering violation @@ -50,6 +51,7 @@ timestamp : <number> } } + sessionId : <string> } From session2: { @@ -74,6 +76,7 @@ timestamp : <number> } } + sessionId : <string> } Disabling logging in session1 Triggering violation @@ -100,6 +103,7 @@ timestamp : <number> } } + sessionId : <string> } Disabling logging in session2 Triggering violation
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/sessions/tracing-start-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/sessions/tracing-start-expected.txt index 29cd75a..422f2fb 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/sessions/tracing-start-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/sessions/tracing-start-expected.txt
@@ -4,6 +4,7 @@ id : <number> result : { } + sessionId : <string> } Starting tracing in session2 { @@ -12,12 +13,14 @@ message : Tracing is already started } id : <number> + sessionId : <string> } Stopping tracing in session1 { id : <number> result : { } + sessionId : <string> } Stopping tracing in session2 { @@ -26,6 +29,7 @@ message : Tracing is not started } id : <number> + sessionId : <string> } session1: dataCollected=true tracingComplete=true session2: dataCollected=false tracingComplete=false
diff --git a/third_party/blink/public/platform/web_layer_tree_view.h b/third_party/blink/public/platform/web_layer_tree_view.h index 46838bbf2..a4ed392a 100644 --- a/third_party/blink/public/platform/web_layer_tree_view.h +++ b/third_party/blink/public/platform/web_layer_tree_view.h
@@ -145,6 +145,9 @@ // dirty. virtual void SetNeedsBeginFrame() {} + // Relays the end of a fling animation. + virtual void DidStopFlinging() {} + // Run layout and paint of all pending document changes asynchronously. virtual void LayoutAndPaintAsync(base::OnceClosure callback) {}
diff --git a/third_party/blink/renderer/core/events/wheel_event.cc b/third_party/blink/renderer/core/events/wheel_event.cc index c26e75a..3b1ce775 100644 --- a/third_party/blink/renderer/core/events/wheel_event.cc +++ b/third_party/blink/renderer/core/events/wheel_event.cc
@@ -117,9 +117,9 @@ } void WheelEvent::preventDefault() { - UIEventWithKeyState::preventDefault(); + MouseEvent::preventDefault(); - if (HandlingPassive() == PassiveMode::kNotPassiveDefault && + if (HandlingPassive() == PassiveMode::kNotPassiveDefault && currentTarget() && currentTarget()->IsTopLevelNode()) { if (ExecutionContext* context = currentTarget()->GetExecutionContext()) { UseCounter::Count(
diff --git a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc index 699f85f..8162e306 100644 --- a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc +++ b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
@@ -520,7 +520,7 @@ ServeRequests(); // We should get a notification about access control check failure. - EXPECT_FALSE(will_follow_redirect_); + EXPECT_TRUE(will_follow_redirect_); EXPECT_FALSE(did_receive_response_); EXPECT_FALSE(did_receive_data_); EXPECT_TRUE(did_fail_); @@ -568,8 +568,7 @@ EXPECT_TRUE(expected_loader_); expected_loader_->LoadAsynchronously(request, this); ServeRequests(); - // We should not receive a notification for the redirect. - EXPECT_FALSE(will_follow_redirect_); + EXPECT_TRUE(will_follow_redirect_); EXPECT_TRUE(did_receive_response_); EXPECT_TRUE(did_receive_data_); EXPECT_TRUE(did_finish_loading_);
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc index 2962b4c..a8f81a3 100644 --- a/third_party/blink/renderer/core/fetch/fetch_manager.cc +++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -179,7 +179,7 @@ ~Loader() override; virtual void Trace(blink::Visitor*); - void DidReceiveRedirectTo(const KURL&) override; + bool WillFollowRedirect(const KURL&, const ResourceResponse&) override; void DidReceiveResponse(unsigned long, const ResourceResponse&, std::unique_ptr<WebDataConsumerHandle>) override; @@ -376,8 +376,10 @@ visitor->Trace(execution_context_); } -void FetchManager::Loader::DidReceiveRedirectTo(const KURL& url) { +bool FetchManager::Loader::WillFollowRedirect(const KURL& url, + const ResourceResponse&) { url_list_.push_back(url); + return true; } void FetchManager::Loader::DidReceiveResponse(
diff --git a/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc b/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc index 21df2ee..d63469d 100644 --- a/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc +++ b/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc
@@ -377,7 +377,7 @@ for (const auto& html_attribute : attributes) { const String& attribute_name = html_attribute.first; - const String& attribute_value = AtomicString(html_attribute.second); + const AtomicString& attribute_value = AtomicString(html_attribute.second); if (ThreadSafeMatch(attribute_name, http_equivAttr)) { if (DeprecatedEqualIgnoringCase(attribute_value, "content-type"))
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl index 331e67d8..237448d 100644 --- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl +++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -5932,6 +5932,8 @@ # Whether to pause new targets when attaching to them. Use `Runtime.runIfWaitingForDebugger` # to run paused targets. boolean waitForDebuggerOnStart + # Enables "flat" access to the session via specifying sessionId attribute in the commands. + experimental optional boolean flatten # Controls whether to discover available targets and notify via # `targetCreated/targetInfoChanged/targetDestroyed` events.
diff --git a/third_party/blink/renderer/core/inspector/inspector_worker_agent.cc b/third_party/blink/renderer/core/inspector/inspector_worker_agent.cc index 56fde78..9cb95fcb 100644 --- a/third_party/blink/renderer/core/inspector/inspector_worker_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_worker_agent.cc
@@ -79,7 +79,8 @@ } Response InspectorWorkerAgent::setAutoAttach(bool auto_attach, - bool wait_for_debugger_on_start) { + bool wait_for_debugger_on_start, + Maybe<bool> flatten) { wait_for_debugger_on_start_.Set(wait_for_debugger_on_start); if (auto_attach == auto_attach_.Get())
diff --git a/third_party/blink/renderer/core/inspector/inspector_worker_agent.h b/third_party/blink/renderer/core/inspector/inspector_worker_agent.h index b482a7a..6f2a733 100644 --- a/third_party/blink/renderer/core/inspector/inspector_worker_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_worker_agent.h
@@ -63,7 +63,8 @@ // Called from Dispatcher protocol::Response setAutoAttach(bool auto_attach, - bool wait_for_debugger_on_start) override; + bool wait_for_debugger_on_start, + protocol::Maybe<bool> flatten) override; protocol::Response sendMessageToTarget( const String& message, protocol::Maybe<String> session_id,
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc index 8b355a9f..05f71c3 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
@@ -16,16 +16,9 @@ namespace { bool IsOccluded(const Element& element, const IntersectionGeometry& geometry) { - HitTestResult hits( + HitTestResult result( element.GetLayoutObject()->HitTestForOcclusion(geometry.TargetRect())); - const HitTestResult::NodeSet& hit_nodes = hits.ListBasedTestResult(); - for (const auto& node : hit_nodes) { - if (!node->contains(&element) && - node->GetLayoutObject()->HasNonZeroEffectiveOpacity()) { - return true; - } - } - return false; + return result.InnerNode() && result.InnerNode() != &element; } } // namespace
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc index c867a3d..02b513f 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc
@@ -354,6 +354,16 @@ EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); EXPECT_FALSE(observer_delegate->LastEntry()->isVisible()); + + // Zero-opacity objects should not count as occluding. + occluder->SetInlineStyleProperty(CSSPropertyOpacity, "0"); + Compositor().BeginFrame(); + test::RunPendingTasks(); + ASSERT_FALSE(Compositor().NeedsBeginFrame()); + EXPECT_EQ(observer_delegate->CallCount(), 3); + EXPECT_EQ(observer_delegate->EntryCount(), 3); + EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); + EXPECT_TRUE(observer_delegate->LastEntry()->isVisible()); } TEST_F(IntersectionObserverV2Test, BasicOpacity) {
diff --git a/third_party/blink/renderer/core/layout/hit_test_request.h b/third_party/blink/renderer/core/layout/hit_test_request.h index e7626ce..0c3e6e9 100644 --- a/third_party/blink/renderer/core/layout/hit_test_request.h +++ b/third_party/blink/renderer/core/layout/hit_test_request.h
@@ -52,6 +52,7 @@ // testing after a hit has been found. kPenetratingList = 1 << 12, kAvoidCache = 1 << 13, + kIgnoreZeroOpacityObjects = 1 << 14, }; typedef unsigned HitTestRequestType;
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 9fa10d6..7ce1cd5 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1701,9 +1701,9 @@ LocalFrame* frame = GetDocument().GetFrame(); DCHECK(!frame->View()->NeedsLayout()); HitTestRequest::HitTestRequestType hit_type = - HitTestRequest::kListBased | HitTestRequest::kPenetratingList | HitTestRequest::kIgnorePointerEventsNone | HitTestRequest::kReadOnly | - HitTestRequest::kIgnoreClipping; + HitTestRequest::kIgnoreClipping | + HitTestRequest::kIgnoreZeroOpacityObjects; HitTestLocation location(hit_rect); return frame->GetEventHandler().HitTestResultAtLocation(location, hit_type, this, true);
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index 52975440..df7732d 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -137,8 +137,6 @@ TRACE_EVENT_BEGIN0("blink,devtools.timeline", "HitTest"); hit_test_count_++; - DCHECK(!location.IsRectBasedTest() || result.GetHitTestRequest().ListBased()); - uint64_t dom_tree_version = GetDocument().DomTreeVersion(); HitTestResult cache_result = result; bool hit_layer = false;
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc index 20f364f..a3c9c51 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader.cc +++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -671,16 +671,10 @@ return false; } - if (out_of_blink_cors_) { - client_->DidReceiveRedirectTo(new_url); - client_->WillFollowRedirect(new_url, redirect_response); - return true; - } - // Allow same origin requests to continue after allowing clients to audit // the redirect. - if (IsAllowedRedirect(new_request.GetFetchRequestMode(), new_url)) { - client_->DidReceiveRedirectTo(new_url); + if (out_of_blink_cors_ || + IsAllowedRedirect(new_request.GetFetchRequestMode(), new_url)) { return client_->WillFollowRedirect(new_url, redirect_response); } @@ -721,7 +715,7 @@ } } - client_->DidReceiveRedirectTo(new_url); + client_->WillFollowRedirect(new_url, redirect_response); // FIXME: consider combining this with CORS redirect handling performed by // CrossOriginAccessControl::handleRedirect().
diff --git a/third_party/blink/renderer/core/loader/threadable_loader_client.h b/third_party/blink/renderer/core/loader/threadable_loader_client.h index a5404ed7..760c66c 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader_client.h +++ b/third_party/blink/renderer/core/loader/threadable_loader_client.h
@@ -50,8 +50,6 @@ public: virtual void DidSendData(unsigned long long /*bytesSent*/, unsigned long long /*totalBytesToBeSent*/) {} - // TODO(japhet?): Merge these redirect callbacks. - virtual void DidReceiveRedirectTo(const KURL&) {} virtual bool WillFollowRedirect(const KURL& new_url, const ResourceResponse&) { return true;
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index 4d93fdf..2603238 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -2001,6 +2001,12 @@ if (!IsSelfPaintingLayer() && !HasSelfPaintingLayerDescendant()) return nullptr; + if ((result.GetHitTestRequest().GetType() & + HitTestRequest::kIgnoreZeroOpacityObjects) && + !layout_object.HasNonZeroEffectiveOpacity()) { + return nullptr; + } + ShouldRespectOverflowClipType clip_behavior = kRespectOverflowClip; if (result.GetHitTestRequest().IgnoreClipping()) clip_behavior = kIgnoreOverflowClip; @@ -2127,8 +2133,8 @@ candidate_layer = hit_layer; } - // Collect the fragments. This will compute the clip rectangles for each layer - // fragment. + // Collect the fragments. This will compute the clip rectangles for each + // layer fragment. base::Optional<PaintLayerFragments> layer_fragments; LayoutPoint offset; if (recursion_data.intersects_location) { @@ -2208,7 +2214,7 @@ inside_fragment_background_rect) && IsHitCandidate(this, false, z_offset_for_contents_ptr, unflattened_transform_state.get())) { - if (recursion_data.original_location.IsRectBasedTest()) + if (result.GetHitTestRequest().ListBased()) result.Append(temp_result); else result = temp_result; @@ -2331,7 +2337,7 @@ if (!GetLayoutObject().HitTestAllPhases(result, hit_test_location, fragment_offset, hit_test_filter)) { // It's wrong to set innerNode, but then claim that you didn't hit anything, - // unless it is a rect-based test. + // unless it is a list-based test. DCHECK(!result.InnerNode() || (result.GetHitTestRequest().ListBased() && result.ListBasedTestResult().size())); return false; @@ -2432,8 +2438,6 @@ // If it is a list-based test, we can safely append the temporary result // since it might had hit nodes but not necesserily had hitLayer set. - DCHECK(!recursion_data.original_location.IsRectBasedTest() || - result.GetHitTestRequest().ListBased()); if (result.GetHitTestRequest().ListBased()) result.Append(temp_result);
diff --git a/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js b/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js index d380af9..71393cc 100644 --- a/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js +++ b/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
@@ -583,7 +583,7 @@ if (!this._currentGroup.messagesHidden()) { const originatingMessage = viewMessage.consoleMessage().originatingMessage(); if (lastMessage && originatingMessage && lastMessage.consoleMessage() === originatingMessage) - lastMessage.toMessageElement().classList.add('console-adjacent-user-command-result'); + viewMessage.toMessageElement().classList.add('console-adjacent-user-command-result'); this._visibleViewMessages.push(viewMessage); this._searchMessage(this._visibleViewMessages.length - 1);
diff --git a/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js b/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js index ebf57f65..de0d78f 100644 --- a/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js +++ b/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js
@@ -93,7 +93,7 @@ */ willHide() { this._isVisible = false; - this._cachedHeight = this.contentElement().offsetHeight; + this._cachedHeight = this.element().offsetHeight; } /**
diff --git a/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js b/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js index 023ecc6..571ac47 100644 --- a/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js +++ b/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js
@@ -166,13 +166,22 @@ } _rebuildCumulativeHeightsIfNeeded() { + let totalCachedHeight = 0; + let totalMeasuredHeight = 0; // Check whether current items in DOM have changed heights. Tolerate 1-pixel // error due to double-to-integer rounding errors. for (let i = 0; i < this._renderedItems.length; ++i) { const cachedItemHeight = this._cachedItemHeight(this._firstActiveIndex + i); - if (Math.abs(cachedItemHeight - this._renderedItems[i].element().offsetHeight) > 1) { + const measuredHeight = this._renderedItems[i].element().offsetHeight; + if (Math.abs(cachedItemHeight - measuredHeight) > 1) { this._rebuildCumulativeHeights(); - break; + return; + } + totalMeasuredHeight += measuredHeight; + totalCachedHeight += cachedItemHeight; + if (Math.abs(totalCachedHeight - totalMeasuredHeight) > 1) { + this._rebuildCumulativeHeights(); + return; } } } @@ -534,6 +543,9 @@ const lastVisibleIndex = this.lastVisibleIndex(); if (index > firstVisibleIndex && index < lastVisibleIndex) return; + // If the prompt is visible, then the last item must be fully on screen. + if (index === lastVisibleIndex && this._cumulativeHeights[index] <= this.element.scrollTop + this._visibleHeight()) + return; if (makeLast) this.forceScrollItemToBeLast(index); else if (index <= firstVisibleIndex) @@ -553,6 +565,8 @@ if (this.element.isScrolledToBottom()) this.setStickToBottom(true); this.refresh(); + // After refresh, the item is in DOM, but may not be visible (items above were larger than expected). + this.renderedElementAt(index).scrollIntoView(true /* alignTop */); } /** @@ -566,6 +580,8 @@ if (this.element.isScrolledToBottom()) this.setStickToBottom(true); this.refresh(); + // After refresh, the item is in DOM, but may not be visible (items above were larger than expected). + this.renderedElementAt(index).scrollIntoView(false /* alignTop */); } /**
diff --git a/third_party/blink/renderer/devtools/front_end/console/consoleView.css b/third_party/blink/renderer/devtools/front_end/console/consoleView.css index 2e7e2792..a6b71fb 100644 --- a/third_party/blink/renderer/devtools/front_end/console/consoleView.css +++ b/third_party/blink/renderer/devtools/front_end/console/consoleView.css
@@ -30,6 +30,9 @@ .console-view { background-color: white; overflow: hidden; + --message-border-color: rgb(240, 240, 240); + --warning-border-color: hsl(50, 100%, 88%); + --error-border-color: hsl(0, 100%, 92%); } .console-toolbar-container { @@ -67,7 +70,6 @@ #console-messages { flex: 1 1; - padding: 2px 0; overflow-y: auto; word-wrap: break-word; -webkit-user-select: text; @@ -87,7 +89,7 @@ position: relative; padding: 3px 22px 1px 0; margin-left: 24px; - min-height: 18px; /* Sync with ConsoleViewMessage.js */ + min-height: 17px; /* Sync with ConsoleViewMessage.js */ flex: auto; display: flex; } @@ -180,23 +182,38 @@ .console-message-wrapper { display: flex; - border-bottom: 1px solid rgb(240, 240, 240); + border-top: 1px solid var(--message-border-color); + border-bottom: 1px solid transparent; } -.console-message-wrapper.console-adjacent-user-command-result { - border-bottom: none; +.console-message-wrapper:first-of-type { + border-top-color: transparent; } -.console-message-wrapper.console-error-level { - border-top: 1px solid hsl(0, 100%, 92%); - border-bottom: 1px solid hsl(0, 100%, 92%); - margin-top: -1px; +.console-message-wrapper.console-adjacent-user-command-result:not(.console-error-level):not(.console-warning-level) { + border-top: none; } -.console-message-wrapper.console-warning-level { - border-top: 1px solid hsl(50, 100%, 88%); - border-bottom: 1px solid hsl(50, 100%, 88%); - margin-top: -1px; +.console-message-wrapper.console-error-level, +.console-message-wrapper.console-error-level + .console-message-wrapper:not(.console-warning-level) { + border-top-color: var(--error-border-color); +} + +.console-message-wrapper.console-warning-level, +.console-message-wrapper.console-warning-level + .console-message-wrapper:not(.console-error-level) { + border-top-color: var(--warning-border-color); +} + +.console-message-wrapper:last-of-type { + border-bottom-color: var(--message-border-color); +} + +.console-message-wrapper.console-error-level:last-of-type { + border-bottom-color: var(--error-border-color); +} + +.console-message-wrapper.console-warning-level:last-of-type { + border-bottom-color: var(--warning-border-color); } .console-message-wrapper .nesting-level-marker { @@ -332,6 +349,10 @@ clear: both; } +.console-message .source-code { + line-height: 1.2; +} + .console-message-anchor { float: right; text-align: right;
diff --git a/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js b/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js index e72a511f..dc28c73c 100644 --- a/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js +++ b/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js
@@ -611,14 +611,12 @@ }; /** - * Returns actual visible indices. Messages in the margin are treated as NOT visible. * @return {!{first: number, last: number, count: number}} */ ConsoleTestRunner.visibleIndices = function() { const consoleView = Console.ConsoleView.instance(); const viewport = consoleView._viewport; const viewportRect = viewport.element.getBoundingClientRect(); - const viewportPadding = parseFloat(window.getComputedStyle(viewport.element).paddingTop); let first = -1; let last = -1; let count = 0; @@ -628,8 +626,7 @@ if (!item._element || !item._element.isConnected) continue; const itemRect = item._element.getBoundingClientRect(); - const isVisible = (itemRect.bottom > viewportRect.top + viewportPadding + 1) && - (itemRect.top <= viewportRect.bottom - viewportPadding - 1); + const isVisible = (itemRect.bottom > viewportRect.top + 1) && (itemRect.top <= viewportRect.bottom - 1); if (isVisible) { first = first === -1 ? i : first; last = i;
diff --git a/third_party/blink/renderer/modules/xr/xr_device.idl b/third_party/blink/renderer/modules/xr/xr_device.idl index 30e102b..f8da225 100644 --- a/third_party/blink/renderer/modules/xr/xr_device.idl +++ b/third_party/blink/renderer/modules/xr/xr_device.idl
@@ -7,6 +7,6 @@ SecureContext, OriginTrialEnabled=WebXR ] interface XRDevice { - [CallWith=ScriptState, MeasureAs=XRSupportsSession] Promise supportsSession([PermissiveDictionaryConversion] optional XRSessionCreationOptions options); - [CallWith=ScriptState, MeasureAs=XRRequestSession] Promise requestSession([PermissiveDictionaryConversion] optional XRSessionCreationOptions options); + [CallWith=ScriptState, MeasureAs=XRSupportsSession] Promise<void> supportsSession([PermissiveDictionaryConversion] optional XRSessionCreationOptions options); + [CallWith=ScriptState, MeasureAs=XRRequestSession] Promise<XRSession> requestSession([PermissiveDictionaryConversion] optional XRSessionCreationOptions options); };
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index 7d8fccd..6549d0f 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -84,7 +84,9 @@ if (!host) return; for (auto child : root_layer_->children()) { - host->UnregisterElement(child->element_id(), cc::ElementListType::ACTIVE); + auto element_id = child->element_id(); + if (element_id) + host->UnregisterElement(element_id, cc::ElementListType::ACTIVE); } root_layer_->RemoveAllChildren(); if (extra_data_for_testing_enabled_) {
diff --git a/third_party/closure_compiler/README.chromium b/third_party/closure_compiler/README.chromium index 8b2d6c5..d0274ffc 100644 --- a/third_party/closure_compiler/README.chromium +++ b/third_party/closure_compiler/README.chromium
@@ -1,8 +1,8 @@ Name: Closure compiler Short Name: closure-compiler URL: http://github.com/google/closure-compiler -Version: v20150729-236-gad656a1 -Date: 2015/08/26 08:46 +Version: v20180725-137c24759 +Date: 2018/07/27 19:34 Revision: 137c2475944651f45433965afa9f1cddf7d1966b License: Apache 2.0 License File: LICENSE
diff --git a/third_party/closure_compiler/externs/settings_private.js b/third_party/closure_compiler/externs/settings_private.js index a95a2ff1..fb13fc7 100644 --- a/third_party/closure_compiler/externs/settings_private.js +++ b/third_party/closure_compiler/externs/settings_private.js
@@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -63,11 +63,11 @@ chrome.settingsPrivate.PrefObject; /** - * Sets a settings value. + * Sets a pref value. * @param {string} name The name of the pref. * @param {*} value The new value of the pref. - * @param {string} pageId The user metrics identifier or null. - * @param {function(boolean):void} callback The callback for whether the pref + * @param {string=} pageId An optional user metrics identifier. + * @param {function(boolean):void=} callback The callback for whether the pref * was set or not. */ chrome.settingsPrivate.setPref = function(name, value, pageId, callback) {};
diff --git a/third_party/closure_compiler/roll_closure_compiler b/third_party/closure_compiler/roll_closure_compiler index d34e162..1341a36 100755 --- a/third_party/closure_compiler/roll_closure_compiler +++ b/third_party/closure_compiler/roll_closure_compiler
@@ -38,7 +38,9 @@ cd closure-compiler -new_head=$(git rev-parse HEAD) +new_head="$(git rev-parse HEAD)" +new_version="$(git log HEAD -n1 --date=format:%Y%m%d --pretty=format:v%cd-%h)" +new_date="$(date --utc '+%Y/%m/%d %H:%M')" if [[ "${new_head}" == "${old_head}" ]]; then echo "No closure-compiler changes since last roll. Nothing to do." @@ -147,7 +149,7 @@ echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" echo -sed -i "s/^Revision: ${old_head}$/Revision: ${new_head}/" "${README}" +sed -i "s/^Revision: ${old_head}$/Revision: ${new_head}/; s,^Date: .*,Date: ${new_date},; s,^Version: .*,Version: ${new_version}," "${README}" echo "git commit -a -m 'Roll closure compiler" echo
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py index 5abba31..ead68d3 100755 --- a/tools/clang/scripts/package.py +++ b/tools/clang/scripts/package.py
@@ -275,6 +275,7 @@ elif sys.platform == 'win32': want.extend(['lib/clang/*/lib/windows/clang_rt.asan*.dll', 'lib/clang/*/lib/windows/clang_rt.asan*.lib', + 'lib/clang/*/lib/windows/clang_rt.profile*.lib', 'lib/clang/*/lib/windows/clang_rt.ubsan*.lib', ])
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 67806b3..32e2c2b 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -29,6 +29,11 @@ 'Mac': 'release_bot_mac_strip', 'Win': 'release_bot_x86_minimal_symbols_enable_archive_compression', 'Win x64': 'release_bot_minimal_symbols_enable_archive_compression', + 'android-rel': 'android_without_codecs_release_bot_minimal_symbols', + 'linux-rel': 'release_bot', + 'mac-rel': 'release_bot_mac_strip', + 'win32-rel': 'release_bot_x86_minimal_symbols_enable_archive_compression', + 'win-rel': 'release_bot_minimal_symbols_enable_archive_compression', }, 'chromium.android': { @@ -555,7 +560,7 @@ }, 'tryserver.chromium.chromiumos': { - 'chromeos-amd64-generic-rel': 'cros_chrome_sdk_dcheck_always_on', + 'chromeos-amd64-generic-rel': 'cros_chrome_sdk', 'chromeos-daisy-rel': 'cros_chrome_sdk', 'linux-chromeos-rel': 'chromeos_with_codecs_release_trybot', 'linux-chromeos-compile-dbg': 'chromeos_with_codecs_debug_bot', @@ -1169,10 +1174,6 @@ 'cros_chrome_sdk', ], - 'cros_chrome_sdk_dcheck_always_on': [ - 'cros_chrome_sdk', 'dcheck_always_on', - ], - 'cros_chrome_sdk_headless_ozone': [ 'cros_chrome_sdk', 'ozone_platform_headless', ],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index a90de18..f0c392bc 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -25507,6 +25507,21 @@ <int value="2" label="SubframeBlocked"/> </enum> +<enum name="IOSGetCookiesForURLCallCookieStoreType"> + <int value="0" label="WKHTTPSystemCookieStore"/> + <int value="1" label="NSHTTPSystemCookieStore"/> + <int value="2" label="CookieMonster"/> +</enum> + +<enum name="IOSGetCookiesForURLCallResult"> + <int value="0" label="Cookies found on WKHTTPSystemCookieStore"/> + <int value="1" label="No Cookies on WKHTTPSystemCookieStore"/> + <int value="2" label="Cookies found on NSHTTPSystemCookieStore"/> + <int value="3" label="No Cookies on NSHTTPSystemCookieStore"/> + <int value="4" label="Cookies found on CookieMonster"/> + <int value="5" label="No Cookies on CookieMonster"/> +</enum> + <enum name="IOSHandoffOrigin"> <int value="0" label="Unknown Origin"/> <int value="1" label="Chrome on iOS"/> @@ -40394,6 +40409,9 @@ </enum> <enum name="QuotaOriginTypes"> + <obsolete> + Removed from code July 2018. + </obsolete> <int value="0" label="Other"/> <int value="1" label="None"/> <int value="2" label="google.com durable"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 43401ed..93b9768 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -595,6 +595,15 @@ </summary> </histogram> +<histogram name="AnchorElementMetrics.Clicked.AreaRank" units="rank"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The rank of the clicked anchor element in terms of area. This histogram is + recorded when the anchor element is clicked. + </summary> +</histogram> + <histogram name="AnchorElementMetrics.Clicked.ClickIntervals" units="ms"> <owner>chelu@chromium.org</owner> <owner>tbansal@chromium.org</owner> @@ -655,6 +664,118 @@ </summary> </histogram> +<histogram name="AnchorElementMetrics.Clicked.NavigationScore" units="score"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The calculated navigation score of the target link (href) of an anchor + element. The score is retrieved from the site engagement service. This + histogram is recorded when the anchor element is clicked and the score has + already been calculated when the document is loaded. + </summary> +</histogram> + +<histogram name="AnchorElementMetrics.Clicked.NavigationScoreRank" units="rank"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The rank of the navigation score of the target link (href) of an anchor + element. This histogram is recorded when the anchor element is clicked and + the score has already been calculated when the document is loaded. + </summary> +</histogram> + +<histogram name="AnchorElementMetrics.Clicked.RatioContainsImage_ContainsImage" + units="%"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The ratio times 100 between the number of anchor elements that contains + images and the total number of anchor elements. This histogram is recorded + when the anchor element is clicked and it contains images. + </summary> +</histogram> + +<histogram name="AnchorElementMetrics.Clicked.RatioContainsImage_NoImage" + units="%"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The ratio times 100 between the number of anchor elements that contains + images and the total number of anchor elements. This histogram is recorded + when the anchor element is clicked and it does not contain images. + </summary> +</histogram> + +<histogram name="AnchorElementMetrics.Clicked.RatioInIframe_InIframe" units="%"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The ratio times 100 between the number of anchor elements that is inside an + iframe and the total number of anchor elements. This histogram is recorded + when the anchor element is clicked and it is inside an iframe. + </summary> +</histogram> + +<histogram name="AnchorElementMetrics.Clicked.RatioInIframe_NotInIframe" + units="%"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The ratio times 100 between the number of anchor elements that is inside an + iframe and the total number of anchor elements. This histogram is recorded + when the anchor element is clicked and it is not inside an iframe. + </summary> +</histogram> + +<histogram name="AnchorElementMetrics.Clicked.RatioSameHost_DiffHost" units="%"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The ratio times 100 between the number of anchor elements whose href have + the same host as the document and the total number of anchor elements. This + histogram is recorded when the anchor element is clicked and href of the + anchor element has a different host than the document. + </summary> +</histogram> + +<histogram name="AnchorElementMetrics.Clicked.RatioSameHost_SameHost" units="%"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The ratio times 100 between the number of anchor elements whose href have + the same host as the document and the total number of anchor elements. This + histogram is recorded when the anchor element is clicked and href of the + anchor element has the same host as the document. + </summary> +</histogram> + +<histogram + name="AnchorElementMetrics.Clicked.RatioUrlIncremented_NotIncremented" + units="%"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The ratio times 100 between the number of anchor elements whose href is + incremented by one from the url of the document and the total number of + anchor elements. This histogram is recorded when the anchor element is + clicked and its href is not incremented by one from the url of the document. + </summary> +</histogram> + +<histogram + name="AnchorElementMetrics.Clicked.RatioUrlIncremented_UrlIncremented" + units="%"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The ratio times 100 between the number of anchor elements whose href is + incremented by one from the url of the document and the total number of + anchor elements. This histogram is recorded when the anchor element is + clicked and its href is incremented by one from the url of the document. + </summary> +</histogram> + <histogram name="AnchorElementMetrics.ContainsImage" enum="Boolean"> <owner>chelu@chromium.org</owner> <owner>tbansal@chromium.org</owner> @@ -663,6 +784,15 @@ </summary> </histogram> +<histogram name="AnchorElementMetrics.DocumentEngagementScore" units="score"> + <owner>chelu@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + The site engagement score of the document URL. The score is retrieved from + the site engagement service. + </summary> +</histogram> + <histogram name="AnchorElementMetrics.IsInIFrame" enum="Boolean"> <owner>chelu@chromium.org</owner> <owner>tbansal@chromium.org</owner> @@ -770,6 +900,16 @@ </summary> </histogram> +<histogram name="AnchorElementMetrics.Visible.NumberOfAnchorElementsAfterMerge" + units="count"> + <owner>chelu@chromium.org</owner> + <summary> + The number of anchor element metrics sent to the browser process on a page + load. Anchor elements having the same href are merged and counted as 1. This + histogram is recorded when the webpage is loaded. + </summary> +</histogram> + <histogram name="Android.Activity.ChromeTabbedActivity.StopReason" enum="AndroidActivityStopReason"> <owner>dfalcantara@chromium.org</owner> @@ -37005,6 +37145,31 @@ </summary> </histogram> +<histogram name="IOS.Cookies.GetCookiesForURLCallResult" + enum="IOSGetCookiesForURLCallResult"> + <owner>mrefaat@chromium.org</owner> + <summary> + Recorded to indicate whether the GetCookiesForURL call found cookies or not + when called on a specific system cookie store implementation. Most of the + cookies fetching on iOS Chromium is done by the WKWebView and doesn't + involve calling GetCookiesForURL. The method is only called when a request + is made by the UrlRequestFetcher for cases that are not handled by WKWebView + (eg. Downloads, Auto Suggestions and NTP tiles). + </summary> +</histogram> + +<histogram name="IOS.Cookies.GetCookiesForURLCallStoreType" + enum="IOSGetCookiesForURLCallCookieStoreType"> + <owner>mrefaat@chromium.org</owner> + <summary> + The system cookie store type used when GetCookiesForURL method is called. + Most of the cookies fetching on iOS Chromium is done by the WKWebView and + doesn't involve calling GetCookiesForURL. The method is only called when a + request is made by the UrlRequestFetcher for cases that are not handled by + WKWebView (eg. Downloads, Auto Suggestions and NTP tiles). + </summary> +</histogram> + <histogram name="IOS.DragAndDrop.DragContent" enum="DragContent"> <owner>jif@chromium.org</owner> <summary> @@ -79312,6 +79477,9 @@ </histogram> <histogram name="Quota.LRUOriginTypes" enum="QuotaOriginTypes"> + <obsolete> + Removed July 2018 + </obsolete> <owner>dgrogan@chromium.org</owner> <summary> Types of origins that are initially selected for eviction via LRU. Some of @@ -115760,6 +115928,7 @@ <suffix name="Clicked" label="Clicked by the user, on click"/> <suffix name="Visible" label="Intersects with the viewport, on page load"/> <affected-histogram name="AnchorElementMetrics.ContainsImage"/> + <affected-histogram name="AnchorElementMetrics.DocumentEngagementScore"/> <affected-histogram name="AnchorElementMetrics.IsInIFrame"/> <affected-histogram name="AnchorElementMetrics.IsSameHost"/> <affected-histogram name="AnchorElementMetrics.IsUrlIncrementedByOne"/>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index f9e13b9..91894b2 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -154,7 +154,6 @@ crbug.com/829499 [ Android_One ] rendering.mobile/css_animations_many_keyframes [ Skip ] crbug.com/829499 [ Android_One ] rendering.mobile/web_animations_many_keyframes [ Skip ] crbug.com/840964 [ Nexus_5X ] rendering.mobile/web_animations_many_keyframes [ Skip ] -crbug.com/750833 [ Android_Webview ] rendering.mobile/flickr_scroll [ Skip ] crbug.com/653993 [ Android_Webview ] rendering.mobile/maps_perf_test [ Skip ] [ All ] rendering.mobile/core_scroll_header_panel [ Skip ] # Polymer test, needs to be modernized. [ All ] rendering.mobile/paper_button [ Skip ] # Polymer test, needs to be modernized.
diff --git a/tools/perf/page_sets/data/rendering_desktop.json b/tools/perf/page_sets/data/rendering_desktop.json index ae6bfc4..485e842 100644 --- a/tools/perf/page_sets/data/rendering_desktop.json +++ b/tools/perf/page_sets/data/rendering_desktop.json
@@ -207,25 +207,91 @@ "many_planets_deep": { "DEFAULT": "tough_webgl_cases_006.wprgo" }, - "blogspot_pinch": { + "accu_weather_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "amazon_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "amazon_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "blogspot_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "blogspot_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "booking_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "booking_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "cnn_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "cnn_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "ebay_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "ebay_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "espn_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "espn_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "facebook_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "facebook_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "gmail_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "gmail_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "google_calendar_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "google_calendar_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "google_image_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "google_image_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "google_search_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "google_search_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "linkedin_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "linkedin_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "twitch_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "twitter_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, - "weather_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + "twitter_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" }, - "booking_pinch": { + "weather_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, "yahoo_games_pinch": { @@ -234,32 +300,20 @@ "yahoo_news_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "yahoo_news_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "yahoo_sports_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, - "amazon_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "cnn_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "ebay_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + "yahoo_sports_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" }, "youtube_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, - "gmail_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "google_search_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "google_calendar_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "google_image_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + "youtube_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" }, "cats_unscaled": { "DEFAULT": "tough_image_decode_cases_000.wprgo" @@ -267,7 +321,7 @@ "cats_viewport_width": { "DEFAULT": "tough_image_decode_cases_000.wprgo" }, - "js_full_screen_invalidation": { + "js_full_screen_invalidation": { "DEFAULT": "tough_compositor_cases_001.wprgo" }, "new_tilings": {
diff --git a/tools/perf/page_sets/data/rendering_mobile.json b/tools/perf/page_sets/data/rendering_mobile.json index 73ae6ad1..52ba1e3 100644 --- a/tools/perf/page_sets/data/rendering_mobile.json +++ b/tools/perf/page_sets/data/rendering_mobile.json
@@ -491,35 +491,23 @@ }, "smash_cat": { "DEFAULT": "tough_canvas_cases_001.wprgo" - }, - "microsoft_performance": { - "DEFAULT": "tough_animation_cases_000.wprgo" }, - "ebay_scroll": { - "DEFAULT": "simple_mobile_sites_002.wprgo" + "microsoft_performance": { + "DEFAULT": "tough_animation_cases_000.wprgo" }, "ebay_scroll_2018": { "DEFAULT": "simple_mobile_sites_003.wprgo" }, - "flickr_scroll": { - "DEFAULT": "simple_mobile_sites_002.wprgo" - }, "flickr_scroll_2018": { "DEFAULT": "simple_mobile_sites_003.wprgo" }, - "nyc_gov_scroll": { - "DEFAULT": "simple_mobile_sites_002.wprgo" - }, "nyc_gov_scroll_2018": { "DEFAULT": "simple_mobile_sites_003.wprgo" }, - "nytimes_scroll": { - "DEFAULT": "simple_mobile_sites_002.wprgo" - }, "nytimes_scroll_2018": { "DEFAULT": "simple_mobile_sites_003.wprgo" }, - "aquarium_20k": { + "aquarium_20k": { "DEFAULT": "tough_webgl_cases_006.wprgo" }, "animometer_webgl": {
diff --git a/tools/perf/page_sets/data/tough_pinch_zoom_cases.json b/tools/perf/page_sets/data/tough_pinch_zoom_cases.json index 671e8e4..e326ad1 100644 --- a/tools/perf/page_sets/data/tough_pinch_zoom_cases.json +++ b/tools/perf/page_sets/data/tough_pinch_zoom_cases.json
@@ -1,24 +1,90 @@ { "archives": { + "accu_weather_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "amazon_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "amazon_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "blogspot_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "blogspot_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "booking_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "booking_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "cnn_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "cnn_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "ebay_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "ebay_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "espn_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "espn_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "facebook_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "facebook_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "gmail_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "gmail_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "google_calendar_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "google_calendar_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "google_image_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "google_image_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "google_search_pinch": { + "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + }, + "google_search_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "linkedin_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "linkedin_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, + "twitch_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "twitter_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, - "weather_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + "twitter_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" }, - "booking_pinch": { + "weather_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, "yahoo_games_pinch": { @@ -27,32 +93,20 @@ "yahoo_news_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, + "yahoo_news_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" + }, "yahoo_sports_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, - "amazon_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "cnn_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "ebay_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + "yahoo_sports_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" }, "youtube_pinch": { "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" }, - "gmail_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "google_search_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "google_calendar_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" - }, - "google_image_pinch": { - "DEFAULT": "tough_pinch_zoom_cases_000.wprgo" + "youtube_pinch_2018": { + "DEFAULT": "tough_pinch_zoom_cases_001.wprgo" } }, "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
diff --git a/tools/perf/page_sets/data/tough_pinch_zoom_cases_001.wprgo.sha1 b/tools/perf/page_sets/data/tough_pinch_zoom_cases_001.wprgo.sha1 new file mode 100644 index 0000000..f523acf --- /dev/null +++ b/tools/perf/page_sets/data/tough_pinch_zoom_cases_001.wprgo.sha1
@@ -0,0 +1 @@ +f343b7d0516f9fa2890a445be57842e12177dd69 \ No newline at end of file
diff --git a/tools/perf/page_sets/rendering/simple_mobile_sites.py b/tools/perf/page_sets/rendering/simple_mobile_sites.py index 89091ca5..74b78a5 100644 --- a/tools/perf/page_sets/rendering/simple_mobile_sites.py +++ b/tools/perf/page_sets/rendering/simple_mobile_sites.py
@@ -36,44 +36,24 @@ action_runner.ScrollPage(direction='down', speed_in_pixels_per_second=300) -class SimpleEbayPage(SimplePage): - BASE_NAME = 'ebay_scroll' - URL = 'http://www.ebay.co.uk/' - - class SimpleEbay2018Page(SimplePage): BASE_NAME = 'ebay_scroll' YEAR = '2018' URL = 'http://www.ebay.co.uk/' -class SimpleFlickrPage(SimplePage): - BASE_NAME = 'flickr_scroll' - URL = 'https://www.flickr.com/' - - class SimpleFlickr2018Page(SimplePage): BASE_NAME = 'flickr_scroll' YEAR = '2018' URL = 'https://www.flickr.com/photos/flickr/albums/72157639858715274' -class SimpleNYCGovPage(SimplePage): - BASE_NAME = 'nyc_gov_scroll' - URL = 'http://www.nyc.gov' - - class SimpleNYCGov2018Page(SimplePage): BASE_NAME = 'nyc_gov_scroll' YEAR = '2018' URL = 'http://www.nyc.gov' -class SimpleNYTimesPage(SimplePage): - BASE_NAME = 'nytimes_scroll' - URL = 'http://m.nytimes.com/' - - class SimpleNYTimes2018Page(SimplePage): BASE_NAME = 'nytimes_scroll' YEAR = '2018'
diff --git a/tools/perf/page_sets/rendering/tough_pinch_zoom_cases.py b/tools/perf/page_sets/rendering/tough_pinch_zoom_cases.py index 3d53ac0..8dda6230 100644 --- a/tools/perf/page_sets/rendering/tough_pinch_zoom_cases.py +++ b/tools/perf/page_sets/rendering/tough_pinch_zoom_cases.py
@@ -7,6 +7,8 @@ from page_sets.rendering import rendering_story from page_sets.rendering import story_tags from page_sets.system_health import platforms +from page_sets.login_helpers import linkedin_login +from page_sets.login_helpers import google_login class ToughPinchZoomPage(rendering_story.RenderingStory): @@ -61,6 +63,19 @@ action_runner.WaitForElement(text='Next') +class GoogleSearchPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: top google property; a google tab is often open. """ + + BASE_NAME = 'google_search_pinch' + YEAR = '2018' + URL = 'https://www.google.com/#hl=en&q=barack+obama' + + def RunNavigateSteps(self, action_runner): + super(GoogleSearchPinchZoom2018Page, self).RunNavigateSteps(action_runner) + action_runner.WaitForElement(text='Next') + + class GmailPinchZoomPage(ToughPinchZoomPage): """ Why: productivity, top google properties """ @@ -75,6 +90,22 @@ 'document.getElementById("gb") !== null') +class GmailPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: productivity, top google properties """ + + BASE_NAME = 'gmail_pinch' + YEAR = '2018' + URL = 'https://mail.google.com/mail/' + + def RunNavigateSteps(self, action_runner): + google_login.NewLoginGoogleAccount(action_runner, 'googletest') + super(GmailPinchZoom2018Page, self).RunNavigateSteps(action_runner) + action_runner.WaitForJavaScriptCondition( + 'window.gmonkey !== undefined &&' + 'document.getElementById("gb") !== null') + + class GoogleCalendarPinchZoomPage(ToughPinchZoomPage): """ Why: productivity, top google properties """ @@ -87,6 +118,21 @@ action_runner.Wait(2) +class GoogleCalendarPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: productivity, top google properties """ + + BASE_NAME = 'google_calendar_pinch' + YEAR = '2018' + URL = 'https://www.google.com/calendar/' + + def RunNavigateSteps(self, action_runner): + google_login.NewLoginGoogleAccount(action_runner, 'googletest') + super(GoogleCalendarPinchZoom2018Page, self).RunNavigateSteps( + action_runner) + action_runner.WaitForElement('span[class~="sm8sCf"]') + + class GoogleImagePinchZoomPage(ToughPinchZoomPage): """ Why: tough image case; top google properties """ @@ -95,6 +141,15 @@ URL = 'https://www.google.com/search?q=cats&tbm=isch' +class GoogleImagePinchZoom2018Page(ToughPinchZoomPage): + + """ Why: tough image case; top google properties """ + + BASE_NAME = 'google_image_pinch' + YEAR = '2018' + URL = 'https://www.google.com/search?q=cats&tbm=isch' + + class YoutubePinchZoomPage(ToughPinchZoomPage): """ Why: #3 (Alexa global) """ @@ -107,6 +162,19 @@ action_runner.Wait(2) +class YoutubePinchZoom2018Page(ToughPinchZoomPage): + + """ Why: #3 (Alexa global) """ + + BASE_NAME = 'youtube_pinch' + YEAR = '2018' + URL = 'http://www.youtube.com' + + def RunNavigateSteps(self, action_runner): + super(YoutubePinchZoom2018Page, self).RunNavigateSteps(action_runner) + action_runner.WaitForElement(selector='#buttons') + + class BlogSpotPinchZoomPage(ToughPinchZoomPage): """ @@ -122,6 +190,22 @@ action_runner.WaitForElement(text='accessibility') +class BlogSpotPinchZoom2018Page(ToughPinchZoomPage): + + """ + Why: #11 (Alexa global), google property; some blogger layouts have infinite + scroll but more interesting + """ + + BASE_NAME = 'blogspot_pinch' + YEAR = '2018' + URL = 'http://googlewebmastercentral.blogspot.com/' + + def RunNavigateSteps(self, action_runner): + super(BlogSpotPinchZoom2018Page, self).RunNavigateSteps(action_runner) + action_runner.WaitForElement('div[class="searchBox"]') + + class FacebookPinchZoomPage(ToughPinchZoomPage): """ Why: top social,Public profile """ @@ -134,6 +218,19 @@ action_runner.WaitForElement(text='About') +class FacebookPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: top social,Public profile """ + + BASE_NAME = 'facebook_pinch' + YEAR = '2018' + URL = 'http://www.facebook.com/barackobama' + + def RunNavigateSteps(self, action_runner): + super(FacebookPinchZoom2018Page, self).RunNavigateSteps(action_runner) + action_runner.WaitForElement(text='Videos') + + class LinkedinPinchZoomPage(ToughPinchZoomPage): """ Why: #12 (Alexa global),Public profile """ @@ -142,6 +239,19 @@ URL = 'http://www.linkedin.com/in/linustorvalds' +class LinkedinPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: #12 (Alexa global),Public profile """ + + BASE_NAME = 'linkedin_pinch' + YEAR = '2018' + URL = 'http://www.linkedin.com/in/linustorvalds' + + def RunNavigateSteps(self, action_runner): + linkedin_login.LoginDesktopAccount(action_runner, 'linkedin') + super(LinkedinPinchZoom2018Page, self).RunNavigateSteps(action_runner) + + class TwitterPinchZoomPage(ToughPinchZoomPage): """ Why: #8 (Alexa global),Picked an interesting page """ @@ -154,6 +264,19 @@ action_runner.Wait(2) +class TwitterPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: #8 (Alexa global),Picked an interesting page """ + + BASE_NAME = 'twitter_pinch' + YEAR = '2018' + URL = 'https://twitter.com/katyperry' + + def RunNavigateSteps(self, action_runner): + super(TwitterPinchZoom2018Page, self).RunNavigateSteps(action_runner) + action_runner.WaitForElement(selector='.ProfileNav') + + class ESPNPinchZoomPage(ToughPinchZoomPage): """ Why: #1 sports """ @@ -162,6 +285,15 @@ URL = 'http://espn.go.com/nba' +class ESPNPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: #1 sports """ + + BASE_NAME = 'espn_pinch' + YEAR = '2018' + URL = 'http://espn.go.com/nba' + + class WeatherDotComPinchZoomPage(ToughPinchZoomPage): """ Why: #7 (Alexa news); #27 total time spent,Picked interesting page """ @@ -170,6 +302,13 @@ URL = 'http://www.weather.com/weather/right-now/Mountain+View+CA+94043' +class AccuWeatherPinchZoom2018Page(ToughPinchZoomPage): + """ Why: #2 weather according to Alexa """ + BASE_NAME = 'accu_weather_pinch' + YEAR = '2018' + URL = 'https://www.accuweather.com/en/us/new-york-ny/10017/weather-forecast/349727' + + class YahooGamePinchZoomPage(ToughPinchZoomPage): """ Why: #1 games according to Alexa (with actual games in it) """ @@ -182,6 +321,13 @@ action_runner.Wait(2) +class TwitchPinchZoom2018Page(ToughPinchZoomPage): + """ Why: #1 games according to Alexa """ + BASE_NAME = 'twitch_pinch' + YEAR = '2018' + URL = 'https://www.twitch.tv' + + class YahooNewsPinchZoomPage(ToughPinchZoomPage): """ Why: #1 news worldwide (Alexa global) """ @@ -190,6 +336,15 @@ URL = 'http://news.yahoo.com' +class YahooNewsPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: #1 news worldwide (Alexa global) """ + + BASE_NAME = 'yahoo_news_pinch' + YEAR = '2018' + URL = 'http://news.yahoo.com' + + class CnnPinchZoomPage(ToughPinchZoomPage): """ Why: #2 news worldwide """ @@ -198,6 +353,15 @@ URL = 'http://www.cnn.com' +class CnnPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: #2 news worldwide """ + + BASE_NAME = 'cnn_pinch' + YEAR = '2018' + URL = 'http://www.cnn.com' + + class AmazonPinchZoomPage(ToughPinchZoomPage): """ @@ -209,6 +373,18 @@ URL = 'http://www.amazon.com' +class AmazonPinchZoom2018Page(ToughPinchZoomPage): + + """ + Why: #1 world commerce website by visits; #3 commerce in the US by + time spent + """ + + BASE_NAME = 'amazon_pinch' + YEAR = '2018' + URL = 'http://www.amazon.com' + + class EBayPinchZoomPage(ToughPinchZoomPage): """ Why: #1 commerce website by time spent by users in US""" @@ -217,6 +393,15 @@ URL = 'http://www.ebay.com' +class EBayPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: #1 commerce website by time spent by users in US""" + + BASE_NAME = 'ebay_pinch' + YEAR = '2018' + URL = 'http://www.ebay.com' + + class BookingPinchZoomPage(ToughPinchZoomPage): """ Why: #1 Alexa recreation""" @@ -225,6 +410,15 @@ URL = 'http://booking.com' +class BookingPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: #1 Alexa recreation""" + + BASE_NAME = 'booking_pinch' + YEAR = '2018' + URL = 'http://booking.com' + + class YahooSportsPinchZoomPage(ToughPinchZoomPage): """ Why: #1 Alexa sports""" @@ -232,6 +426,14 @@ URL = 'http://sports.yahoo.com/' +class YahooSportsPinchZoom2018Page(ToughPinchZoomPage): + + """ Why: #1 Alexa sports""" + BASE_NAME = 'yahoo_sports_pinch' + YEAR = '2018' + URL = 'http://sports.yahoo.com/' + + # TODO(crbug.com/760553):remove this class after # smoothness.tough_pinch_zoom_cases benchmark is completely # replaced by rendering benchmarks @@ -283,6 +485,43 @@ self.AddStory(BookingPinchZoomPage( page_set=self)) + self.AddStory(GoogleSearchPinchZoom2018Page( + page_set=self)) + self.AddStory(GmailPinchZoom2018Page( + page_set=self)) + self.AddStory(GoogleCalendarPinchZoom2018Page( + page_set=self)) + self.AddStory(GoogleImagePinchZoom2018Page( + page_set=self)) + self.AddStory(YoutubePinchZoom2018Page( + page_set=self)) + self.AddStory(BlogSpotPinchZoom2018Page( + page_set=self)) + self.AddStory(FacebookPinchZoom2018Page( + page_set=self)) + self.AddStory(LinkedinPinchZoom2018Page( + page_set=self)) + self.AddStory(TwitterPinchZoom2018Page( + page_set=self)) + self.AddStory(ESPNPinchZoom2018Page( + page_set=self)) + self.AddStory(TwitchPinchZoom2018Page( + page_set=self)) + self.AddStory(YahooNewsPinchZoom2018Page( + page_set=self)) + self.AddStory(CnnPinchZoom2018Page( + page_set=self)) + self.AddStory(AmazonPinchZoom2018Page( + page_set=self)) + self.AddStory(EBayPinchZoom2018Page( + page_set=self)) + self.AddStory(AccuWeatherPinchZoom2018Page( + page_set=self)) + self.AddStory(YahooSportsPinchZoom2018Page( + page_set=self)) + self.AddStory(BookingPinchZoom2018Page( + page_set=self)) + class AndroidToughPinchZoomCasesPageSet(ToughPinchZoomCasesPageSet):
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index 09f770c..f7b742e 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -1313,22 +1313,62 @@ void AXPlatformNodeAuraLinux::GetAtkState(AtkStateSet* atk_state_set) { AXNodeData data = GetData(); + if (data.HasState(ax::mojom::State::kCollapsed)) + atk_state_set_add_state(atk_state_set, ATK_STATE_EXPANDABLE); if (data.HasState(ax::mojom::State::kDefault)) atk_state_set_add_state(atk_state_set, ATK_STATE_DEFAULT); if (data.HasState(ax::mojom::State::kEditable)) atk_state_set_add_state(atk_state_set, ATK_STATE_EDITABLE); - if (data.HasState(ax::mojom::State::kExpanded)) + if (data.HasState(ax::mojom::State::kExpanded)) { + atk_state_set_add_state(atk_state_set, ATK_STATE_EXPANDABLE); atk_state_set_add_state(atk_state_set, ATK_STATE_EXPANDED); + } if (data.HasState(ax::mojom::State::kFocusable)) atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSABLE); + if (data.HasState(ax::mojom::State::kHorizontal)) + atk_state_set_add_state(atk_state_set, ATK_STATE_HORIZONTAL); + if (!data.HasState(ax::mojom::State::kInvisible)) { + atk_state_set_add_state(atk_state_set, ATK_STATE_VISIBLE); + if (!delegate_->IsOffscreen()) + atk_state_set_add_state(atk_state_set, ATK_STATE_SHOWING); + } + if (data.HasState(ax::mojom::State::kMultiselectable)) + atk_state_set_add_state(atk_state_set, ATK_STATE_MULTISELECTABLE); + if (data.HasState(ax::mojom::State::kRequired)) + atk_state_set_add_state(atk_state_set, ATK_STATE_REQUIRED); + if (data.HasState(ax::mojom::State::kVertical)) + atk_state_set_add_state(atk_state_set, ATK_STATE_VERTICAL); + if (data.HasState(ax::mojom::State::kVisited)) + atk_state_set_add_state(atk_state_set, ATK_STATE_VISITED); + if (data.HasIntAttribute(ax::mojom::IntAttribute::kInvalidState) && + data.GetIntAttribute(ax::mojom::IntAttribute::kInvalidState) != + static_cast<int32_t>(ax::mojom::InvalidState::kFalse)) + atk_state_set_add_state(atk_state_set, ATK_STATE_INVALID_ENTRY); #if defined(ATK_216) + if (data.HasIntAttribute(ax::mojom::IntAttribute::kCheckedState)) + atk_state_set_add_state(atk_state_set, ATK_STATE_CHECKABLE); if (data.HasIntAttribute(ax::mojom::IntAttribute::kHasPopup)) atk_state_set_add_state(atk_state_set, ATK_STATE_HAS_POPUP); #endif - if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) - atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTED); - if (data.HasBoolAttribute(ax::mojom::BoolAttribute::kSelected)) + if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kBusy)) + atk_state_set_add_state(atk_state_set, ATK_STATE_BUSY); + if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kModal)) + atk_state_set_add_state(atk_state_set, ATK_STATE_MODAL); + if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) { atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTABLE); + atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTED); + } + if (IsPlainTextField() || IsRichTextField()) { + atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTABLE_TEXT); + if (data.HasState(ax::mojom::State::kMultiline)) + atk_state_set_add_state(atk_state_set, ATK_STATE_MULTI_LINE); + else + atk_state_set_add_state(atk_state_set, ATK_STATE_SINGLE_LINE); + } + + if (!GetStringAttribute(ax::mojom::StringAttribute::kAutoComplete).empty() || + IsFocusedInputWithSuggestions()) + atk_state_set_add_state(atk_state_set, ATK_STATE_SUPPORTS_AUTOCOMPLETION); // Checked state const auto checked_state = GetData().GetCheckedState(); @@ -1349,6 +1389,7 @@ switch (GetData().GetRestriction()) { case ax::mojom::Restriction::kNone: atk_state_set_add_state(atk_state_set, ATK_STATE_ENABLED); + atk_state_set_add_state(atk_state_set, ATK_STATE_SENSITIVE); break; case ax::mojom::Restriction::kReadOnly: #if defined(ATK_216)
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc index 612e070d..3a94cf3 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -76,6 +76,9 @@ // // AtkObject tests // +#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 16, 0) +#define ATK_216 +#endif TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectDetachedObject) { AXNodeData root; @@ -201,9 +204,6 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectState) { AXNodeData root; root.id = 1; - root.AddState(ax::mojom::State::kDefault); - root.AddState(ax::mojom::State::kExpanded); - Init(root); AtkObject* root_obj(GetRootAtkObject()); @@ -212,9 +212,107 @@ AtkStateSet* state_set = atk_object_ref_state_set(root_obj); ASSERT_TRUE(ATK_IS_STATE_SET(state_set)); - ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_DEFAULT)); - ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDED)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_ENABLED)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_SENSITIVE)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_SHOWING)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_VISIBLE)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_BUSY)); +#if defined(ATK_216) + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_CHECKABLE)); +#endif + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_CHECKED)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_DEFAULT)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_EDITABLE)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDABLE)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDED)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_FOCUSABLE)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_FOCUSED)); +#if defined(ATK_216) + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_HAS_POPUP)); +#endif + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_HORIZONTAL)); + ASSERT_FALSE( + atk_state_set_contains_state(state_set, ATK_STATE_INVALID_ENTRY)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_MODAL)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_MULTI_LINE)); + ASSERT_FALSE( + atk_state_set_contains_state(state_set, ATK_STATE_MULTISELECTABLE)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_REQUIRED)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_SELECTABLE)); + ASSERT_FALSE( + atk_state_set_contains_state(state_set, ATK_STATE_SELECTABLE_TEXT)); ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_SELECTED)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_SINGLE_LINE)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, + ATK_STATE_SUPPORTS_AUTOCOMPLETION)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_VERTICAL)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_VISITED)); + g_object_unref(state_set); + + root = AXNodeData(); + root.AddState(ax::mojom::State::kDefault); + root.AddState(ax::mojom::State::kEditable); + root.AddState(ax::mojom::State::kExpanded); + root.AddState(ax::mojom::State::kFocusable); + root.AddState(ax::mojom::State::kMultiselectable); + root.AddState(ax::mojom::State::kRequired); + root.AddState(ax::mojom::State::kVertical); + root.AddBoolAttribute(ax::mojom::BoolAttribute::kBusy, true); + root.SetInvalidState(ax::mojom::InvalidState::kTrue); + root.AddStringAttribute(ax::mojom::StringAttribute::kAutoComplete, "foo"); + GetRootNode()->SetData(root); + + state_set = atk_object_ref_state_set(root_obj); + ASSERT_TRUE(ATK_IS_STATE_SET(state_set)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_BUSY)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_DEFAULT)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EDITABLE)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDABLE)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDED)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_FOCUSABLE)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_INVALID_ENTRY)); + ASSERT_TRUE( + atk_state_set_contains_state(state_set, ATK_STATE_MULTISELECTABLE)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_REQUIRED)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, + ATK_STATE_SUPPORTS_AUTOCOMPLETION)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_VERTICAL)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_FOCUSED)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_HORIZONTAL)); + g_object_unref(state_set); + + root = AXNodeData(); + root.AddState(ax::mojom::State::kCollapsed); + root.AddState(ax::mojom::State::kHorizontal); + root.AddState(ax::mojom::State::kVisited); + root.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true); + root.SetHasPopup(ax::mojom::HasPopup::kTrue); + GetRootNode()->SetData(root); + + state_set = atk_object_ref_state_set(root_obj); + ASSERT_TRUE(ATK_IS_STATE_SET(state_set)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDABLE)); +#if defined(ATK_216) + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_HAS_POPUP)); +#endif + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_HORIZONTAL)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_SELECTABLE)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_SELECTED)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_VISITED)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDED)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_VERTICAL)); + g_object_unref(state_set); + + root = AXNodeData(); + root.AddState(ax::mojom::State::kInvisible); + root.AddBoolAttribute(ax::mojom::BoolAttribute::kModal, true); + GetRootNode()->SetData(root); + + state_set = atk_object_ref_state_set(root_obj); + ASSERT_TRUE(ATK_IS_STATE_SET(state_set)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_MODAL)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_SHOWING)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_VISIBLE)); g_object_unref(state_set); g_object_unref(root_obj);
diff --git a/ui/chromeos/events/event_rewriter_chromeos.cc b/ui/chromeos/events/event_rewriter_chromeos.cc index e2d287b2..05639df 100644 --- a/ui/chromeos/events/event_rewriter_chromeos.cc +++ b/ui/chromeos/events/event_rewriter_chromeos.cc
@@ -110,8 +110,9 @@ const ModifierRemapping* kModifierRemappingNeoMod3 = &kModifierRemappings[1]; // Gets a remapped key for |pref_name| key. For example, to find out which -// key Search is currently remapped to, call the function with -// prefs::kLanguageRemapSearchKeyTo. +// key Ctrl is currently remapped to, call the function with +// prefs::kLanguageRemapControlKeyTo. +// Note: For the Search key, call GetSearchRemappedKey(). const ModifierRemapping* GetRemappedKey( const std::string& pref_name, EventRewriterChromeOS::Delegate* delegate) { @@ -122,13 +123,40 @@ if (!delegate->GetKeyboardRemappedPrefValue(pref_name, &value)) return nullptr; - for (size_t i = 0; i < arraysize(kModifierRemappings); ++i) { - if (value == static_cast<int>(kModifierRemappings[i].remap_to)) - return &kModifierRemappings[i]; + for (auto& remapping : kModifierRemappings) { + if (value == static_cast<int>(remapping.remap_to)) + return &remapping; } + return nullptr; } +// Gets a remapped key for the Search key based on the |keyboard_type| of the +// last event. Internal Search key, Command key on external Apple keyboards, and +// Meta key (either Search or Windows) on external non-Apple keyboards can all +// be remapped separately. +const ModifierRemapping* GetSearchRemappedKey( + EventRewriterChromeOS::Delegate* delegate, + EventRewriterChromeOS::DeviceType keyboard_type) { + std::string pref_name; + switch (keyboard_type) { + case EventRewriterChromeOS::kDeviceAppleKeyboard: + pref_name = prefs::kLanguageRemapExternalCommandKeyTo; + break; + + case EventRewriterChromeOS::kDeviceExternalNonAppleKeyboard: + pref_name = prefs::kLanguageRemapExternalMetaKeyTo; + break; + + default: + // Use the preference for internal Search key remapping. + pref_name = prefs::kLanguageRemapSearchKeyTo; + break; + } + + return GetRemappedKey(pref_name, delegate); +} + bool HasDiamondKey() { return base::CommandLine::ForCurrentProcess()->HasSwitch( ::chromeos::switches::kHasChromeOSDiamondKey); @@ -144,36 +172,6 @@ return manager->IsISOLevel5ShiftUsedByCurrentInputMethod(); } -EventRewriterChromeOS::DeviceType GetDeviceType(const std::string& device_name, - int vendor_id, - int product_id) { - if (vendor_id == kHotrodRemoteVendorId && - product_id == kHotrodRemoteProductId) { - return EventRewriterChromeOS::kDeviceHotrodRemote; - } - - if (base::LowerCaseEqualsASCII(device_name, "virtual core keyboard")) - return EventRewriterChromeOS::kDeviceVirtualCoreKeyboard; - - std::vector<std::string> tokens = base::SplitString( - device_name, " .", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - - // If the |device_name| contains the two words, "apple" and "keyboard", treat - // it as an Apple keyboard. - bool found_apple = false; - bool found_keyboard = false; - for (size_t i = 0; i < tokens.size(); ++i) { - if (!found_apple && base::LowerCaseEqualsASCII(tokens[i], "apple")) - found_apple = true; - if (!found_keyboard && base::LowerCaseEqualsASCII(tokens[i], "keyboard")) - found_keyboard = true; - if (found_apple && found_keyboard) - return EventRewriterChromeOS::kDeviceAppleKeyboard; - } - - return EventRewriterChromeOS::kDeviceUnknown; -} - struct KeyboardRemapping { // MatchKeyboardRemapping() succeeds if the tested has all of the specified // flags (and possibly other flags), and either the key_code matches or the @@ -273,15 +271,56 @@ EventRewriterChromeOS::~EventRewriterChromeOS() {} +// static +EventRewriterChromeOS::DeviceType EventRewriterChromeOS::GetDeviceType( + const ui::InputDevice& keyboard_device) { + if (keyboard_device.vendor_id == kHotrodRemoteVendorId && + keyboard_device.product_id == kHotrodRemoteProductId) { + return EventRewriterChromeOS::kDeviceHotrodRemote; + } + + if (base::LowerCaseEqualsASCII(keyboard_device.name, + "virtual core keyboard")) { + return EventRewriterChromeOS::kDeviceVirtualCoreKeyboard; + } + + const std::vector<std::string> tokens = + base::SplitString(keyboard_device.name, " .", base::KEEP_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + + // If the |device_name| contains the two words, "apple" and "keyboard", treat + // it as an Apple keyboard. + bool found_apple = false; + bool found_keyboard = false; + for (size_t i = 0; i < tokens.size(); ++i) { + if (!found_apple && base::LowerCaseEqualsASCII(tokens[i], "apple")) + found_apple = true; + if (!found_keyboard && base::LowerCaseEqualsASCII(tokens[i], "keyboard")) + found_keyboard = true; + if (found_apple && found_keyboard) + return EventRewriterChromeOS::kDeviceAppleKeyboard; + } + + if (!found_apple && found_keyboard && + keyboard_device.type == INPUT_DEVICE_EXTERNAL) { + return EventRewriterChromeOS::kDeviceExternalNonAppleKeyboard; + } + + return EventRewriterChromeOS::kDeviceUnknown; +} + void EventRewriterChromeOS::KeyboardDeviceAddedForTesting( int device_id, const std::string& device_name, - KeyboardTopRowLayout layout) { + KeyboardTopRowLayout layout, + InputDeviceType device_type) { // Tests must avoid XI2 reserved device IDs. DCHECK((device_id < 0) || (device_id > 1)); - KeyboardDeviceAddedInternal( - device_id, - GetDeviceType(device_name, kUnknownVendorId, kUnknownProductId), layout); + InputDevice keyboard_device(device_id, device_type, device_name); + keyboard_device.vendor_id = kUnknownVendorId; + keyboard_device.product_id = kUnknownProductId; + KeyboardDeviceAddedInternal(device_id, GetDeviceType(keyboard_device), + layout); } void EventRewriterChromeOS::RewriteMouseButtonEventForTesting( @@ -398,27 +437,26 @@ last_keyboard_device_id_ = device_id; } -bool EventRewriterChromeOS::IsAppleKeyboard() const { - return IsLastKeyboardOfType(kDeviceAppleKeyboard); -} - bool EventRewriterChromeOS::IsHotrodRemote() const { return IsLastKeyboardOfType(kDeviceHotrodRemote); } bool EventRewriterChromeOS::IsLastKeyboardOfType(DeviceType device_type) const { - if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE) - return false; + return GetLastKeyboardType() == device_type; +} - // Check which device generated |event|. +EventRewriterChromeOS::DeviceType EventRewriterChromeOS::GetLastKeyboardType() + const { + if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE) + return kDeviceUnknown; + const auto iter = device_id_to_info_.find(last_keyboard_device_id_); if (iter == device_id_to_info_.end()) { LOG(ERROR) << "Device ID " << last_keyboard_device_id_ << " is unknown."; - return false; + return kDeviceUnknown; } - const DeviceType type = iter->second.type; - return type == device_type; + return iter->second.type; } int EventRewriterChromeOS::GetRemappedModifierMasks(const ui::Event& event, @@ -432,11 +470,7 @@ continue; switch (kModifierRemappings[i].flag) { case ui::EF_COMMAND_DOWN: - // Rewrite Command key presses on an Apple keyboard to Control. - if (IsAppleKeyboard()) { - DCHECK_EQ(ui::EF_CONTROL_DOWN, kModifierRemappingCtrl->flag); - remapped_key = kModifierRemappingCtrl; - } + remapped_key = GetSearchRemappedKey(delegate_, GetLastKeyboardType()); break; case ui::EF_MOD3_DOWN: // If EF_MOD3_DOWN is used by the current input method, leave it alone; @@ -684,8 +718,7 @@ GetRemappedKey(prefs::kLanguageRemapCapsLockKeyTo, delegate_); } else { characteristic_flag = ui::EF_ALTGR_DOWN; - remapped_key = - GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, delegate_); + remapped_key = GetSearchRemappedKey(delegate_, GetLastKeyboardType()); } } if (remapped_key && remapped_key->result.key_code == ui::VKEY_CAPITAL) @@ -734,14 +767,7 @@ case ui::DomCode::META_LEFT: case ui::DomCode::META_RIGHT: characteristic_flag = ui::EF_COMMAND_DOWN; - // Rewrite Command-L/R key presses on an Apple keyboard to Control. - if (IsAppleKeyboard()) { - DCHECK_EQ(ui::VKEY_CONTROL, kModifierRemappingCtrl->result.key_code); - remapped_key = kModifierRemappingCtrl; - } else { - remapped_key = - GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, delegate_); - } + remapped_key = GetSearchRemappedKey(delegate_, GetLastKeyboardType()); // Default behavior is Super key, hence don't remap the event if the pref // is unavailable. break; @@ -1173,8 +1199,7 @@ ui::InputDeviceManager::GetInstance()->GetKeyboardDevices(); for (const auto& keyboard : keyboard_devices) { if (keyboard.id == device_id) { - const DeviceType type = - GetDeviceType(keyboard.name, keyboard.vendor_id, keyboard.product_id); + const DeviceType type = GetDeviceType(keyboard); if (type == kDeviceAppleKeyboard) { VLOG(1) << "Apple keyboard '" << keyboard.name << "' connected: " << "id=" << device_id;
diff --git a/ui/chromeos/events/event_rewriter_chromeos.h b/ui/chromeos/events/event_rewriter_chromeos.h index ee570e6..8d51f34 100644 --- a/ui/chromeos/events/event_rewriter_chromeos.h +++ b/ui/chromeos/events/event_rewriter_chromeos.h
@@ -12,6 +12,7 @@ #include "base/files/file_path.h" #include "base/macros.h" +#include "ui/events/devices/input_device.h" #include "ui/events/event.h" #include "ui/events/event_rewriter.h" #include "ui/events/keycodes/dom/dom_key.h" @@ -41,6 +42,7 @@ enum DeviceType { kDeviceUnknown = 0, kDeviceAppleKeyboard, + kDeviceExternalNonAppleKeyboard, kDeviceHotrodRemote, kDeviceVirtualCoreKeyboard, // X-server generated events. }; @@ -106,11 +108,14 @@ ui::EventRewriter* sticky_keys_controller); ~EventRewriterChromeOS() override; + static DeviceType GetDeviceType(const ui::InputDevice& keyboard_device); + // Calls KeyboardDeviceAddedInternal. void KeyboardDeviceAddedForTesting( int device_id, const std::string& device_name, - KeyboardTopRowLayout layout = kKbdTopRowLayoutDefault); + KeyboardTopRowLayout layout = kKbdTopRowLayoutDefault, + InputDeviceType device_type = INPUT_DEVICE_UNKNOWN); // Calls RewriteMouseEvent(). void RewriteMouseButtonEventForTesting( @@ -164,12 +169,12 @@ DeviceType type, KeyboardTopRowLayout layout); - // Returns true if |last_keyboard_device_id_| is Apple's. - bool IsAppleKeyboard() const; // Returns true if |last_keyboard_device_id_| is Hotrod remote. bool IsHotrodRemote() const; // Returns true if |last_keyboard_device_id_| is of given |device_type|. bool IsLastKeyboardOfType(DeviceType device_type) const; + // Returns the device type of |last_keyboard_device_id_|. + DeviceType GetLastKeyboardType() const; // Given modifier flags |original_flags|, returns the remapped modifiers // according to user preferences and/or event properties.
diff --git a/ui/chromeos/events/pref_names.cc b/ui/chromeos/events/pref_names.cc index f3b5307..765c0eb 100644 --- a/ui/chromeos/events/pref_names.cc +++ b/ui/chromeos/events/pref_names.cc
@@ -27,5 +27,9 @@ "settings.language.remap_backspace_key_to"; const char kLanguageRemapDiamondKeyTo[] = "settings.language.remap_diamond_key_to"; +const char kLanguageRemapExternalCommandKeyTo[] = + "settings.language.remap_external_command_key_to"; +const char kLanguageRemapExternalMetaKeyTo[] = + "settings.language.remap_external_meta_key_to"; } // namespace prefs
diff --git a/ui/chromeos/events/pref_names.h b/ui/chromeos/events/pref_names.h index d597176..f75aa2a 100644 --- a/ui/chromeos/events/pref_names.h +++ b/ui/chromeos/events/pref_names.h
@@ -17,6 +17,8 @@ extern const char kLanguageRemapEscapeKeyTo[]; extern const char kLanguageRemapBackspaceKeyTo[]; extern const char kLanguageRemapDiamondKeyTo[]; +extern const char kLanguageRemapExternalCommandKeyTo[]; +extern const char kLanguageRemapExternalMetaKeyTo[]; } // namespace prefs
diff --git a/ui/gl/gl_surface_presentation_helper.cc b/ui/gl/gl_surface_presentation_helper.cc index 5a6ce42..064dca9f 100644 --- a/ui/gl/gl_surface_presentation_helper.cc +++ b/ui/gl/gl_surface_presentation_helper.cc
@@ -5,6 +5,7 @@ #include "ui/gl/gl_surface_presentation_helper.h" #include "base/threading/thread_task_runner_handle.h" +#include "build/build_config.h" #include "ui/gfx/vsync_provider.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" @@ -118,6 +119,12 @@ gpu_timing_client_ = context->CreateGPUTimingClient(); if (!gpu_timing_client_->IsAvailable()) gpu_timing_client_ = nullptr; + +// https://crbug.com/854298 : disable GLFence on Android as they seem to cause +// issues on some devices. +#if !defined(OS_ANDROID) + gl_fence_supported_ = GLFence::IsSupported(); +#endif } void GLSurfacePresentationHelper::PreSwapBuffers( @@ -127,7 +134,7 @@ timer = gpu_timing_client_->CreateGPUTimer(false /* prefer_elapsed_time */); timer->QueryTimeStamp(); pending_frames_.push_back(Frame(std::move(timer), callback)); - } else if (GLFence::IsSupported()) { + } else if (gl_fence_supported_) { auto fence = GLFence::Create(); pending_frames_.push_back(Frame(std::move(fence), callback)); } else { @@ -170,7 +177,7 @@ bool need_update_vsync = false; bool disjoint_occurred = gpu_timing_client_ && gpu_timing_client_->CheckAndResetTimerErrors(); - if (disjoint_occurred || (!gpu_timing_client_ && !GLFence::IsSupported())) { + if (disjoint_occurred || (!gpu_timing_client_ && !gl_fence_supported_)) { // If GPUTimer and GLFence are not avaliable or disjoint occurred, we will // compute the next VSync's timestamp and use it to run presentation // callback.
diff --git a/ui/gl/gl_surface_presentation_helper.h b/ui/gl/gl_surface_presentation_helper.h index d4020f10..32c09b7 100644 --- a/ui/gl/gl_surface_presentation_helper.h +++ b/ui/gl/gl_surface_presentation_helper.h
@@ -96,6 +96,7 @@ base::TimeTicks vsync_timebase_; base::TimeDelta vsync_interval_; bool check_pending_frame_scheduled_ = false; + bool gl_fence_supported_ = false; base::WeakPtrFactory<GLSurfacePresentationHelper> weak_ptr_factory_;
diff --git a/ui/views/win/pen_event_processor.cc b/ui/views/win/pen_event_processor.cc index b5e7093..b820c51 100644 --- a/ui/views/win/pen_event_processor.cc +++ b/ui/views/win/pen_event_processor.cc
@@ -45,12 +45,12 @@ // have to check if previously the pointer type is an eraser. if (pointer_pen_info.penFlags & PEN_FLAG_ERASER) { input_type = ui::EventPointerType::POINTER_TYPE_ERASER; - DCHECK(eraser_pointer_id_ == -1 || eraser_pointer_id_ == mapped_pointer_id); + DCHECK(!eraser_pointer_id_ || *eraser_pointer_id_ == mapped_pointer_id); eraser_pointer_id_ = mapped_pointer_id; - } else if (eraser_pointer_id_ == mapped_pointer_id && + } else if (eraser_pointer_id_ && *eraser_pointer_id_ == mapped_pointer_id && message == WM_POINTERUP) { input_type = ui::EventPointerType::POINTER_TYPE_ERASER; - eraser_pointer_id_ = -1; + eraser_pointer_id_.reset(); } // convert pressure into a float [0, 1]. The range of the pressure is
diff --git a/ui/views/win/pen_event_processor.h b/ui/views/win/pen_event_processor.h index 87d949c..ab10799c 100644 --- a/ui/views/win/pen_event_processor.h +++ b/ui/views/win/pen_event_processor.h
@@ -9,6 +9,7 @@ #include <memory> +#include "base/optional.h" #include "ui/events/event.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/sequential_id_generator.h" @@ -54,7 +55,7 @@ bool send_touch_for_pen_ = false; bool sent_mouse_down_ = false; bool sent_touch_start_ = false; - int eraser_pointer_id_ = -1; + base::Optional<unsigned int> eraser_pointer_id_; DISALLOW_COPY_AND_ASSIGN(PenEventProcessor); };
diff --git a/webrunner/service/common.h b/webrunner/service/common.h index 351fbf2..3e4eeb7 100644 --- a/webrunner/service/common.h +++ b/webrunner/service/common.h
@@ -7,6 +7,8 @@ #include <zircon/processargs.h> +#include "webrunner/common/webrunner_export.h" + namespace base { class FilePath; } @@ -29,7 +31,7 @@ // Returns data directory that should be used by this context process. Should // not be called in ContextProvider. Empty path is returned if the context // doesn't have storage dir. -base::FilePath GetWebContextDataDir(); +WEBRUNNER_EXPORT base::FilePath GetWebContextDataDir(); } // namespace webrunner