diff --git a/DEPS b/DEPS index 7cd5e17..7ee58ee 100644 --- a/DEPS +++ b/DEPS
@@ -313,15 +313,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '685cd3e1e037753a4ebc4b8e8dcb9f8cb4f715ee', + 'v8_revision': '9896bae00b80769ae185b10c4217a2a3e4175a1f', # 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': 'fd0ced8b49a2d996b03e02504208be8dbc57b9df', + 'angle_revision': '9ae918cbd468a0b36475ce67564189eee37f3568', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '770571d91b69a1793b7f2036e197969df46ea5eb', + 'swiftshader_revision': '174e65e859012a393cca6d90def85699a31d2914', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -336,7 +336,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:12.20230412.1.1', + 'fuchsia_version': 'version:12.20230412.3.1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -436,11 +436,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '0b3fc055d3df8a2eb4a17cce2efda19f82316314', + 'dawn_revision': '3dba94c1d4f113894a878c8ff7709fd4c75b6e8c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': 'bd548ab081feb21557e52d1ce09930267501d59b', + 'quiche_revision': '385be0b4fa0b5eb5259d6673f154554dbc316250', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -480,7 +480,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'libcxxabi_revision': '695316e1aa3920e1eeb3aefdd38947e474ceef68', + 'libcxxabi_revision': '46d77edb733d1941b7650a8198ac1beff20a157a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -500,7 +500,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': '4156a29aabacb1365718dcc6c2d54cbe878f5e76', + 'libcxx_revision': 'a112d60e2f99bce2892f6aa75b7a6999cdcf8961', # GN CIPD package version. 'gn_version': 'git_revision:ffeea1b1fd070cb6a8d47154a03f8523486b50a7', @@ -795,7 +795,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - 'a41372780a554c5343c56aa82224280d4688e77d', + 'd24b8851c95b4d40302534895e44111162ec96af', 'condition': 'checkout_android and checkout_src_internal', }, @@ -984,7 +984,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'BQdOdR3FkMY93_ukKnPjihaAXycdYucQgngtlCJWxGkC', + 'version': '0iBHIye2VF9ikEfHvOSFmKHtYuzwGC9TltUjKDEgsKsC', }, ], 'condition': 'checkout_android', @@ -1219,7 +1219,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8d19d8641bd11d0bf796fc2e3b7f3d9f6898d5d2', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '88f79dd119bffa65169f1a062f3f5a7155569c97', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1885,7 +1885,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0ac5d460dab4d56f3c07c43eee895557c9d3b9e4', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '2a3942fec1b0fac8e70df55accb8115759f1dc84', + Var('webrtc_git') + '/src.git' + '@' + '921448fbc6765e59590fc4a76d7e5d51ec52b9ca', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -1975,7 +1975,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': Var('chrome_git') + '/chrome/src-internal.git@49abfa4fb1fd2a4cb1246b779fc03dc85cd8a51a', + 'url': Var('chrome_git') + '/chrome/src-internal.git@423928875ebed251bdc69be1fe4fdae15703c325', 'condition': 'checkout_src_internal', },
diff --git a/ash/accelerators/accelerator_alias_converter.cc b/ash/accelerators/accelerator_alias_converter.cc index 63acef2a..4e0bc515 100644 --- a/ash/accelerators/accelerator_alias_converter.cc +++ b/ash/accelerators/accelerator_alias_converter.cc
@@ -10,12 +10,61 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/accelerators/accelerator.h" #include "ui/events/ash/keyboard_capability.h" +#include "ui/events/ash/keyboard_layout_util.h" #include "ui/events/devices/device_data_manager.h" #include "ui/events/devices/input_device.h" #include "ui/events/keycodes/keyboard_codes_posix.h" namespace ash { +namespace { + +using DeviceType = ui::KeyboardCapability::DeviceType; + +bool IsChromeOSKeyboard(const ui::InputDevice& keyboard) { + const auto device_type = + Shell::Get()->keyboard_capability()->GetDeviceType(keyboard); + return device_type == DeviceType::kDeviceInternalKeyboard || + device_type == DeviceType::kDeviceExternalChromeOsKeyboard; +} + +// Gets the most recently plugged in external keyboard. If there are no external +// keyboards, return the internal keyboard. +absl::optional<ui::InputDevice> GetPriorityKeyboard() { + DeviceType priority_device_type = DeviceType::kDeviceUnknown; + absl::optional<ui::InputDevice> priority_keyboard; + for (const ui::InputDevice& keyboard : + ui::DeviceDataManager::GetInstance()->GetKeyboardDevices()) { + const auto device_type = + Shell::Get()->keyboard_capability()->GetDeviceType(keyboard); + switch (device_type) { + case DeviceType::kDeviceUnknown: + case DeviceType::kDeviceInternalKeyboard: + if (!priority_keyboard) { + priority_keyboard = keyboard; + priority_device_type = DeviceType::kDeviceInternalKeyboard; + } + break; + case DeviceType::kDeviceExternalChromeOsKeyboard: + case DeviceType::kDeviceExternalAppleKeyboard: + case DeviceType::kDeviceExternalGenericKeyboard: + case DeviceType::kDeviceExternalUnknown: + case DeviceType::kDeviceHotrodRemote: + case DeviceType::kDeviceVirtualCoreKeyboard: + if (!priority_keyboard || + priority_device_type == DeviceType::kDeviceInternalKeyboard || + keyboard.id > priority_keyboard->id) { + priority_keyboard = keyboard; + priority_device_type = device_type; + } + break; + } + } + return priority_keyboard; +} + +} // namespace + // TODO(zhangwenyu): Handle cases when an accelerator should be suppressed // because certain keys are unavailable. std::vector<ui::Accelerator> AcceleratorAliasConverter::CreateAcceleratorAlias( @@ -52,35 +101,57 @@ // TODO(zhangwenyu): Handle the case when meta + top row key rewrite is // suppressed, following https://crrev.com/c/4160339. // Avoid remapping if [Search] is part of the original accelerator. - if (accelerator.IsCmdDown() || - !Shell::Get()->keyboard_capability()->TopRowKeysAreFKeys()) { - return std::vector<ui::Accelerator>(); + if (accelerator.IsCmdDown()) { + return {}; } - // Deduping is needed since keyboards with the same top row layouts generate - // the same alias. Use flat_set since the size is small. - base::flat_set<ui::Accelerator> aliases_set; - // TODO(zhangwenyu): Handle custom vivaldi layouts. - for (const ui::InputDevice& keyboard : - ui::DeviceDataManager::GetInstance()->GetKeyboardDevices()) { - absl::optional<ui::KeyboardCode> f_key = - Shell::Get()->keyboard_capability()->GetMappedFKeyIfExists( - accelerator.key_code(), keyboard); - if (f_key.has_value()) { - // When a keycode has a mapped function key (meaning it is top row - // key), for internal keyboard, we show icon + meta key, for external - // keyboard, we show F-key + meta key. If both internal and external - // exist, we show both variations. - aliases_set.insert(ui::Accelerator( - keyboard.type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL - ? accelerator.key_code() - : f_key.value(), - accelerator.modifiers() | ui::EF_COMMAND_DOWN, - accelerator.key_state())); + // If the accelerator is not an action key, do no aliasing. + absl::optional<ui::TopRowActionKey> action_key = + ui::KeyboardCapability::ConvertToTopRowActionKey(accelerator.key_code()); + if (!action_key) { + return {}; + } + + absl::optional<ui::InputDevice> priority_keyboard = GetPriorityKeyboard(); + if (!priority_keyboard.has_value()) { + return {}; + } + + const bool top_row_are_fkeys = + Shell::Get()->keyboard_capability()->TopRowKeysAreFKeys(); + absl::optional<ui::KeyboardCode> function_key = + Shell::Get()->keyboard_capability()->GetCorrespondingFunctionKey( + *priority_keyboard, *action_key); + if (!function_key.has_value()) { + return {}; + } + + if (IsChromeOSKeyboard(*priority_keyboard)) { + // If its a ChromeOS Keyboard, the UI should show the Action Key glyph. If + // `top_row_are_fkeys` is true, Search must be added so convert the "F-Key" + // into the action key. + if (top_row_are_fkeys) { + return {ui::Accelerator(accelerator.key_code(), + accelerator.modifiers() | ui::EF_COMMAND_DOWN, + accelerator.key_state())}; + } else { + // Otherwise if `top_row_are_fkeys` is false, the identity accelerator + // should be returned. + return {accelerator}; + } + } else { + // If its an external, the F-Key glyph should be shown. If + // `top_row_are_fkeys` is true, search must be added to convert the "F-Key" + // into the action key. Otherwise, the "F-Key" is implicitly the action key. + if (top_row_are_fkeys) { + return {ui::Accelerator(*function_key, + accelerator.modifiers() | ui::EF_COMMAND_DOWN, + accelerator.key_state())}; + } else { + return {ui::Accelerator(*function_key, accelerator.modifiers(), + accelerator.key_state())}; } } - - return std::vector<ui::Accelerator>(aliases_set.begin(), aliases_set.end()); } std::vector<ui::Accelerator> AcceleratorAliasConverter::CreateSixPackAliases( @@ -152,13 +223,45 @@ AcceleratorAliasConverter::FilterAliasBySupportedKeys( const std::vector<ui::Accelerator>& accelerators) const { std::vector<ui::Accelerator> filtered_accelerators; - std::copy_if( - accelerators.begin(), accelerators.end(), - std::back_inserter(filtered_accelerators), - [](const ui::Accelerator& accelerator) { - return Shell::Get()->keyboard_capability()->HasKeyEventOnAnyKeyboard( + auto priority_keyboard = GetPriorityKeyboard(); + + for (const auto& accelerator : accelerators) { + if (auto action_key = ui::KeyboardCapability::ConvertToTopRowActionKey( accelerator.key_code()); - }); + action_key.has_value()) { + if (priority_keyboard && + Shell::Get()->keyboard_capability()->HasTopRowActionKey( + *priority_keyboard, *action_key)) { + filtered_accelerators.push_back(accelerator); + } + continue; + } + + if (ui::KeyboardCapability::IsSixPackKey(accelerator.key_code())) { + if (ui::KeyboardCapability::HasSixPackOnAnyKeyboard()) { + filtered_accelerators.push_back(accelerator); + } + continue; + } + + if (accelerator.key_code() == ui::VKEY_ASSISTANT) { + if (ui::DeviceKeyboardHasAssistantKey()) { + filtered_accelerators.push_back(accelerator); + } + continue; + } + + if (accelerator.key_code() == ui::VKEY_MODECHANGE) { + if (Shell::Get()->keyboard_capability()->HasGlobeKeyOnAnyKeyboard()) { + filtered_accelerators.push_back(accelerator); + } + continue; + } + + // Otherwise, always copy the accelerator. + filtered_accelerators.push_back(accelerator); + } + return filtered_accelerators; }
diff --git a/ash/accelerators/accelerator_alias_converter_unittest.cc b/ash/accelerators/accelerator_alias_converter_unittest.cc index 01c1116..467e95b5 100644 --- a/ash/accelerators/accelerator_alias_converter_unittest.cc +++ b/ash/accelerators/accelerator_alias_converter_unittest.cc
@@ -13,25 +13,21 @@ #include "ui/base/accelerators/accelerator.h" #include "ui/events/ash/keyboard_capability.h" #include "ui/events/devices/device_data_manager_test_api.h" +#include "ui/events/event_constants.h" +#include "ui/events/keycodes/keyboard_codes_posix.h" namespace ash { namespace { constexpr char kKbdTopRowPropertyName[] = "CROS_KEYBOARD_TOP_ROW_LAYOUT"; + +constexpr char kKbdTopRowLayoutUnspecified[] = ""; constexpr char kKbdTopRowLayout1Tag[] = "1"; constexpr char kKbdTopRowLayout2Tag[] = "2"; constexpr char kKbdTopRowLayoutWilcoTag[] = "3"; constexpr char kKbdTopRowLayoutDrallionTag[] = "4"; -ui::InputDeviceType INTERNAL = ui::InputDeviceType::INPUT_DEVICE_INTERNAL; -ui::InputDeviceType EXTERNAL_USB = ui::InputDeviceType::INPUT_DEVICE_USB; -ui::InputDeviceType EXTERNAL_BLUETOOTH = - ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH; -// For INPUT_DEVICE_UNKNOWN type, we treat it as external keyboard. -ui::InputDeviceType EXTERNAL_UNKNOWN = - ui::InputDeviceType::INPUT_DEVICE_UNKNOWN; - struct AcceleratorAliasConverterTestData { ui::Accelerator accelerator_; absl::optional<ui::Accelerator> expected_accelerator_; @@ -111,6 +107,34 @@ EXPECT_EQ(accelerator, accelerator_aliases[0]); } +TEST_F(AcceleratorAliasConverterTest, CheckGlobeKeyAlias) { + std::unique_ptr<FakeDeviceManager> fake_keyboard_manager_ = + std::make_unique<FakeDeviceManager>(); + ui::InputDevice fake_keyboard( + /*id=*/1, /*type=*/ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH, + /*name=*/kKbdTopRowLayout1Tag); + fake_keyboard.sys_path = base::FilePath("path"); + fake_keyboard_manager_->AddFakeKeyboard(fake_keyboard, kKbdTopRowLayout1Tag); + + AcceleratorAliasConverter accelerator_alias_converter_; + + const ui::Accelerator accelerator{ui::VKEY_MODECHANGE, ui::EF_NONE}; + std::vector<ui::Accelerator> accelerator_aliases = + accelerator_alias_converter_.CreateAcceleratorAlias(accelerator); + EXPECT_EQ(0u, accelerator_aliases.size()); + + ui::InputDevice wilco_keyboard( + /*id=*/2, /*type=*/ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + /*name=*/kKbdTopRowLayout1Tag); + wilco_keyboard.sys_path = base::FilePath("path2"); + fake_keyboard_manager_->AddFakeKeyboard(wilco_keyboard, + kKbdTopRowLayoutWilcoTag); + accelerator_aliases = + accelerator_alias_converter_.CreateAcceleratorAlias(accelerator); + EXPECT_EQ(1u, accelerator_aliases.size()); + EXPECT_EQ(accelerator, accelerator_aliases[0]); +} + class TopRowAliasTest : public AcceleratorAliasConverterTest, public testing::WithParamInterface< TopRowAcceleratorAliasConverterTestData> { @@ -142,30 +166,31 @@ testing::ValuesIn(std::vector<TopRowAcceleratorAliasConverterTestData>{ // [Search] as original modifier prevents remapping, regardless of // keyboard connection type. - {{INTERNAL}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayout1Tag}, ui::Accelerator{ui::VKEY_ZOOM, ui::EF_COMMAND_DOWN}, - {}}, + {ui::Accelerator{ui::VKEY_ZOOM, ui::EF_COMMAND_DOWN}}}, // key_code not as a top row key prevents remapping, regardless of // keyboard connection type. - {{INTERNAL, EXTERNAL_USB}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + ui::InputDeviceType::INPUT_DEVICE_USB}, {kKbdTopRowLayout1Tag, kKbdTopRowLayout2Tag}, ui::Accelerator{ui::VKEY_TAB, ui::EF_ALT_DOWN}, - {}}, + {ui::Accelerator{ui::VKEY_TAB, ui::EF_ALT_DOWN}}}, // Below are testing each layout type. // For TopRowLayout1: [Alt] + [Back] -> [Alt] + [Search] + [F1]. // TopRowKeysAreFKeys() remains true. This statement applies to all // tests in TopRowAliasTest class. - {{EXTERNAL_USB}, - {kKbdTopRowLayout1Tag}, + {{ui::InputDeviceType::INPUT_DEVICE_USB}, + {kKbdTopRowLayoutUnspecified}, ui::Accelerator{ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN}, {ui::Accelerator{ui::VKEY_F1, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, // For internal keyboard only, we shows icon + meta. - {{INTERNAL}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayout1Tag}, ui::Accelerator{ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN}, {ui::Accelerator{ui::VKEY_BROWSER_BACK, @@ -173,186 +198,121 @@ // For internal keyboard only, layout1 doesn't have // VKEY_MEDIA_PLAY_PAUSE key. - {{INTERNAL}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayout1Tag}, ui::Accelerator{ui::VKEY_MEDIA_PLAY_PAUSE, ui::EF_ALT_DOWN}, {}}, - // For internal keyboard only, layout2 doesn't have VKEY_BROWSER_FORWARD - // key. - {{INTERNAL}, + // For internal keyboard only, layout2 doesn't have + // VKEY_BROWSER_FORWARD key. + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayout2Tag}, ui::Accelerator{ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN}, {}}, // Layout2 doesn't have VKEY_ALL_APPLICATIONS key. - {{INTERNAL}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayout2Tag}, ui::Accelerator{ui::VKEY_ALL_APPLICATIONS, ui::EF_ALT_DOWN}, {}}, // Layout1 doesn't have VKEY_SNAPSHOT key. - {{EXTERNAL_BLUETOOTH}, + {{ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH}, {kKbdTopRowLayout1Tag}, ui::Accelerator{ui::VKEY_SNAPSHOT, ui::EF_ALT_DOWN}, {}}, // LayoutWilco doesn't have VKEY_MICROPHONE_MUTE_TOGGLE key. - {{EXTERNAL_USB}, + {{ui::InputDeviceType::INPUT_DEVICE_USB}, {kKbdTopRowLayoutWilcoTag}, ui::Accelerator{ui::VKEY_MICROPHONE_MUTE_TOGGLE, ui::EF_ALT_DOWN}, {}}, // For TopRowLayout1: [Alt] + [Forward] -> [Alt] + [Search] + [F2]. - {{EXTERNAL_BLUETOOTH}, - {kKbdTopRowLayout1Tag}, + {{ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH}, + {kKbdTopRowLayoutUnspecified}, ui::Accelerator{ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN}, {ui::Accelerator{ui::VKEY_F2, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, // For TopRowLayout1: [Alt] + [Zoom] -> [Alt] + [Search] + [F4]. - {{EXTERNAL_USB}, - {kKbdTopRowLayout1Tag}, + {{ui::InputDeviceType::INPUT_DEVICE_USB}, + {kKbdTopRowLayoutUnspecified}, ui::Accelerator{ui::VKEY_ZOOM, ui::EF_ALT_DOWN}, {ui::Accelerator{ui::VKEY_F4, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, // For TopRowLayout2: [Alt] + [Shift] + [Back] -> [Alt] + [Shift] + - // [Search] + [F1]. - {{EXTERNAL_UNKNOWN}, + // [Search] + [Back]. + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayout2Tag}, ui::Accelerator{ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN}, - {ui::Accelerator{ui::VKEY_F1, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | - ui::EF_SHIFT_DOWN}}}, + {ui::Accelerator{ui::VKEY_BROWSER_BACK, ui::EF_COMMAND_DOWN | + ui::EF_ALT_DOWN | + ui::EF_SHIFT_DOWN}}}, // For TopRowLayout2: [Alt] + [Zoom] -> [Alt] + [Search] + [F3]. - {{EXTERNAL_BLUETOOTH}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayout2Tag}, ui::Accelerator{ui::VKEY_ZOOM, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F3, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, + {ui::Accelerator{ui::VKEY_ZOOM, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, // For TopRowLayout2: [Alt] + [Pause] -> [Alt] + [Search] + [F7]. - {{EXTERNAL_USB}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayout2Tag}, ui::Accelerator{ui::VKEY_MEDIA_PLAY_PAUSE, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F7, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, + {ui::Accelerator{ui::VKEY_MEDIA_PLAY_PAUSE, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, // For TopRowLayoutWilco: [Alt] + [Zoom] -> [Alt] + [Search] + [F3]. - {{EXTERNAL_UNKNOWN}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayoutWilcoTag}, ui::Accelerator{ui::VKEY_ZOOM, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F3, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, + {ui::Accelerator{ui::VKEY_ZOOM, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, // For TopRowLayoutWilco: [Alt] + [VolumeUp] -> [Alt] + [Search] + [F9]. - {{EXTERNAL_BLUETOOTH}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayoutWilcoTag}, ui::Accelerator{ui::VKEY_VOLUME_UP, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F9, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, + {ui::Accelerator{ui::VKEY_VOLUME_UP, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, // For kKbdTopRowLayoutDrallionTag: [Alt] + [Mute] -> [Alt] + [Search] + // [F7]. - {{EXTERNAL_USB}, + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, {kKbdTopRowLayoutDrallionTag}, ui::Accelerator{ui::VKEY_VOLUME_MUTE, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F7, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, + {ui::Accelerator{ui::VKEY_VOLUME_MUTE, + ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - // Below are testing multiple connected keyboards. + // Aliasing should be for the most recently connected external keyboard + // (last item in the list). + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH, + ui::InputDeviceType::INPUT_DEVICE_USB}, + {kKbdTopRowLayout1Tag, kKbdTopRowLayoutUnspecified, + kKbdTopRowLayout2Tag}, + ui::Accelerator{ui::VKEY_MEDIA_PLAY_PAUSE, ui::EF_NONE}, + {ui::Accelerator{ui::VKEY_MEDIA_PLAY_PAUSE, ui::EF_COMMAND_DOWN}}}, - // Two keyboards with the same layout type: [Alt] + [Forward] -> [Alt] + - // [Search] + [F2]. No duplicated alias exists. - {{EXTERNAL_BLUETOOTH, EXTERNAL_USB}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout1Tag}, - ui::Accelerator{ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F2, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - - // Two keyboards with the same layout type. Both do not have - // VKEY_MEDIA_PLAY_PAUSE key. - {{EXTERNAL_BLUETOOTH, EXTERNAL_USB}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout1Tag}, - ui::Accelerator{ui::VKEY_MEDIA_PLAY_PAUSE, ui::EF_ALT_DOWN}, + // Since the external keyboard uses Layout1 by default, it does not have + // play/pause which means there should be no mapped accelerator. + {{ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + ui::InputDeviceType::INPUT_DEVICE_USB}, + {kKbdTopRowLayout2Tag, kKbdTopRowLayoutUnspecified}, + ui::Accelerator{ui::VKEY_MEDIA_PLAY_PAUSE, ui::EF_NONE}, {}}, - // Both internal and external keyboards exists, we show both variations. - {{INTERNAL, EXTERNAL_USB}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout1Tag}, - ui::Accelerator{ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F2, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}, - ui::Accelerator{ui::VKEY_BROWSER_FORWARD, - ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - - // For TopRowLayout1 + TopRowLayout2: [Alt] + [Forward] -> [Alt] + - // [Search] + [F2]. Only layout1 has [Forward] key. - {{EXTERNAL_BLUETOOTH, EXTERNAL_USB, INTERNAL}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout2Tag, kKbdTopRowLayout2Tag}, - ui::Accelerator{ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F2, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - - // For internal keyboard, we show icon + meta. No duplicated alias - // exists. - {{INTERNAL, INTERNAL}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout2Tag}, - ui::Accelerator{ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_BROWSER_FORWARD, - ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - - // For TopRowLayout1 + TopRowLayout2: [Alt] + [Refresh] -> [Alt] + - // [Search] + [F2] AND [Alt] + [Search] + [F3]. Layout1's [Refresh] key - // maps to [F3], while layout2 maps to [F2]. - {{EXTERNAL_USB, EXTERNAL_UNKNOWN}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout2Tag}, - ui::Accelerator{ui::VKEY_BROWSER_REFRESH, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F2, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}, - ui::Accelerator{ui::VKEY_F3, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - - // Internal keyboard shows icon + meta, external keyboard shows F-key + - // meta. - {{INTERNAL, EXTERNAL_USB}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout2Tag}, - ui::Accelerator{ui::VKEY_BROWSER_REFRESH, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F2, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}, - ui::Accelerator{ui::VKEY_BROWSER_REFRESH, - ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - - // For TopRowLayout1 + TopRowLayout2: [Alt] + [VolumeUp] -> [Alt] + - // [Search] + [F10]. Both layout1 and layout2' [VolumeUp] key maps to - // [F10]. No duplicated alias exists. - {{INTERNAL, EXTERNAL_USB, EXTERNAL_BLUETOOTH}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout2Tag}, - ui::Accelerator{ui::VKEY_VOLUME_UP, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F10, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}, - ui::Accelerator{ui::VKEY_VOLUME_UP, - ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - - // For TopRowLayout1 + TopRowLayout2 + TopRowLayoutWilco: [Alt] + [Back] - // -> [Alt] + [Search] + [F1]. All layouts' [Back] key maps to [F1]. No - // duplicated alias exists. - {{EXTERNAL_USB, EXTERNAL_BLUETOOTH, EXTERNAL_UNKNOWN}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout2Tag, kKbdTopRowLayoutWilcoTag}, - ui::Accelerator{ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F1, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - - // For TopRowLayout1 + TopRowLayout2 + TopRowLayoutWilco: [Alt] + [Zoom] - // -> [Alt] + [Search] + [F3] AND [Alt] + [Search] + [F4]. - {{INTERNAL, EXTERNAL_USB, EXTERNAL_USB, EXTERNAL_USB}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout1Tag, kKbdTopRowLayout2Tag, - kKbdTopRowLayoutWilcoTag}, - ui::Accelerator{ui::VKEY_ZOOM, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F3, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}, - ui::Accelerator{ui::VKEY_F4, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}, - ui::Accelerator{ui::VKEY_ZOOM, - ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, - - // For TopRowLayout1 + TopRowLayout2 + TopRowLayoutWilco + - // TopRowLayoutDrallion: [Alt] + [Launch] -> [Alt] + [Search] + [F4] AND - // [Alt] + [Search] + [F5]. - {{INTERNAL, EXTERNAL_BLUETOOTH, EXTERNAL_BLUETOOTH, EXTERNAL_BLUETOOTH, - EXTERNAL_BLUETOOTH}, - {kKbdTopRowLayout1Tag, kKbdTopRowLayout1Tag, kKbdTopRowLayout2Tag, - kKbdTopRowLayoutWilcoTag, kKbdTopRowLayoutDrallionTag}, - ui::Accelerator{ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_ALT_DOWN}, - {ui::Accelerator{ui::VKEY_F4, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}, - ui::Accelerator{ui::VKEY_F5, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}, - ui::Accelerator{ui::VKEY_MEDIA_LAUNCH_APP1, - ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN}}}, + // Since the external keyboard uses Layout1 by default, it does not have + // play/pause which means there should be no mapped accelerator. + // Eventhough the internal keyboard is listed last, the external + // keyboard should still be used for aliasing. + {{ui::InputDeviceType::INPUT_DEVICE_USB, + ui::InputDeviceType::INPUT_DEVICE_INTERNAL}, + {kKbdTopRowLayoutUnspecified, kKbdTopRowLayout2Tag}, + ui::Accelerator{ui::VKEY_MEDIA_PLAY_PAUSE, ui::EF_NONE}, + {}}, })); TEST_P(TopRowAliasTest, CheckTopRowAlias) { @@ -372,14 +332,10 @@ std::vector<ui::Accelerator> accelerator_alias = accelerator_alias_converter_.CreateAcceleratorAlias(accelerator_); - EXPECT_TRUE(Shell::Get()->keyboard_capability()->TopRowKeysAreFKeys()); - if (expected_accelerator_.size() > 0) { - EXPECT_EQ(expected_accelerator_.size(), accelerator_alias.size()); - for (size_t i = 0; i < expected_accelerator_.size(); i++) { - EXPECT_EQ(expected_accelerator_[i], accelerator_alias[i]); - } - } else if (accelerator_alias.size() > 0) { - EXPECT_EQ(accelerator_, accelerator_alias[0]); + ASSERT_TRUE(Shell::Get()->keyboard_capability()->TopRowKeysAreFKeys()); + ASSERT_EQ(expected_accelerator_.size(), accelerator_alias.size()); + for (size_t i = 0; i < expected_accelerator_.size(); i++) { + EXPECT_EQ(expected_accelerator_[i], accelerator_alias[i]); } } @@ -473,7 +429,7 @@ } else { // Accelerator doesn't have a valid remapping. EXPECT_EQ(1u, accelerator_alias.size()); - EXPECT_EQ(accelerator_, accelerator_alias[0]); + ASSERT_EQ(accelerator_, accelerator_alias[0]); } }
diff --git a/ash/app_list/views/app_list_view_pixeltest.cc b/ash/app_list/views/app_list_view_pixeltest.cc index a6b924593..c592451 100644 --- a/ash/app_list/views/app_list_view_pixeltest.cc +++ b/ash/app_list/views/app_list_view_pixeltest.cc
@@ -367,36 +367,14 @@ "search_box_view_active", /*revision_number=*/0, search_box_view)); } -class AppListViewAssistantZeroStateParams { - public: - AppListViewAssistantZeroStateParams(bool rtl, bool dark_theme) - : rtl_(rtl), dark_theme_(dark_theme) {} - - static std::string ToTestSuffix( - const testing::TestParamInfo<AppListViewAssistantZeroStateParams>& info) { - std::string suffix; - suffix.append(info.param.rtl() ? "rtl" : "ltr"); - suffix.append("_"); - suffix.append(info.param.dark_theme() ? "dark" : "light"); - return suffix; - } - - bool rtl() const { return rtl_; } - bool dark_theme() const { return dark_theme_; } - - private: - bool rtl_; - bool dark_theme_; -}; - class AppListViewAssistantZeroStateTest : public AssistantAshTestBase, - public testing::WithParamInterface<AppListViewAssistantZeroStateParams> { + public testing::WithParamInterface<TestVariantsParam> { public: absl::optional<pixel_test::InitParams> CreatePixelTestInitParams() const override { pixel_test::InitParams init_params; - init_params.under_rtl = GetParam().rtl(); + init_params.under_rtl = IsRtl(GetParam()); return init_params; } @@ -408,19 +386,19 @@ SetNumberOfSessionsWhereOnboardingShown( assistant::ui::kOnboardingMaxSessionsShown); DarkLightModeController::Get()->SetDarkModeEnabledForTest( - GetParam().dark_theme()); + IsDarkMode(GetParam())); + Shell::Get()->tablet_mode_controller()->SetEnabledForTest( + IsTabletMode(GetParam())); ShowAssistantUi(); } }; -INSTANTIATE_TEST_SUITE_P( - RTL, - AppListViewAssistantZeroStateTest, - testing::Values(AppListViewAssistantZeroStateParams(false, false), - AppListViewAssistantZeroStateParams(false, true), - AppListViewAssistantZeroStateParams(true, false), - AppListViewAssistantZeroStateParams(true, true)), - &AppListViewAssistantZeroStateParams::ToTestSuffix); +INSTANTIATE_TEST_SUITE_P(RTL, + AppListViewAssistantZeroStateTest, + testing::Combine(/*IsRtl=*/testing::Bool(), + /*IsDarkMode=*/testing::Bool(), + /*IsTabletMode=*/testing::Bool()), + &GenerateTestSuffix); TEST_P(AppListViewAssistantZeroStateTest, Basic) { // Wait layout.
diff --git a/ash/app_list/views/continue_section_view.cc b/ash/app_list/views/continue_section_view.cc index d937270..2c15983 100644 --- a/ash/app_list/views/continue_section_view.cc +++ b/ash/app_list/views/continue_section_view.cc
@@ -168,7 +168,7 @@ return false; } - return HasMinimumFilesToShow() && + return (HasDesksAdminTemplates() || HasMinimumFilesToShow()) && !(nudge_controller_->IsPrivacyNoticeAccepted() || nudge_controller_->WasPrivacyNoticeShown()); }
diff --git a/ash/app_list/views/continue_section_view_unittest.cc b/ash/app_list/views/continue_section_view_unittest.cc index 326bcf2..38232f4 100644 --- a/ash/app_list/views/continue_section_view_unittest.cc +++ b/ash/app_list/views/continue_section_view_unittest.cc
@@ -25,6 +25,7 @@ #include "ash/app_list/views/recent_apps_view.h" #include "ash/app_list/views/scrollable_apps_grid_view.h" #include "ash/app_list/views/search_box_view.h" +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/app_list/app_list_types.h" #include "ash/session/session_controller_impl.h" @@ -32,6 +33,7 @@ #include "ash/test/ash_test_base.h" #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -382,6 +384,22 @@ EXPECT_EQ(GetResultViewAt(2)->result()->id(), "id3"); } +// Tests that the continue section view will be visible once we have a admin +// template. +TEST_P(ContinueSectionViewTest, ShowContinueSectionWhenAdminTemplateAvailable) { + base::test::ScopedFeatureList scoped_list; + scoped_list.InitAndEnableFeature(features::kAppLaunchAutomation); + + AddSearchResult("id", AppListSearchResultType::kDesksAdminTemplate); + + EnsureLauncherShown(); + VerifyResultViewsUpdated(); + + ContinueSectionView* view = GetContinueSectionView(); + ASSERT_EQ(view->GetTasksSuggestionsCount(), 1u); + EXPECT_TRUE(GetContinueSectionView()->GetVisible()); +} + TEST_P(ContinueSectionViewTest, ShowsHelpAppResults) { AddSearchResult("id1", AppListSearchResultType::kZeroStateHelpApp); AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index bafa81f..7b8f37d 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -2015,6 +2015,12 @@ "SmartLockUIRevamp", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kSmdsSupport, "SmdsSupport", base::FEATURE_DISABLED_BY_DEFAULT); + +BASE_FEATURE(kSmdsSupportEuiccUpload, + "SmdsSupportEuiccUpload", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kSmdsDbusMigration, "SmdsDbusMigration", base::FEATURE_DISABLED_BY_DEFAULT); @@ -3159,7 +3165,9 @@ } bool IsPrivacyIndicatorsEnabled() { - return base::FeatureList::IsEnabled(kPrivacyIndicators); + // Privacy indicators should not be enabled when video conference is enabled. + return base::FeatureList::IsEnabled(kPrivacyIndicators) && + !IsVideoConferenceEnabled(); } bool IsProductivityLauncherEnabled() { @@ -3302,6 +3310,17 @@ return base::FeatureList::IsEnabled(kShimlessRMADiagnosticPage); } +bool IsSmdsSupportEnabled() { + return base::FeatureList::IsEnabled(kSmdsDbusMigration) && + base::FeatureList::IsEnabled(kSmdsSupport); +} + +bool IsSmdsSupportEuiccUploadEnabled() { + return base::FeatureList::IsEnabled(kSmdsDbusMigration) && + base::FeatureList::IsEnabled(kSmdsSupport) && + base::FeatureList::IsEnabled(kSmdsSupportEuiccUpload); +} + bool IsSmdsDbusMigrationEnabled() { return base::FeatureList::IsEnabled(kSmdsDbusMigration); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 6178851b2..4312489b 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -575,6 +575,8 @@ BASE_DECLARE_FEATURE(kSmartDimExperimentalComponent); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSmartLockSignInRemoved); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSmartLockUIRevamp); +COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSmdsSupport); +COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSmdsSupportEuiccUpload); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSmdsDbusMigration); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSnapGroup); COMPONENT_EXPORT(ASH_CONSTANTS) @@ -904,6 +906,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsShimlessRMAOsUpdateEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsShimlessRMADarkModeDisabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSmartReaderEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSmdsSupportEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSmdsSupportEuiccUploadEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSmdsDbusMigrationEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSnoopingProtectionEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSnapGroupEnabled();
diff --git a/ash/events/keyboard_capability_unittest.cc b/ash/events/keyboard_capability_unittest.cc index 01ec885..0d2c1201 100644 --- a/ash/events/keyboard_capability_unittest.cc +++ b/ash/events/keyboard_capability_unittest.cc
@@ -12,6 +12,8 @@ #include "ash/test/ash_test_base.h" #include "base/files/file_path.h" #include "base/ranges/algorithm.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "components/prefs/pref_service.h" #include "device/udev_linux/fake_udev_loader.h" #include "ui/events/ash/mojom/modifier_key.mojom-shared.h" @@ -46,6 +48,28 @@ // A tag that should fail parsing for the top row custom scan code string. constexpr char kKbdInvalidCustomTopRowLayout[] = "X X X"; +enum CustomTopRowScanCode : uint32_t { + kPreviousTrack = 0x90, + kFullscreen = 0x91, + kOverview = 0x92, + kScreenshot = 0x93, + kScreenBrightnessDown = 0x94, + kScreenBrightnessUp = 0x95, + kPrivacyScreenToggle = 0x96, + kKeyboardBacklightDown = 0x97, + kKeyboardBacklightUp = 0x98, + kNextTrack = 0x99, + kPlayPause = 0x9A, + kMicrophoneMute = 0x9B, + kKeyboardBacklightToggle = 0x9E, + kVolumeMute = 0xA0, + kVolumeDown = 0xAE, + kVolumeUp = 0xB0, + kForward = 0xE9, + kBack = 0xEA, + kRefresh = 0xE7, +}; + constexpr int kDeviceId1 = 5; constexpr int kDeviceId2 = 10; @@ -390,6 +414,58 @@ EXPECT_FALSE(keyboard_capability_->IsTopRowKey(ui::KeyboardCode::VKEY_A)); } +TEST_F(KeyboardCapabilityTest, TestHasGlobeKey) { + ui::InputDevice external_keyboard( + /*id=*/1, /*type=*/ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH, + /*name=*/"Keyboard1"); + external_keyboard.sys_path = base::FilePath("path1"); + fake_keyboard_manager_->AddFakeKeyboard(external_keyboard, + kKbdTopRowLayoutUnspecified); + EXPECT_FALSE(keyboard_capability_->HasGlobeKey(external_keyboard)); + + ui::InputDevice internal_keyboard_layout1( + /*id=*/2, /*type=*/ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH, + /*name=*/"Keyboard2"); + internal_keyboard_layout1.sys_path = base::FilePath("path1"); + fake_keyboard_manager_->AddFakeKeyboard(internal_keyboard_layout1, + kKbdTopRowLayout1Tag); + EXPECT_FALSE(keyboard_capability_->HasGlobeKey(internal_keyboard_layout1)); + + ui::InputDevice internal_keyboard_layout2( + /*id=*/3, /*type=*/ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH, + /*name=*/"Keyboard3"); + internal_keyboard_layout2.sys_path = base::FilePath("path1"); + fake_keyboard_manager_->AddFakeKeyboard(internal_keyboard_layout2, + kKbdTopRowLayout2Tag); + EXPECT_FALSE(keyboard_capability_->HasGlobeKey(internal_keyboard_layout2)); + + ui::InputDevice internal_keyboard_layout_custom( + /*id=*/4, /*type=*/ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH, + /*name=*/"Keyboard4"); + internal_keyboard_layout_custom.sys_path = base::FilePath("path1"); + fake_keyboard_manager_->AddFakeKeyboard(internal_keyboard_layout_custom, + kKbdDefaultCustomTopRowLayout, + /*has_custom_top_row=*/true); + EXPECT_FALSE( + keyboard_capability_->HasGlobeKey(internal_keyboard_layout_custom)); + + ui::InputDevice internal_keyboard_wilco( + /*id=*/5, /*type=*/ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH, + /*name=*/"Keyboard5"); + internal_keyboard_wilco.sys_path = base::FilePath("path1"); + fake_keyboard_manager_->AddFakeKeyboard(internal_keyboard_wilco, + kKbdTopRowLayoutWilcoTag); + EXPECT_TRUE(keyboard_capability_->HasGlobeKey(internal_keyboard_wilco)); + + ui::InputDevice internal_keyboard_drallion( + /*id=*/6, /*type=*/ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH, + /*name=*/"Keyboard6"); + internal_keyboard_drallion.sys_path = base::FilePath("path1"); + fake_keyboard_manager_->AddFakeKeyboard(internal_keyboard_drallion, + kKbdTopRowLayoutDrallionTag); + EXPECT_TRUE(keyboard_capability_->HasGlobeKey(internal_keyboard_drallion)); +} + class ModifierKeyTest : public KeyboardCapabilityTest, public testing::WithParamInterface< std::tuple<ui::DeviceCapabilities, @@ -714,6 +790,14 @@ keyboard_capability_->HasTopRowActionKey(input_device, action_key)) << "Action Key: " << static_cast<int>(action_key); } + + ui::KeyboardCode expected_fkey = ui::VKEY_F1; + for (const auto action_key : ui::kLayout1TopRowActionKeys) { + EXPECT_EQ(expected_fkey, keyboard_capability_->GetCorrespondingFunctionKey( + input_device, action_key)); + expected_fkey = + static_cast<ui::KeyboardCode>(static_cast<int>(expected_fkey) + 1); + } } TEST_F(KeyboardCapabilityTest, TopRowLayout2) { @@ -731,6 +815,14 @@ keyboard_capability_->HasTopRowActionKey(input_device, action_key)) << "Action Key: " << static_cast<int>(action_key); } + + ui::KeyboardCode expected_fkey = ui::VKEY_F1; + for (const auto action_key : ui::kLayout2TopRowActionKeys) { + EXPECT_EQ(expected_fkey, keyboard_capability_->GetCorrespondingFunctionKey( + input_device, action_key)); + expected_fkey = + static_cast<ui::KeyboardCode>(static_cast<int>(expected_fkey) + 1); + } } TEST_F(KeyboardCapabilityTest, TopRowLayoutWilco) { @@ -739,7 +831,7 @@ fake_keyboard_manager_->AddFakeKeyboard(wilco_device, kKbdTopRowLayoutWilcoTag, /*has_custom_top_row=*/false); - ui::InputDevice drallion_device(kDeviceId1, ui::INPUT_DEVICE_INTERNAL, + ui::InputDevice drallion_device(kDeviceId2, ui::INPUT_DEVICE_INTERNAL, "Internal Keyboard"); fake_keyboard_manager_->AddFakeKeyboard(drallion_device, kKbdTopRowLayoutDrallionTag, @@ -758,6 +850,163 @@ keyboard_capability_->HasTopRowActionKey(drallion_device, action_key)) << "Action Key: " << static_cast<int>(action_key); } + + ui::KeyboardCode expected_fkey = ui::VKEY_F1; + for (const auto action_key : ui::kLayoutWilcoDrallionTopRowActionKeys) { + EXPECT_EQ(expected_fkey, keyboard_capability_->GetCorrespondingFunctionKey( + wilco_device, action_key)); + EXPECT_EQ(expected_fkey, keyboard_capability_->GetCorrespondingFunctionKey( + drallion_device, action_key)); + expected_fkey = + static_cast<ui::KeyboardCode>(static_cast<int>(expected_fkey) + 1); + } +} + +class TopRowLayoutCustomTest + : public KeyboardCapabilityTest, + public testing::WithParamInterface<std::vector<ui::TopRowActionKey>> { + public: + void SetUp() override { + KeyboardCapabilityTest::SetUp(); + top_row_action_keys_ = GetParam(); + custom_layout_string_.clear(); + + std::vector<std::string> custom_scan_codes; + custom_scan_codes.reserve(top_row_action_keys_.size()); + for (const auto& action_key : top_row_action_keys_) { + const uint32_t scan_code = ConvertTopRowActionKeyToScanCode(action_key); + custom_scan_codes.push_back( + base::ToLowerASCII(base::HexEncode(&scan_code, 1))); + } + + custom_layout_string_ = base::JoinString(custom_scan_codes, " "); + } + + uint32_t ConvertTopRowActionKeyToScanCode(ui::TopRowActionKey action_key) { + switch (action_key) { + case ui::TopRowActionKey::kBack: + return CustomTopRowScanCode::kBack; + case ui::TopRowActionKey::kForward: + return CustomTopRowScanCode::kForward; + case ui::TopRowActionKey::kRefresh: + return CustomTopRowScanCode::kRefresh; + case ui::TopRowActionKey::kFullscreen: + return CustomTopRowScanCode::kFullscreen; + case ui::TopRowActionKey::kOverview: + return CustomTopRowScanCode::kOverview; + case ui::TopRowActionKey::kScreenshot: + return CustomTopRowScanCode::kScreenshot; + case ui::TopRowActionKey::kScreenBrightnessDown: + return CustomTopRowScanCode::kScreenBrightnessDown; + case ui::TopRowActionKey::kScreenBrightnessUp: + return CustomTopRowScanCode::kScreenBrightnessUp; + case ui::TopRowActionKey::kMicrophoneMute: + return CustomTopRowScanCode::kMicrophoneMute; + case ui::TopRowActionKey::kVolumeMute: + return CustomTopRowScanCode::kVolumeMute; + case ui::TopRowActionKey::kVolumeDown: + return CustomTopRowScanCode::kVolumeDown; + case ui::TopRowActionKey::kVolumeUp: + return CustomTopRowScanCode::kVolumeUp; + case ui::TopRowActionKey::kKeyboardBacklightToggle: + return CustomTopRowScanCode::kKeyboardBacklightToggle; + case ui::TopRowActionKey::kKeyboardBacklightDown: + return CustomTopRowScanCode::kKeyboardBacklightDown; + case ui::TopRowActionKey::kKeyboardBacklightUp: + return CustomTopRowScanCode::kKeyboardBacklightUp; + case ui::TopRowActionKey::kNextTrack: + return CustomTopRowScanCode::kNextTrack; + case ui::TopRowActionKey::kPreviousTrack: + return CustomTopRowScanCode::kPreviousTrack; + case ui::TopRowActionKey::kPlayPause: + return CustomTopRowScanCode::kPlayPause; + case ui::TopRowActionKey::kLauncher: + case ui::TopRowActionKey::kUnknown: + case ui::TopRowActionKey::kNone: + return 0; + } + } + + protected: + std::vector<ui::TopRowActionKey> top_row_action_keys_; + std::string custom_layout_string_; +}; + +INSTANTIATE_TEST_SUITE_P( + All, + TopRowLayoutCustomTest, + testing::ValuesIn(std::vector<std::vector<ui::TopRowActionKey>>{ + // Test with full 15 key set. + { + ui::TopRowActionKey::kBack, + ui::TopRowActionKey::kForward, + ui::TopRowActionKey::kRefresh, + ui::TopRowActionKey::kFullscreen, + ui::TopRowActionKey::kOverview, + ui::TopRowActionKey::kScreenshot, + ui::TopRowActionKey::kScreenBrightnessDown, + ui::TopRowActionKey::kScreenBrightnessUp, + ui::TopRowActionKey::kMicrophoneMute, + ui::TopRowActionKey::kVolumeMute, + ui::TopRowActionKey::kVolumeDown, + ui::TopRowActionKey::kVolumeUp, + ui::TopRowActionKey::kKeyboardBacklightToggle, + ui::TopRowActionKey::kKeyboardBacklightDown, + ui::TopRowActionKey::kKeyboardBacklightUp, + }, + // Test the remaining untested set of keys. + { + ui::TopRowActionKey::kOverview, + ui::TopRowActionKey::kScreenshot, + ui::TopRowActionKey::kScreenBrightnessDown, + ui::TopRowActionKey::kScreenBrightnessUp, + ui::TopRowActionKey::kMicrophoneMute, + ui::TopRowActionKey::kVolumeMute, + ui::TopRowActionKey::kVolumeDown, + ui::TopRowActionKey::kVolumeUp, + ui::TopRowActionKey::kKeyboardBacklightToggle, + ui::TopRowActionKey::kKeyboardBacklightDown, + ui::TopRowActionKey::kKeyboardBacklightUp, + ui::TopRowActionKey::kNextTrack, + ui::TopRowActionKey::kPreviousTrack, + ui::TopRowActionKey::kPlayPause, + }, + // Tests with a small subset of the possible keys. + { + ui::TopRowActionKey::kBack, + ui::TopRowActionKey::kForward, + ui::TopRowActionKey::kRefresh, + }, + { + ui::TopRowActionKey::kMicrophoneMute, + ui::TopRowActionKey::kVolumeMute, + ui::TopRowActionKey::kVolumeDown, + ui::TopRowActionKey::kVolumeUp, + ui::TopRowActionKey::kKeyboardBacklightToggle, + }})); + +TEST_P(TopRowLayoutCustomTest, TopRowLayout) { + ui::InputDevice keyboard(kDeviceId1, ui::INPUT_DEVICE_INTERNAL, + "Internal Keyboard"); + fake_keyboard_manager_->AddFakeKeyboard(keyboard, custom_layout_string_, + /*has_custom_top_row=*/true); + + for (ui::TopRowActionKey action_key = ui::TopRowActionKey::kMinValue; + action_key <= ui::TopRowActionKey::kMaxValue; + action_key = + static_cast<ui::TopRowActionKey>(static_cast<int>(action_key) + 1)) { + EXPECT_EQ(base::Contains(top_row_action_keys_, action_key), + keyboard_capability_->HasTopRowActionKey(keyboard, action_key)) + << "Action Key: " << static_cast<int>(action_key); + } + + ui::KeyboardCode expected_fkey = ui::VKEY_F1; + for (const auto action_key : top_row_action_keys_) { + EXPECT_EQ(expected_fkey, keyboard_capability_->GetCorrespondingFunctionKey( + keyboard, action_key)); + expected_fkey = + static_cast<ui::KeyboardCode>(static_cast<int>(expected_fkey) + 1); + } } } // namespace ash
diff --git a/ash/public/cpp/wallpaper/wallpaper_controller.h b/ash/public/cpp/wallpaper/wallpaper_controller.h index 2a54976..3509810 100644 --- a/ash/public/cpp/wallpaper/wallpaper_controller.h +++ b/ash/public/cpp/wallpaper/wallpaper_controller.h
@@ -244,16 +244,19 @@ // when using this method. virtual void ShowOneShotWallpaper(const gfx::ImageSkia& image) = 0; - // Shows a wallpaper that stays on top of everything except for the power off - // animation. All other wallpaper requests are ignored when the always-on-top - // wallpaper is being shown. + // Shows an override wallpaper instead of the wallpaper that would normally be + // shown. All other wallpaper requests are ignored when the override wallpaper + // is being shown. // |image_path|: The file path to read the image data from. - virtual void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) = 0; + // |always_on_top|: Whether the override wallpaper should be shown on top of + // everything except for the power off animation. + virtual void ShowOverrideWallpaper(const base::FilePath& image_path, + bool always_on_top) = 0; - // Removes the always-on-top wallpaper. The wallpaper will revert to the - // previous one, or a default one if there was none. No-op if the current - // wallpaper is not always-on-top. - virtual void RemoveAlwaysOnTopWallpaper() = 0; + // Removes the override wallpaper. The wallpaper will revert to the previous + // one, or a default one if there was none. No-op if the current wallpaper is + // not overridden. + virtual void RemoveOverrideWallpaper() = 0; // Removes all of the user's saved wallpapers and related info. // |account_id|: The user's account id.
diff --git a/ash/system/input_device_settings/input_device_settings_controller_impl.cc b/ash/system/input_device_settings/input_device_settings_controller_impl.cc index fbca23b1..e7144e9 100644 --- a/ash/system/input_device_settings/input_device_settings_controller_impl.cc +++ b/ash/system/input_device_settings/input_device_settings_controller_impl.cc
@@ -603,9 +603,11 @@ // TODO(dpad): Validate incoming settings to make sure the settings can // apply to the given device. auto& found_touchpad = *found_touchpad_iter->second; + const auto old_settings = std::move(found_touchpad.settings); found_touchpad.settings = settings.Clone(); touchpad_pref_handler_->UpdateTouchpadSettings(active_pref_service_, found_touchpad); + metrics_manager_->RecordTouchpadChangedMetrics(found_touchpad, *old_settings); DispatchTouchpadSettingsChanged(id); // Check the list of touchpads to see if any have the same |device_key|. // If so, their settings need to also be updated. @@ -634,9 +636,11 @@ RecordSetMouseSetttingsValidMetric(/*is_valid=*/true); auto& found_mouse = *found_mouse_iter->second; + const auto old_settings = std::move(found_mouse.settings); found_mouse.settings = settings.Clone(); mouse_pref_handler_->UpdateMouseSettings( active_pref_service_, policy_handler_->mouse_policies(), found_mouse); + metrics_manager_->RecordMouseChangedMetrics(found_mouse, *old_settings); DispatchMouseSettingsChanged(id); // Check the list of mice to see if any have the same |device_key|. // If so, their settings need to also be updated. @@ -664,9 +668,12 @@ RecordSetPointingStickSetttingsValidMetric(/*is_valid=*/true); auto& found_pointing_stick = *found_pointing_stick_iter->second; + const auto old_settings = std::move(found_pointing_stick.settings); found_pointing_stick.settings = settings.Clone(); pointing_stick_pref_handler_->UpdatePointingStickSettings( active_pref_service_, found_pointing_stick); + metrics_manager_->RecordPointingStickChangedMetrics(found_pointing_stick, + *old_settings); DispatchPointingStickSettingsChanged(id); // Check the list of pointing sticks to see if any have the same // |device_key|. If so, their settings need to also be updated.
diff --git a/ash/system/input_device_settings/input_device_settings_controller_unittest.cc b/ash/system/input_device_settings/input_device_settings_controller_unittest.cc index eb6ed3c2..d4cabe8 100644 --- a/ash/system/input_device_settings/input_device_settings_controller_unittest.cc +++ b/ash/system/input_device_settings/input_device_settings_controller_unittest.cc
@@ -67,8 +67,14 @@ 0x1111, 0x3333, 0}; -const ui::InputDevice kSampleTouchpadInternal = {1, ui::INPUT_DEVICE_INTERNAL, - "kSampleTouchpadInternal"}; +const ui::InputDevice kSampleTouchpadInternal = {1, + ui::INPUT_DEVICE_INTERNAL, + "kSampleTouchpadInternal", + "", + base::FilePath(), + 0x1111, + 0x4444, + 0}; const ui::InputDevice kSamplePointingStickInternal = { 2, ui::INPUT_DEVICE_INTERNAL, "kSamplePointingStickInternal"}; const ui::InputDevice kSampleMouseInternal = {3, ui::INPUT_DEVICE_INTERNAL, @@ -533,22 +539,8 @@ TEST_F(InputDeviceSettingsControllerTest, RecordsMetricsSettings) { // Initially expect no user preferences recorded. base::HistogramTester histogram_tester; - - // Metrics identifies different devices with device_key, which is constructed - // from vendor_id and product_id. - ui::InputDevice kKeyboardUsbWithDeviceKey = - ui::InputDevice(kSampleKeyboardUsb); - kKeyboardUsbWithDeviceKey.vendor_id = 0; - kKeyboardUsbWithDeviceKey.product_id = 0; - - ui::InputDevice kKeyboardBluetoothWithDeviceKey = - ui::InputDevice(kSampleKeyboardBluetooth); - kKeyboardBluetoothWithDeviceKey.vendor_id = 0; - kKeyboardBluetoothWithDeviceKey.product_id = 1; - - controller_->OnKeyboardListUpdated( - {kKeyboardUsbWithDeviceKey, kKeyboardBluetoothWithDeviceKey}, {}); - + controller_->OnKeyboardListUpdated({kSampleKeyboardUsb, kSampleKeyboardUsb2}, + {}); histogram_tester.ExpectTotalCount( "ChromeOS.Settings.Device.Keyboard.ExternalChromeOS.TopRowAreFKeys." "Initial", @@ -564,8 +556,7 @@ // Test Metrics Updates when setKeyboardSettings is called. auto updated_settings = mojom::KeyboardSettings::New(); updated_settings.get()->top_row_are_fkeys = true; - - controller_->SetKeyboardSettings(kKeyboardUsbWithDeviceKey.id, + controller_->SetKeyboardSettings(kSampleKeyboardUsb.id, std::move(updated_settings)); histogram_tester.ExpectTotalCount( "ChromeOS.Settings.Device.Keyboard.ExternalChromeOS.TopRowAreFKeys." @@ -575,6 +566,14 @@ "ChromeOS.Settings.Device.Keyboard.ExternalChromeOS." "BlockMetaFKeyRewrites.Changed", /*expected_count=*/0); + + // Test Metrics Updates when setTouchpadSettings is called. + controller_->OnTouchpadListUpdated({kSampleTouchpadInternal}, {}); + controller_->SetTouchpadSettings(kSampleTouchpadInternal.id, + mojom::TouchpadSettings::New()); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.Touchpad.Internal.AccelerationEnabled.Changed", + /*expected_count=*/1u); } TEST_F(InputDeviceSettingsControllerTest, GetGeneralizedTopRowAreFKeys) {
diff --git a/ash/system/input_device_settings/input_device_settings_metrics_manager.cc b/ash/system/input_device_settings/input_device_settings_metrics_manager.cc index 6fe93309..c1b3218 100644 --- a/ash/system/input_device_settings/input_device_settings_metrics_manager.cc +++ b/ash/system/input_device_settings/input_device_settings_metrics_manager.cc
@@ -118,6 +118,34 @@ // TODO(yyhyyh@): Add scroll settings metrics. } +void InputDeviceSettingsMetricsManager::RecordMouseChangedMetrics( + const mojom::Mouse& mouse, + const mojom::MouseSettings& old_settings) { + if (mouse.settings->acceleration_enabled != + old_settings.acceleration_enabled) { + base::UmaHistogramBoolean( + "ChromeOS.Settings.Device.Mouse.AccelerationEnabled.Changed", + mouse.settings->acceleration_enabled); + } + if (mouse.settings->reverse_scrolling != old_settings.reverse_scrolling) { + base::UmaHistogramBoolean( + "ChromeOS.Settings.Device.Mouse.ReverseScrolling.Changed", + mouse.settings->reverse_scrolling); + } + if (mouse.settings->sensitivity != old_settings.sensitivity) { + PointerSensitivity sensitivity = + static_cast<PointerSensitivity>(mouse.settings->sensitivity); + base::UmaHistogramEnumeration( + "ChromeOS.Settings.Device.Mouse.Sensitivity.Changed", sensitivity); + } + if (mouse.settings->swap_right != old_settings.swap_right) { + base::UmaHistogramBoolean( + "ChromeOS.Settings.Device.Mouse.SwapPrimaryButtons.Changed", + mouse.settings->swap_right); + } + // TODO(yyhyyh@): Add scroll settings metrics. +} + void InputDeviceSettingsMetricsManager::RecordPointingStickInitialMetrics( const mojom::PointingStick& pointing_stick) { // Only record the metrics once for each pointing stick. @@ -145,6 +173,29 @@ pointing_stick.settings->swap_right); } +void InputDeviceSettingsMetricsManager::RecordPointingStickChangedMetrics( + const mojom::PointingStick& pointing_stick, + const mojom::PointingStickSettings& old_settings) { + if (pointing_stick.settings->acceleration_enabled != + old_settings.acceleration_enabled) { + base::UmaHistogramBoolean( + "ChromeOS.Settings.Device.PointingStick.AccelerationEnabled.Changed", + pointing_stick.settings->acceleration_enabled); + } + if (pointing_stick.settings->sensitivity != old_settings.sensitivity) { + PointerSensitivity sensitivity = + static_cast<PointerSensitivity>(pointing_stick.settings->sensitivity); + base::UmaHistogramEnumeration( + "ChromeOS.Settings.Device.PointingStick.Sensitivity.Changed", + sensitivity); + } + if (pointing_stick.settings->swap_right != old_settings.swap_right) { + base::UmaHistogramBoolean( + "ChromeOS.Settings.Device.PointingStick.SwapPrimaryButtons.Changed", + pointing_stick.settings->swap_right); + } +} + void InputDeviceSettingsMetricsManager::RecordTouchpadInitialMetrics( const mojom::Touchpad& touchpad) { // Only record the metrics once for each Touchpad. @@ -179,4 +230,40 @@ // TODO(yyhyyh@): Add haptic settings metrics. } +void InputDeviceSettingsMetricsManager::RecordTouchpadChangedMetrics( + const mojom::Touchpad& touchpad, + const mojom::TouchpadSettings& old_settings) { + const std::string touchpad_metrics_prefix = + touchpad.is_external ? "ChromeOS.Settings.Device.Touchpad.External." + : "ChromeOS.Settings.Device.Touchpad.Internal."; + if (touchpad.settings->acceleration_enabled != + old_settings.acceleration_enabled) { + base::UmaHistogramBoolean( + touchpad_metrics_prefix + "AccelerationEnabled.Changed", + touchpad.settings->acceleration_enabled); + } + if (touchpad.settings->reverse_scrolling != old_settings.reverse_scrolling) { + base::UmaHistogramBoolean( + touchpad_metrics_prefix + "ReverseScrolling.Changed", + touchpad.settings->reverse_scrolling); + } + if (touchpad.settings->sensitivity != old_settings.sensitivity) { + PointerSensitivity sensitivity = + static_cast<PointerSensitivity>(touchpad.settings->sensitivity); + base::UmaHistogramEnumeration( + touchpad_metrics_prefix + "Sensitivity.Changed", sensitivity); + } + if (touchpad.settings->tap_dragging_enabled != + old_settings.tap_dragging_enabled) { + base::UmaHistogramBoolean(touchpad_metrics_prefix + "TapDragging.Changed", + touchpad.settings->tap_dragging_enabled); + } + if (touchpad.settings->tap_to_click_enabled != + old_settings.tap_to_click_enabled) { + base::UmaHistogramBoolean(touchpad_metrics_prefix + "TapToClick.Changed", + touchpad.settings->tap_to_click_enabled); + } + // TODO(yyhyyh@): Add haptic settings metrics. +} + } // namespace ash \ No newline at end of file
diff --git a/ash/system/input_device_settings/input_device_settings_metrics_manager.h b/ash/system/input_device_settings/input_device_settings_metrics_manager.h index 6086646..ef943d8 100644 --- a/ash/system/input_device_settings/input_device_settings_metrics_manager.h +++ b/ash/system/input_device_settings/input_device_settings_metrics_manager.h
@@ -27,9 +27,17 @@ const mojom::Keyboard& keyboard, const mojom::KeyboardSettings& old_settings); void RecordMouseInitialMetrics(const mojom::Mouse& mouse); + void RecordMouseChangedMetrics(const mojom::Mouse& mouse, + const mojom::MouseSettings& old_settings); void RecordPointingStickInitialMetrics( const mojom::PointingStick& pointingStick); + void RecordPointingStickChangedMetrics( + const mojom::PointingStick& pointing_stick, + const mojom::PointingStickSettings& old_settings); void RecordTouchpadInitialMetrics(const mojom::Touchpad& touchpad); + void RecordTouchpadChangedMetrics( + const mojom::Touchpad& touchpad, + const mojom::TouchpadSettings& old_settings); private: base::flat_map<AccountId, base::flat_set<std::string>> recorded_keyboards_;
diff --git a/ash/system/input_device_settings/input_device_settings_metrics_manager_unittest.cc b/ash/system/input_device_settings/input_device_settings_metrics_manager_unittest.cc index 23b9374..5edf2312 100644 --- a/ash/system/input_device_settings/input_device_settings_metrics_manager_unittest.cc +++ b/ash/system/input_device_settings/input_device_settings_metrics_manager_unittest.cc
@@ -19,6 +19,7 @@ constexpr char kPointingStickId[] = "test:pointingstick"; constexpr char kExternalTouchpadId[] = "test:touchpad-external"; constexpr int kSampleSensitivity = 3; +constexpr int kSampleMaxSensitivity = 5; constexpr char kUser1[] = "user1@gmail.com"; constexpr char kUser2[] = "user2@gmail.com"; @@ -205,6 +206,21 @@ histogram_tester.ExpectTotalCount( "ChromeOS.Settings.Device.Mouse.Sensitivity.Initial", /*expected_count=*/2u); + + // Call record changed settings metrics. + const auto old_setting = mouse.settings->Clone(); + mouse.settings->sensitivity = kSampleMaxSensitivity; + mouse.settings->reverse_scrolling = !mouse.settings->reverse_scrolling; + manager_.get()->RecordMouseChangedMetrics(mouse, *old_setting); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.Mouse.SwapPrimaryButtons.Changed", + /*expected_count=*/0); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.Mouse.Sensitivity.Changed", + /*expected_count=*/1u); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.Mouse.ReverseScrolling.Changed", + /*expected_count=*/1u); } TEST_F(InputDeviceSettingsMetricsManagerTest, RecordPointingStickSettings) { @@ -234,6 +250,22 @@ histogram_tester.ExpectTotalCount( "ChromeOS.Settings.Device.PointingStick.Sensitivity.Initial", /*expected_count=*/2u); + + // Call record changed settings metrics. + const auto old_setting = pointing_stick.settings->Clone(); + pointing_stick.settings->sensitivity = kSampleMaxSensitivity; + pointing_stick.settings->swap_right = !pointing_stick.settings->swap_right; + manager_.get()->RecordPointingStickChangedMetrics(pointing_stick, + *old_setting); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.PointingStick.AccelerationEnabled.Changed", + /*expected_count=*/0); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.PointingStick.Sensitivity.Changed", + /*expected_count=*/1u); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.PointingStick.SwapPrimaryButtons.Changed", + /*expected_count=*/1u); } TEST_F(InputDeviceSettingsMetricsManagerTest, RecordTouchpadSettings) { @@ -264,6 +296,32 @@ histogram_tester.ExpectTotalCount( "ChromeOS.Settings.Device.Touchpad.External.Sensitivity.Initial", /*expected_count=*/2u); + + // Call record changed settings metrics. + const auto old_setting = touchpad_external.settings->Clone(); + touchpad_external.settings->sensitivity = kSampleMaxSensitivity; + touchpad_external.settings->reverse_scrolling = + !touchpad_external.settings->reverse_scrolling; + touchpad_external.settings->tap_dragging_enabled = + !touchpad_external.settings->tap_dragging_enabled; + touchpad_external.settings->tap_to_click_enabled = + !touchpad_external.settings->tap_to_click_enabled; + manager_.get()->RecordTouchpadChangedMetrics(touchpad_external, *old_setting); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.Touchpad.External.AccelerationEnabled.Changed", + /*expected_count=*/0); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.Touchpad.External.ReverseScrolling.Changed", + /*expected_count=*/1u); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.Touchpad.External.Sensitivity.Changed", + /*expected_count=*/1u); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.Touchpad.External.TapDragging.Changed", + /*expected_count=*/1u); + histogram_tester.ExpectTotalCount( + "ChromeOS.Settings.Device.Touchpad.External.TapToClick.Changed", + /*expected_count=*/1u); } } // namespace ash \ No newline at end of file
diff --git a/ash/system/media/quick_settings_media_view.cc b/ash/system/media/quick_settings_media_view.cc index 5c0124a..ca9b84b 100644 --- a/ash/system/media/quick_settings_media_view.cc +++ b/ash/system/media/quick_settings_media_view.cc
@@ -171,4 +171,26 @@ controller_->SetShowMediaView(!items_.empty()); } +void QuickSettingsMediaView::UpdateItemOrder(std::list<std::string> ids) { + if (ids.empty()) { + return; + } + + // Remove all the media views for re-ordering. + std::map<const std::string, + std::unique_ptr<global_media_controls::MediaItemUIView>> + media_items; + for (auto& item : items_) { + media_items[item.first] = + media_scroll_view_->contents()->RemoveChildViewT(item.second); + } + + // Add back the media views given the new order. + for (auto& id : ids) { + DCHECK(base::Contains(media_items, id)); + items_[id] = media_scroll_view_->contents()->AddChildView( + std::move(media_items[id])); + } +} + } // namespace ash \ No newline at end of file
diff --git a/ash/system/media/quick_settings_media_view.h b/ash/system/media/quick_settings_media_view.h index beae7ae5..821a1cc 100644 --- a/ash/system/media/quick_settings_media_view.h +++ b/ash/system/media/quick_settings_media_view.h
@@ -5,6 +5,7 @@ #ifndef ASH_SYSTEM_MEDIA_QUICK_SETTINGS_MEDIA_VIEW_H_ #define ASH_SYSTEM_MEDIA_QUICK_SETTINGS_MEDIA_VIEW_H_ +#include <list> #include <map> #include "ash/ash_export.h" @@ -45,6 +46,9 @@ // Removes the given media item from the media view. void HideItem(const std::string& id); + // Updates the media item order given the id order in the list. + void UpdateItemOrder(std::list<std::string> ids); + private: raw_ptr<QuickSettingsMediaViewController> controller_ = nullptr;
diff --git a/ash/system/media/quick_settings_media_view_container.cc b/ash/system/media/quick_settings_media_view_container.cc index 083226c..a15a9d1 100644 --- a/ash/system/media/quick_settings_media_view_container.cc +++ b/ash/system/media/quick_settings_media_view_container.cc
@@ -4,7 +4,9 @@ #include "ash/system/media/quick_settings_media_view_container.h" +#include "ash/system/media/quick_settings_media_view_controller.h" #include "ash/system/tray/tray_constants.h" +#include "ash/system/unified/unified_system_tray_controller.h" #include "ui/views/layout/fill_layout.h" namespace ash { @@ -13,7 +15,9 @@ constexpr int kContainerHeight = 150; } // namespace -QuickSettingsMediaViewContainer::QuickSettingsMediaViewContainer() { +QuickSettingsMediaViewContainer::QuickSettingsMediaViewContainer( + UnifiedSystemTrayController* controller) + : controller_(controller) { SetLayoutManager(std::make_unique<views::FillLayout>()); } @@ -24,6 +28,11 @@ void QuickSettingsMediaViewContainer::MaybeShowMediaView() { SetVisible(show_media_view_); + if (show_media_view_) { + // When the quick settings view wants to show the media view, update the + // media item order to put the actively playing ones in the front. + controller_->media_view_controller()->UpdateMediaItemOrder(); + } } int QuickSettingsMediaViewContainer::GetExpandedHeight() const {
diff --git a/ash/system/media/quick_settings_media_view_container.h b/ash/system/media/quick_settings_media_view_container.h index 12c6f3f..ab60c49 100644 --- a/ash/system/media/quick_settings_media_view_container.h +++ b/ash/system/media/quick_settings_media_view_container.h
@@ -9,11 +9,14 @@ namespace ash { +class UnifiedSystemTrayController; + // Container view of QuickSettingsMediaView which manages the visibility of the // entire quick settings media view. class QuickSettingsMediaViewContainer : public views::View { public: - QuickSettingsMediaViewContainer(); + explicit QuickSettingsMediaViewContainer( + UnifiedSystemTrayController* controller); QuickSettingsMediaViewContainer(const QuickSettingsMediaViewContainer&) = delete; QuickSettingsMediaViewContainer& operator=( @@ -34,6 +37,8 @@ gfx::Size CalculatePreferredSize() const override; private: + UnifiedSystemTrayController* const controller_; + bool show_media_view_ = false; };
diff --git a/ash/system/media/quick_settings_media_view_controller.cc b/ash/system/media/quick_settings_media_view_controller.cc index 86b9c6e0..7326254 100644 --- a/ash/system/media/quick_settings_media_view_controller.cc +++ b/ash/system/media/quick_settings_media_view_controller.cc
@@ -120,4 +120,8 @@ tray_controller_->SetShowMediaView(show_media_view); } +void QuickSettingsMediaViewController::UpdateMediaItemOrder() { + media_view_->UpdateItemOrder(media_item_manager_->GetActiveItemIds()); +} + } // namespace ash \ No newline at end of file
diff --git a/ash/system/media/quick_settings_media_view_controller.h b/ash/system/media/quick_settings_media_view_controller.h index c1850212..7b51831 100644 --- a/ash/system/media/quick_settings_media_view_controller.h +++ b/ash/system/media/quick_settings_media_view_controller.h
@@ -66,6 +66,9 @@ // Sets whether the quick settings view should show any media item. void SetShowMediaView(bool show_media_view); + // Updates the order of media items in the quick settings media view. + void UpdateMediaItemOrder(); + private: raw_ptr<UnifiedSystemTrayController> tray_controller_ = nullptr;
diff --git a/ash/system/message_center/ash_message_popup_collection.cc b/ash/system/message_center/ash_message_popup_collection.cc index b9cf033..f85b34b 100644 --- a/ash/system/message_center/ash_message_popup_collection.cc +++ b/ash/system/message_center/ash_message_popup_collection.cc
@@ -5,7 +5,6 @@ #include "ash/system/message_center/ash_message_popup_collection.h" #include "ash/constants/ash_constants.h" -#include "ash/constants/ash_features.h" #include "ash/focus_cycler.h" #include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/shelf_types.h" @@ -50,10 +49,6 @@ AshMessagePopupCollection::AshMessagePopupCollection(Shelf* shelf) : screen_(nullptr), shelf_(shelf), tray_bubble_height_(0) { - // The order for notifications will be reversed when - // IsNotificationsRefreshEnabled. - if (!features::IsNotificationsRefreshEnabled()) - set_inverse(); shelf_->AddObserver(this); Shell::Get()->tablet_mode_controller()->AddObserver(this); }
diff --git a/ash/system/notification_center/notification_center_tray.cc b/ash/system/notification_center/notification_center_tray.cc index 50ecdd4f..d5a41e9 100644 --- a/ash/system/notification_center/notification_center_tray.cc +++ b/ash/system/notification_center/notification_center_tray.cc
@@ -47,10 +47,7 @@ // only added by host views. notification_icons_controller_->AddNotificationTrayItems(tray_container()); - // Do not show this indicator if video conference feature is enabled since - // privacy indicator is already shown there. - if (features::IsPrivacyIndicatorsEnabled() && - !features::IsVideoConferenceEnabled()) { + if (features::IsPrivacyIndicatorsEnabled()) { privacy_indicators_view_ = tray_container()->AddChildView( std::make_unique<PrivacyIndicatorsTrayItemView>(shelf)); }
diff --git a/ash/system/phonehub/app_stream_launcher_item.cc b/ash/system/phonehub/app_stream_launcher_item.cc index 1dd7cc5..0aa2fb02 100644 --- a/ash/system/phonehub/app_stream_launcher_item.cc +++ b/ash/system/phonehub/app_stream_launcher_item.cc
@@ -72,7 +72,7 @@ const bool enabled = app_metadata.app_streamability_status == phonehub::proto::AppStreamabilityStatus::STREAMABLE; - gfx::Image image = app_metadata.icon; + gfx::Image image = app_metadata.color_icon; if (!enabled) { // Fade the image in order to make it look like grayed out. // TODO(b/261916553): Make grayed out icons "gray" in
diff --git a/ash/system/phonehub/app_stream_launcher_list_item.cc b/ash/system/phonehub/app_stream_launcher_list_item.cc index 7c421d47..b40a7900 100644 --- a/ash/system/phonehub/app_stream_launcher_list_item.cc +++ b/ash/system/phonehub/app_stream_launcher_list_item.cc
@@ -50,7 +50,8 @@ gfx::ImageSkia resized_app_icon = gfx::ImageSkiaOperations::CreateResizedImage( - app_metadata.icon.AsImageSkia(), skia::ImageOperations::RESIZE_BEST, + app_metadata.color_icon.AsImageSkia(), + skia::ImageOperations::RESIZE_BEST, gfx::Size(kEcheAppLIstItemIconSize, kEcheAppLIstItemIconSize)); app_button_->SetImage(views::Button::ButtonState::STATE_NORMAL,
diff --git a/ash/system/phonehub/app_stream_launcher_view_unittest.cc b/ash/system/phonehub/app_stream_launcher_view_unittest.cc index e010f48..238b3a6a 100644 --- a/ash/system/phonehub/app_stream_launcher_view_unittest.cc +++ b/ash/system/phonehub/app_stream_launcher_view_unittest.cc
@@ -81,7 +81,7 @@ index)); } - const gfx::Image CreateTestImage() { + const gfx::Image /*cololr_icon=*/CreateTestImage() { SkBitmap bitmap; bitmap.allocN32Pixels(60, 60); gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); @@ -133,7 +133,7 @@ .size()); auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, CreateTestImage(), + app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); std::vector<phonehub::Notification::AppMetadata> apps; @@ -163,7 +163,7 @@ const char16_t app_visible_name[] = u"Fake App"; const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, CreateTestImage(), + app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); std::vector<phonehub::Notification::AppMetadata> apps; @@ -188,7 +188,7 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, CreateTestImage(), + app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); std::vector<phonehub::Notification::AppMetadata> apps; @@ -227,7 +227,8 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, CreateTestImage(), + app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); std::vector<phonehub::Notification::AppMetadata> apps; @@ -260,7 +261,8 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, CreateTestImage(), + app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); std::vector<phonehub::Notification::AppMetadata> apps; @@ -306,7 +308,8 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, CreateTestImage(), + app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); std::vector<phonehub::Notification::AppMetadata> apps; @@ -345,7 +348,8 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, CreateTestImage(), + app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::BLOCK_LISTED); std::vector<phonehub::Notification::AppMetadata> apps; @@ -384,7 +388,8 @@ const char package_name[] = "com.fakeapp"; auto app1 = phonehub::Notification::AppMetadata( - app_visible_name, package_name, CreateTestImage(), + app_visible_name, package_name, /*cololr_icon=*/CreateTestImage(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id, phonehub::proto::AppStreamabilityStatus::BLOCK_LISTED); std::vector<phonehub::Notification::AppMetadata> apps;
diff --git a/ash/system/phonehub/phone_hub_more_apps_button.cc b/ash/system/phonehub/phone_hub_more_apps_button.cc index d7a4c3f..fba1ec9 100644 --- a/ash/system/phonehub/phone_hub_more_apps_button.cc +++ b/ash/system/phonehub/phone_hub_more_apps_button.cc
@@ -170,8 +170,8 @@ if (!app_list->empty()) { auto app_count = std::min(app_list->size(), size_t{3}); for (size_t i = 0; i < app_count; i++) { - AddChildView( - std::make_unique<AppIcon>(app_list->at(i).icon, AppIcon::kSizeSmall)); + AddChildView(std::make_unique<AppIcon>(app_list->at(i).color_icon, + AppIcon::kSizeSmall)); } }
diff --git a/ash/system/phonehub/phone_hub_notification_controller.cc b/ash/system/phonehub/phone_hub_notification_controller.cc index 9a5bcf3..7714165 100644 --- a/ash/system/phonehub/phone_hub_notification_controller.cc +++ b/ash/system/phonehub/phone_hub_notification_controller.cc
@@ -677,7 +677,9 @@ std::u16string display_source = app_metadata.visible_app_name; message_center::RichNotificationData optional_fields; - optional_fields.small_image = app_metadata.icon; + optional_fields.small_image = app_metadata.monochrome_icon_mask.has_value() + ? app_metadata.monochrome_icon_mask.value() + : app_metadata.color_icon; optional_fields.timestamp = notification->timestamp(); optional_fields.accessible_name = l10n_util::GetStringFUTF16( IDS_ASH_PHONE_HUB_NOTIFICATION_ACCESSIBLE_NAME, display_source, title,
diff --git a/ash/system/phonehub/phone_hub_notification_controller_unittest.cc b/ash/system/phonehub/phone_hub_notification_controller_unittest.cc index 68738220..6f25e5d 100644 --- a/ash/system/phonehub/phone_hub_notification_controller_unittest.cc +++ b/ash/system/phonehub/phone_hub_notification_controller_unittest.cc
@@ -59,8 +59,9 @@ return phonehub::Notification( id, phonehub::Notification::AppMetadata( - kAppName, kPackageName, /*icon=*/gfx::Image(), - /*icon_color=*/absl::nullopt, /*icon_is_monochrome =*/true, kUserId, + kAppName, kPackageName, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE), base::Time::Now(), phonehub::Notification::Importance::kDefault, phonehub::Notification::Category::kConversation, @@ -75,8 +76,9 @@ id, phonehub::Notification::AppMetadata( kAppName, kPackageName, - /*icon=*/gfx::Image(), /*icon_color =*/absl::nullopt, - /*icon_is_monochrome =*/true, kUserId, + /*color_icon=*/gfx::Image(), /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE), base::Time::Now(), phonehub::Notification::Importance::kDefault, phonehub::Notification::Category::kIncomingCall, @@ -163,8 +165,9 @@ kPhoneHubNotificationId1, phonehub::Notification::AppMetadata( kAppName, kPackageName, - /*icon=*/gfx::Image(), /*icon_color =*/absl::nullopt, - /*icon_is_monochrome =*/true, kUserId, + /*color_icon=*/gfx::Image(), /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE), base::Time::Now(), phonehub::Notification::Importance::kDefault, phonehub::Notification::Category::kConversation, @@ -195,8 +198,9 @@ phonehub::Notification updated_notification( kPhoneHubNotificationId1, phonehub::Notification::AppMetadata( - kAppName, kPackageName, /*icon=*/gfx::Image(), iconColor, - /*icon_is_monochrome =*/true, kUserId, + kAppName, kPackageName, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, iconColor, + /*icon_is_monochrome=*/true, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE), base::Time::Now(), phonehub::Notification::Importance::kDefault, phonehub::Notification::Category::kConversation, @@ -216,8 +220,9 @@ kPhoneHubNotificationId1, phonehub::Notification::AppMetadata( kAppName, kPackageName, - /*icon=*/gfx::Image(), /*icon_color =*/absl::nullopt, - /*icon_is_monochrome =*/false, kUserId, + /*color_icon=*/gfx::Image(), /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/false, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE), base::Time::Now(), phonehub::Notification::Importance::kDefault, phonehub::Notification::Category::kConversation, @@ -339,8 +344,10 @@ phonehub::Notification fake_notification( kPhoneHubNotificationId0, phonehub::Notification::AppMetadata( - kAppName, kPackageName, icon, /*icon_color =*/absl::nullopt, - /*icon_is_monochrome =*/true, kUserId, + kAppName, kPackageName, /*color_icon=*/icon, + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE), timestamp, phonehub::Notification::Importance::kHigh, phonehub::Notification::Category::kConversation, @@ -447,8 +454,9 @@ kPhoneHubNotificationId0, phonehub::Notification::AppMetadata( kAppName, kPackageName, - /*icon=*/gfx::Image(), /*icon_color =*/absl::nullopt, - /*icon_is_monochrome =*/true, kUserId, + /*color_icon=*/gfx::Image(), /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE), old_timestamp, phonehub::Notification::Importance::kHigh, phonehub::Notification::Category::kConversation, @@ -477,8 +485,9 @@ kPhoneHubNotificationId0, phonehub::Notification::AppMetadata( kAppName, kPackageName, - /*icon=*/gfx::Image(), /*icon_color =*/absl::nullopt, - /*icon_is_monochrome =*/true, kUserId, + /*color_icon=*/gfx::Image(), /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE), base::Time::Now(), phonehub::Notification::Importance::kHigh, phonehub::Notification::Category::kConversation, @@ -509,8 +518,9 @@ kPhoneHubNotificationId0, phonehub::Notification::AppMetadata( kAppName, kPackageName, - /*icon=*/gfx::Image(), /*icon_color =*/absl::nullopt, - /*icon_is_monochrome =*/true, kUserId, + /*color_icon=*/gfx::Image(), /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE), base::Time::Now(), phonehub::Notification::Importance::kMin, phonehub::Notification::Category::kConversation,
diff --git a/ash/system/phonehub/phone_hub_recent_apps_view.cc b/ash/system/phonehub/phone_hub_recent_apps_view.cc index 94f748a..5f319dbc 100644 --- a/ash/system/phonehub/phone_hub_recent_apps_view.cc +++ b/ash/system/phonehub/phone_hub_recent_apps_view.cc
@@ -31,6 +31,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" #include "ui/gfx/geometry/insets.h" +#include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/views/animation/animation_builder.h" @@ -428,7 +429,7 @@ recent_app_button_list_.push_back( recent_app_buttons_view_->AddRecentAppButton( std::make_unique<PhoneHubRecentAppButton>( - recent_app.icon, recent_app.visible_app_name, + recent_app.color_icon, recent_app.visible_app_name, pressed_callback))); }
diff --git a/ash/system/phonehub/phone_hub_recent_apps_view_unittest.cc b/ash/system/phonehub/phone_hub_recent_apps_view_unittest.cc index e26753b..9868dfd 100644 --- a/ash/system/phonehub/phone_hub_recent_apps_view_unittest.cc +++ b/ash/system/phonehub/phone_hub_recent_apps_view_unittest.cc
@@ -75,8 +75,9 @@ void NotifyRecentAppAddedOrUpdated() { auto app_metadata = phonehub::Notification::AppMetadata( kAppName, kPackageName, - /*icon=*/gfx::Image(), /*icon_color =*/absl::nullopt, - /*icon_is_monochrome =*/true, kUserId, + /*color_icon=*/gfx::Image(), /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, kUserId, phonehub::proto::AppStreamabilityStatus::STREAMABLE); fake_recent_apps_interaction_handler_.NotifyRecentAppAddedOrUpdated(
diff --git a/ash/system/privacy/privacy_indicators_controller.cc b/ash/system/privacy/privacy_indicators_controller.cc index f1be218..97fa23e 100644 --- a/ash/system/privacy/privacy_indicators_controller.cc +++ b/ash/system/privacy/privacy_indicators_controller.cc
@@ -135,9 +135,7 @@ bool is_new_app, bool was_camera_in_use, bool was_microphone_in_use) { - // Privacy indicators don't exist when video conference controls are enabled. - if (!features::IsPrivacyIndicatorsEnabled() || - features::IsVideoConferenceEnabled()) { + if (!features::IsPrivacyIndicatorsEnabled()) { return; } DCHECK(Shell::HasInstance());
diff --git a/ash/system/privacy/privacy_indicators_controller_unittest.cc b/ash/system/privacy/privacy_indicators_controller_unittest.cc index 908f612..efa6f12 100644 --- a/ash/system/privacy/privacy_indicators_controller_unittest.cc +++ b/ash/system/privacy/privacy_indicators_controller_unittest.cc
@@ -4,6 +4,7 @@ #include "ash/system/privacy/privacy_indicators_controller.h" +#include <memory> #include <string> #include "ash/constants/ash_constants.h" @@ -14,10 +15,12 @@ #include "ash/strings/grit/ash_strings.h" #include "ash/system/message_center/ash_message_popup_collection.h" #include "ash/system/message_center/unified_message_center_bubble.h" +#include "ash/system/notification_center/notification_center_tray.h" #include "ash/system/notification_center/notification_center_view.h" #include "ash/system/notification_center/notification_list_view.h" #include "ash/system/privacy/privacy_indicators_tray_item_view.h" #include "ash/system/unified/unified_system_tray.h" +#include "ash/system/video_conference/fake_video_conference_tray_controller.h" #include "ash/test/ash_test_base.h" #include "base/command_line.h" #include "base/functional/bind.h" @@ -384,4 +387,80 @@ PrivacyIndicatorsSource::kLinuxVm, 1); } +// Tests enabling both `kPrivacyIndicators` and `kVideoConference`, +// parameterized with `kQsRevamp` enabled and disabled. +class PrivacyIndicatorsControllerVideoConferenceTest + : public AshTestBase, + public testing::WithParamInterface<bool> { + public: + PrivacyIndicatorsControllerVideoConferenceTest() { + std::vector<base::test::FeatureRef> enabled_features = { + features::kPrivacyIndicators, features::kVideoConference}; + std::vector<base::test::FeatureRef> disabled_features; + + if (IsQsRevampEnabled()) { + enabled_features.push_back(features::kQsRevamp); + } else { + disabled_features.push_back(features::kQsRevamp); + } + + scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); + } + PrivacyIndicatorsControllerVideoConferenceTest( + const PrivacyIndicatorsControllerVideoConferenceTest&) = delete; + PrivacyIndicatorsControllerVideoConferenceTest& operator=( + const PrivacyIndicatorsControllerVideoConferenceTest&) = delete; + ~PrivacyIndicatorsControllerVideoConferenceTest() override = default; + + bool IsQsRevampEnabled() { return GetParam(); } + + // AshTestBase: + void SetUp() override { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kCameraEffectsSupportedByHardware); + + // Instantiates a fake controller (the real one is created in + // ChromeBrowserMainExtraPartsAsh::PreProfileInit() which is not called in + // ash unit tests). + controller_ = std::make_unique<FakeVideoConferenceTrayController>(); + + AshTestBase::SetUp(); + } + + void TearDown() override { + AshTestBase::TearDown(); + controller_.reset(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<FakeVideoConferenceTrayController> controller_; +}; + +INSTANTIATE_TEST_SUITE_P(All, + PrivacyIndicatorsControllerVideoConferenceTest, + testing::Bool() /* IsQsRevampEnabled() */); + +// Make sure that when `kPrivacyIndicators` and `kVideoConference` are both +// enabled, the privacy indicators view and the controller is not created. +TEST_P(PrivacyIndicatorsControllerVideoConferenceTest, ObjectsCreation) { + EXPECT_FALSE(PrivacyIndicatorsController::Get()); + + for (auto* root_window_controller : + Shell::Get()->GetAllRootWindowControllers()) { + DCHECK(root_window_controller); + auto* status_area_widget = root_window_controller->GetStatusAreaWidget(); + DCHECK(status_area_widget); + + auto* privacy_indicators_view = + features::IsQsRevampEnabled() + ? status_area_widget->notification_center_tray() + ->privacy_indicators_view() + : status_area_widget->unified_system_tray() + ->privacy_indicators_view(); + + EXPECT_FALSE(privacy_indicators_view); + } +} + } // namespace ash
diff --git a/ash/system/unified/quick_settings_view.cc b/ash/system/unified/quick_settings_view.cc index b2e50af..99e14cac 100644 --- a/ash/system/unified/quick_settings_view.cc +++ b/ash/system/unified/quick_settings_view.cc
@@ -153,7 +153,7 @@ if (base::FeatureList::IsEnabled(media::kGlobalMediaControlsCrOSUpdatedUI)) { media_view_container_ = system_tray_container_->AddChildView( - std::make_unique<QuickSettingsMediaViewContainer>()); + std::make_unique<QuickSettingsMediaViewContainer>(controller_)); } else if (base::FeatureList::IsEnabled( media::kGlobalMediaControlsForChromeOS)) { media_controls_container_ = system_tray_container_->AddChildView(
diff --git a/ash/system/unified/unified_system_tray.cc b/ash/system/unified/unified_system_tray.cc index b0cf0bc..733c81c 100644 --- a/ash/system/unified/unified_system_tray.cc +++ b/ash/system/unified/unified_system_tray.cc
@@ -258,11 +258,9 @@ shelf, Shell::Get()->shell_delegate()->GetChannel())); } - // Do not show this indicator if video conference feature is enabled since - // privacy indicator is already shown there. We also do not show this here in - // the new Quick Settings UI. + // We do not show privacy indicators here in the new Quick Settings UI. if (features::IsPrivacyIndicatorsEnabled() && - !features::IsVideoConferenceEnabled() && !features::IsQsRevampEnabled()) { + !features::IsQsRevampEnabled()) { privacy_indicators_view_ = AddTrayItemToContainer( std::make_unique<PrivacyIndicatorsTrayItemView>(shelf)); }
diff --git a/ash/system/unified/unified_system_tray_controller.h b/ash/system/unified/unified_system_tray_controller.h index d0eb8ca..29a59eb 100644 --- a/ash/system/unified/unified_system_tray_controller.h +++ b/ash/system/unified/unified_system_tray_controller.h
@@ -203,6 +203,11 @@ return detailed_view_controller_.get(); } + QuickSettingsMediaViewController* media_view_controller() { + DCHECK(media_view_controller_); + return media_view_controller_.get(); + } + bool showing_audio_detailed_view() const { return showing_audio_detailed_view_; }
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc index 295dd1e0..1e05d51 100644 --- a/ash/wallpaper/wallpaper_controller_impl.cc +++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -645,10 +645,11 @@ void WallpaperControllerImpl::ShowWallpaperImage(const gfx::ImageSkia& image, WallpaperInfo info, bool preview_mode, - bool always_on_top) { - // Prevent showing other wallpapers if there is an always-on-top wallpaper. - if (is_always_on_top_wallpaper_ && !always_on_top) + bool is_override) { + // Prevent showing other wallpapers if there is an override wallpaper. + if (is_override_wallpaper_ && !is_override) { return; + } // Ignore show wallpaper requests during preview mode. This could happen if a // custom wallpaper previously set on another device is being synced. @@ -931,7 +932,7 @@ weak_factory_.GetWeakPtr(), image, WallpaperInfo{/*in_location=*/std::string(), layout, WallpaperType::kCustomized, base::Time::Now(), file_path}, - /*preview_mode=*/true, /*always_on_top=*/false); + /*preview_mode=*/true, /*is_override=*/false); // Show the preview wallpaper. reload_preview_wallpaper_callback_.Run(); } else { @@ -1325,7 +1326,7 @@ gfx::ImageSkia user_wallpaper; if (GetWallpaperFromCache(account_id, &user_wallpaper)) { ShowWallpaperImage(user_wallpaper, info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); return; } @@ -1395,29 +1396,32 @@ WallpaperLayout::WALLPAPER_LAYOUT_STRETCH, WallpaperType::kOneShot, base::Time::Now()}; ShowWallpaperImage(image, info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); } -void WallpaperControllerImpl::ShowAlwaysOnTopWallpaper( - const base::FilePath& image_path) { - is_always_on_top_wallpaper_ = true; +void WallpaperControllerImpl::ShowOverrideWallpaper( + const base::FilePath& image_path, + bool always_on_top) { + is_always_on_top_wallpaper_ = always_on_top; + is_override_wallpaper_ = true; const WallpaperInfo info = {/*in_location=*/std::string(), WallpaperLayout::WALLPAPER_LAYOUT_CENTER_CROPPED, WallpaperType::kOneShot, base::Time::Now()}; ReparentWallpaper(GetWallpaperContainerId(locked_)); ReadAndDecodeWallpaper( - base::BindOnce(&WallpaperControllerImpl::OnAlwaysOnTopWallpaperDecoded, + base::BindOnce(&WallpaperControllerImpl::OnOverrideWallpaperDecoded, weak_factory_.GetWeakPtr(), info), image_path); } -void WallpaperControllerImpl::RemoveAlwaysOnTopWallpaper() { - if (!is_always_on_top_wallpaper_) { - DCHECK(!reload_always_on_top_wallpaper_callback_); +void WallpaperControllerImpl::RemoveOverrideWallpaper() { + if (!is_override_wallpaper_) { + DCHECK(!reload_override_wallpaper_callback_); return; } is_always_on_top_wallpaper_ = false; - reload_always_on_top_wallpaper_callback_.Reset(); + is_override_wallpaper_ = false; + reload_override_wallpaper_callback_.Reset(); ReparentWallpaper(GetWallpaperContainerId(locked_)); // Forget current wallpaper data. current_wallpaper_.reset(); @@ -2085,7 +2089,7 @@ reload_preview_wallpaper_callback_ = base::BindRepeating( &WallpaperControllerImpl::ShowWallpaperImage, weak_factory_.GetWeakPtr(), image, WallpaperInfo(params), - /*preview_mode=*/true, /*always_on_top=*/false); + /*preview_mode=*/true, /*is_override=*/false); // Show the preview wallpaper. reload_preview_wallpaper_callback_.Run(); } else { @@ -2104,7 +2108,7 @@ } if (show_wallpaper) { ShowWallpaperImage(image, wallpaper_info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); } wallpaper_cache_map_[params.account_id] = @@ -2302,7 +2306,7 @@ reload_preview_wallpaper_callback_ = base::BindRepeating(&WallpaperControllerImpl::ShowWallpaperImage, weak_factory_.GetWeakPtr(), image, wallpaper_info, - /*preview_mode=*/true, /*always_on_top=*/false); + /*preview_mode=*/true, /*is_override=*/false); // Show the preview wallpaper. reload_preview_wallpaper_callback_.Run(); @@ -2325,7 +2329,7 @@ if (show_wallpaper) { ShowWallpaperImage(image, wallpaper_info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); } // Add current Google Photos wallpaper to in-memory cache. @@ -2449,7 +2453,7 @@ WallpaperInfo info(cached_default_wallpaper_.file_path.value(), layout, WallpaperType::kDefault, base::Time::Now()); ShowWallpaperImage(cached_default_wallpaper_.image, info, - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); } } @@ -2542,7 +2546,7 @@ if (show_wallpaper) { ShowWallpaperImage(image, info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); } wallpaper_cache_map_[account_id] = @@ -2567,7 +2571,7 @@ wallpaper_cache_map_[account_id] = CustomWallpaperElement(path, image); if (show_wallpaper) { ShowWallpaperImage(image, info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); } } @@ -2581,16 +2585,17 @@ if (clear_cache) wallpaper_cache_map_.clear(); - if (reload_always_on_top_wallpaper_callback_) - reload_always_on_top_wallpaper_callback_.Run(); - else if (reload_preview_wallpaper_callback_) + if (reload_override_wallpaper_callback_) { + reload_override_wallpaper_callback_.Run(); + } else if (reload_preview_wallpaper_callback_) { reload_preview_wallpaper_callback_.Run(); - else if (current_user_.is_valid()) + } else if (current_user_.is_valid()) { ShowUserWallpaper(current_user_); - else if (was_one_shot_wallpaper) + } else if (was_one_shot_wallpaper) { ShowOneShotWallpaper(one_shot_wallpaper); - else + } else { ShowSigninWallpaper(); + } } void WallpaperControllerImpl::SetCalculatedColors( @@ -2653,22 +2658,23 @@ !image.isNull(); } -void WallpaperControllerImpl::OnAlwaysOnTopWallpaperDecoded( +void WallpaperControllerImpl::OnOverrideWallpaperDecoded( const WallpaperInfo& info, const gfx::ImageSkia& image) { - // Do nothing if |RemoveAlwaysOnTopWallpaper| was called before decoding + // Do nothing if |RemoveOverrideWallpaper()| was called before decoding // completes. - if (!is_always_on_top_wallpaper_) - return; - if (image.isNull()) { - is_always_on_top_wallpaper_ = false; + if (!is_override_wallpaper_) { return; } - reload_always_on_top_wallpaper_callback_ = + if (image.isNull()) { + RemoveOverrideWallpaper(); + return; + } + reload_override_wallpaper_callback_ = base::BindRepeating(&WallpaperControllerImpl::ShowWallpaperImage, weak_factory_.GetWeakPtr(), image, info, - /*preview_mode=*/false, /*always_on_top=*/true); - reload_always_on_top_wallpaper_callback_.Run(); + /*preview_mode=*/false, /*is_override=*/true); + reload_override_wallpaper_callback_.Run(); } bool WallpaperControllerImpl::IsDevicePolicyWallpaper() const { @@ -2719,7 +2725,7 @@ WALLPAPER_LAYOUT_CENTER_CROPPED, WallpaperType::kDevice, base::Time::Now()}; ShowWallpaperImage(image, info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); } }
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h index 576e496..0521b55 100644 --- a/ash/wallpaper/wallpaper_controller_impl.h +++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -176,11 +176,11 @@ // Does not show the image if: // 1) |preview_mode| is false and the current wallpaper is still being // previewed. See comments for |confirm_preview_wallpaper_callback_|. - // 2) |always_on_top| is false but the current wallpaper is always-on-top. + // 2) |is_override| is false but the current wallpaper is overridden. void ShowWallpaperImage(const gfx::ImageSkia& image, WallpaperInfo info, bool preview_mode, - bool always_on_top); + bool is_override); // Update the blurred state of the current wallpaper for lock screen. Applies // blur if |blur| is true and blur is allowed by the controller, otherwise any @@ -297,8 +297,9 @@ user_manager::UserType user_type) override; void ShowSigninWallpaper() override; void ShowOneShotWallpaper(const gfx::ImageSkia& image) override; - void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) override; - void RemoveAlwaysOnTopWallpaper() override; + void ShowOverrideWallpaper(const base::FilePath& image_path, + bool always_on_top) override; + void RemoveOverrideWallpaper() override; void RemoveUserWallpaper(const AccountId& account_id, base::OnceClosure on_removed) override; void RemovePolicyWallpaper(const AccountId& account_id) override; @@ -652,9 +653,9 @@ void OnColorCalculationComplete(const WallpaperInfo& info, const WallpaperCalculatedColors& colors); - // The callback when decoding of the always-on-top wallpaper completes. - void OnAlwaysOnTopWallpaperDecoded(const WallpaperInfo& info, - const gfx::ImageSkia& image); + // The callback when decoding of the override wallpaper completes. + void OnOverrideWallpaperDecoded(const WallpaperInfo& info, + const gfx::ImageSkia& image); // Returns whether the current wallpaper is set by device policy. bool IsDevicePolicyWallpaper() const; @@ -843,6 +844,9 @@ // If true, the current wallpaper should always stay on top. bool is_always_on_top_wallpaper_ = false; + // If true, the current wallpaper is overridden. + bool is_override_wallpaper_ = false; + const std::unique_ptr<WallpaperImageDownloader> wallpaper_image_downloader_; scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_; @@ -867,10 +871,9 @@ // change). Has the same lifetime with |confirm_preview_wallpaper_callback_|. base::RepeatingClosure reload_preview_wallpaper_callback_; - // Called when the always-on-top wallpaper needs to be reloaded (e.g. display - // size change). Non-empty if and only if |is_always_on_top_wallpaper_| is - // true. - base::RepeatingClosure reload_always_on_top_wallpaper_callback_; + // Called when the override wallpaper needs to be reloaded (e.g. display size + // change). Non-empty if and only if |is_override_wallpaper_| is true. + base::RepeatingClosure reload_override_wallpaper_callback_; // Transient storage for the wallpaper variant (out of the N total variants // that may exist for a given "unit") that was requested by the client. The
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index 23018bf..f4a8289 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -490,7 +490,7 @@ const gfx::ImageSkia kImage = CreateImage(10, 10, kWallpaperColor); controller_->ShowWallpaperImage( kImage, CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); SetSessionState(SessionState::ACTIVE); EXPECT_TRUE(ShouldCalculateColors()); @@ -898,7 +898,7 @@ // that the resized image is the expected size. controller_->ShowWallpaperImage( image, CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); EXPECT_TRUE(image.BackedBySameObjectAs(controller_->GetWallpaper())); RunAllTasksUntilIdle(); gfx::ImageSkia resized_image = controller_->GetWallpaper(); @@ -910,7 +910,7 @@ // (http://crbug.com/321402). controller_->ShowWallpaperImage( image, CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); RunAllTasksUntilIdle(); EXPECT_TRUE(resized_image.BackedBySameObjectAs(controller_->GetWallpaper())); } @@ -969,7 +969,7 @@ SCOPED_TRACE(base::StringPrintf("1200x600*2 high resolution")); controller_->ShowWallpaperImage( image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); WallpaperFitToNativeResolution(wallpaper_view(), high_dsf, high_resolution.width(), high_resolution.height(), kWallpaperColor); @@ -978,7 +978,7 @@ SCOPED_TRACE(base::StringPrintf("1200x600*2 low resolution")); controller_->ShowWallpaperImage( image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); WallpaperFitToNativeResolution(wallpaper_view(), high_dsf, low_resolution.width(), low_resolution.height(), kWallpaperColor); @@ -989,7 +989,7 @@ SCOPED_TRACE(base::StringPrintf("1200x600 high resolution")); controller_->ShowWallpaperImage( image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); WallpaperFitToNativeResolution(wallpaper_view(), low_dsf, high_resolution.width(), high_resolution.height(), kWallpaperColor); @@ -998,7 +998,7 @@ SCOPED_TRACE(base::StringPrintf("1200x600 low resolution")); controller_->ShowWallpaperImage( image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); WallpaperFitToNativeResolution(wallpaper_view(), low_dsf, low_resolution.width(), low_resolution.height(), kWallpaperColor); @@ -1009,7 +1009,7 @@ SCOPED_TRACE(base::StringPrintf("1200x600/u@1.5 high resolution")); controller_->ShowWallpaperImage( image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); WallpaperFitToNativeResolution(wallpaper_view(), low_dsf, high_resolution.width(), high_resolution.height(), kWallpaperColor); @@ -1018,7 +1018,7 @@ SCOPED_TRACE(base::StringPrintf("1200x600/u@1.5 low resolution")); controller_->ShowWallpaperImage( image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); WallpaperFitToNativeResolution(wallpaper_view(), low_dsf, low_resolution.width(), low_resolution.height(), kWallpaperColor); @@ -1076,7 +1076,7 @@ old_info.location = "old"; controller_->ShowWallpaperImage(old_image, old_info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); // Run the controller until resize completes for the first wallpaper and // color calculation starts. run_loop.Run(); @@ -1093,7 +1093,7 @@ controller_->ShowWallpaperImage(image, info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); // Run until we get a notification of colors changed. colors_loop.Run(); @@ -1120,7 +1120,7 @@ const gfx::ImageSkia kImage = CreateImage(10, 10, kWallpaperColor); controller_->ShowWallpaperImage(kImage, wallpaper_info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); SetSessionState(SessionState::ACTIVE); // Wait for color computation to complete. @@ -1143,7 +1143,7 @@ const gfx::ImageSkia kImage = CreateImage(10, 10, kWallpaperColor); controller_->ShowWallpaperImage(kImage, wallpaper_info, /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); SetSessionState(SessionState::ACTIVE); // Wait for color computation to complete. @@ -2291,14 +2291,14 @@ RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); - // Show an always-on-top wallpaper. + // Show an override wallpaper. const base::FilePath image_path = base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( switches::kGuestWallpaperLarge); CreateDefaultWallpapers(); SetBypassDecode(); ClearWallpaperCount(); - controller_->ShowAlwaysOnTopWallpaper(image_path); + controller_->ShowOverrideWallpaper(image_path, /*always_on_top=*/true); RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); // Rotating the display should trigger a wallpaper reload. @@ -2587,7 +2587,7 @@ gfx::ImageSkia image = CreateImage(600, 400, kWallpaperColor); controller_->ShowWallpaperImage( image, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); TestWallpaperControllerObserver observer(controller_); @@ -2631,7 +2631,7 @@ gfx::ImageSkia image = CreateImage(600, 400, kWallpaperColor); controller_->ShowWallpaperImage( image, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER), - /*preview_mode=*/false, /*always_on_top=*/false); + /*preview_mode=*/false, /*is_override=*/false); TestWallpaperControllerObserver observer(controller_); EnterOverview(); @@ -3387,7 +3387,7 @@ controller_->ShowWallpaperImage(CreateImage(640, 480, SK_ColorBLUE), CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH), /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); RunAllTasksUntilIdle(); EXPECT_EQ(SK_ColorBLUE, GetWallpaperColor()); EXPECT_EQ(1, GetWallpaperCount()); @@ -3396,7 +3396,7 @@ controller_->ShowWallpaperImage(CreateImage(640, 480, SK_ColorCYAN), CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH), /*preview_mode=*/false, - /*always_on_top=*/false); + /*is_override=*/false); RunAllTasksUntilIdle(); EXPECT_EQ(SK_ColorCYAN, GetWallpaperColor()); EXPECT_EQ(2, GetWallpaperCount()); @@ -3457,7 +3457,23 @@ EXPECT_EQ(kWallpaperColor, GetWallpaperColor()); } -TEST_F(WallpaperControllerTest, AlwaysOnTopWallpaper) { +// Base class for `WallpaperControllerTest` parameterized by whether override +// wallpapers should be shown on top of everything except for the power off +// animation. +class WallpaperControllerOverrideWallpaperTest + : public WallpaperControllerTest, + public testing::WithParamInterface</*always_on_top=*/bool> { + public: + // Returns whether override wallpapers should be shown on top of everything + // except for the power off animation given test parameterization. + bool always_on_top() const { return GetParam(); } +}; + +INSTANTIATE_TEST_SUITE_P(All, + WallpaperControllerOverrideWallpaperTest, + /*always_on_top=*/testing::Bool()); + +TEST_P(WallpaperControllerOverrideWallpaperTest, OverrideWallpaper) { CreateDefaultWallpapers(); SetBypassDecode(); @@ -3470,38 +3486,40 @@ EXPECT_EQ(1, ChildCountForContainer(kWallpaperId)); EXPECT_EQ(0, ChildCountForContainer(kAlwaysOnTopWallpaperId)); - // Show an always-on-top wallpaper. + // Show an override wallpaper. const base::FilePath image_path = base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( switches::kGuestWallpaperLarge); - controller_->ShowAlwaysOnTopWallpaper(image_path); + controller_->ShowOverrideWallpaper(image_path, always_on_top()); RunAllTasksUntilIdle(); EXPECT_EQ(2, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kOneShot); - EXPECT_EQ(0, ChildCountForContainer(kWallpaperId)); - EXPECT_EQ(1, ChildCountForContainer(kAlwaysOnTopWallpaperId)); + EXPECT_EQ(always_on_top() ? 0 : 1, ChildCountForContainer(kWallpaperId)); + EXPECT_EQ(always_on_top() ? 1 : 0, + ChildCountForContainer(kAlwaysOnTopWallpaperId)); // Subsequent wallpaper requests are ignored when the current wallpaper is - // always-on-top. + // overridden. controller_->ShowSigninWallpaper(); RunAllTasksUntilIdle(); EXPECT_EQ(2, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kOneShot); - EXPECT_EQ(0, ChildCountForContainer(kWallpaperId)); - EXPECT_EQ(1, ChildCountForContainer(kAlwaysOnTopWallpaperId)); + EXPECT_EQ(always_on_top() ? 0 : 1, ChildCountForContainer(kWallpaperId)); + EXPECT_EQ(always_on_top() ? 1 : 0, + ChildCountForContainer(kAlwaysOnTopWallpaperId)); - // The wallpaper reverts to the default after the always-on-top wallpaper is + // The wallpaper reverts to the default after the override wallpaper is // removed. - controller_->RemoveAlwaysOnTopWallpaper(); + controller_->RemoveOverrideWallpaper(); RunAllTasksUntilIdle(); EXPECT_EQ(3, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault); EXPECT_EQ(1, ChildCountForContainer(kWallpaperId)); EXPECT_EQ(0, ChildCountForContainer(kAlwaysOnTopWallpaperId)); - // Calling |RemoveAlwaysOnTopWallpaper| is a no-op when the current wallpaper - // is not always-on-top. - controller_->RemoveAlwaysOnTopWallpaper(); + // Calling |RemoveOverrideWallpaper()| is a no-op when the current wallpaper + // is not overridden. + controller_->RemoveOverrideWallpaper(); RunAllTasksUntilIdle(); EXPECT_EQ(3, GetWallpaperCount()); EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault);
diff --git a/ash/webui/common/resources/smb_shares/OWNERS b/ash/webui/common/resources/smb_shares/OWNERS index 5189b388..73220a8 100644 --- a/ash/webui/common/resources/smb_shares/OWNERS +++ b/ash/webui/common/resources/smb_shares/OWNERS
@@ -1 +1 @@ -khorimoto@chromium.org +file://ui/file_manager/OWNERS
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_card.html b/ash/webui/diagnostics_ui/resources/diagnostics_card.html index 1778fac..a8ca4228 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_card.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_card.html
@@ -1,4 +1,12 @@ <style include="diagnostics-shared"> + :host { + --diagnostics-card-icon-bg-color: var(--cros-highlight-color) + } + + :host-context(body.jelly-enabled) ::slotted([slot=icon]) { + --diagnostics-card-icon-bg-color: var(--cros-sys-highlight_shape); + } + ::slotted([slot=chip]) { background-color: var(--diagnostics-chip-bg-color); border-radius: 16px; @@ -8,7 +16,7 @@ --iron-icon-fill-color: var(--cros-color-prominent); --iron-icon-height: 20px; --iron-icon-width: 20px; - background-color: var(--cros-highlight-color); + background-color: var(--diagnostics-card-icon-bg-color); border-radius: 50%; margin: 0 20px; padding: 8px;
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.html b/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.html index 9a61a584..faefc0b38 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.html
@@ -3,6 +3,10 @@ --cros-icon-color-primary: var(--cros-icon-color-secondary); } + :host-context(body.jelly-enabled) #connectingIcon { + --paper-spinner-color: var(--cros-sys-progress); + } + #connectingIcon { height: 20px; width: 20px;
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_shared.css b/ash/webui/diagnostics_ui/resources/diagnostics_shared.css index 39f86dc..acb9b12b 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_shared.css +++ b/ash/webui/diagnostics_ui/resources/diagnostics_shared.css
@@ -25,6 +25,21 @@ --diagnostics-medium-font-weight: 500; } + :host-context(body.jelly-enabled) { + --diagnostics-box-shadow: + 0 1px 2px var(--cros-shadow-color-key), + 0 1px 3px var(--cros-shadow-color-ambient); + --diagnostics-box-shadow-elevation-2: + 0 1px 2px var(--cros-shadow-color-key), + 0 2px 6px var(--cros-shadow-color-ambient); + --diagnostics-card-bg-color: var(--cros-sys-app_base); + --diagnostics-chip-bg-color: var(--cros-sys-app_base); + } + + :host-context(body.jelly-enabled) .grey-container { + background-color: var(--cros-sys-app_base_shaded); + } + hr { border: 0; border-top: 1px solid var(--cros-separator-color); @@ -276,6 +291,16 @@ --diagnostics-chip-bg-color: var(--cros-bg-color-elevation-3); } + :host-context(body.jelly-enabled) { + --diagnostics-card-bg-color: var(--cros-sys-base_elevated); + --diagnostics-chip-bg-color: var(--cros-sys-base_elevated); + } + + :host-context(body.jelly-enabled) .grey-container { + background-color: var(--cros-sys-app_base_shaded); + } + + .grey-container { background-color: var(--cros-bg-color-dropped-elevation-2); }
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html b/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html index 063fff1d..3447045 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html
@@ -1,4 +1,8 @@ <style include="cr-shared-style diagnostics-shared"> + :host-context(body.jelly-enabled) #banner { + background-color: var(--cros-sys-primary_container); + } + #banner { align-items: center; background-color: var(--cros-highlight-color);
diff --git a/ash/webui/diagnostics_ui/resources/index.html b/ash/webui/diagnostics_ui/resources/index.html index 68692809..72e0397a 100644 --- a/ash/webui/diagnostics_ui/resources/index.html +++ b/ash/webui/diagnostics_ui/resources/index.html
@@ -24,6 +24,10 @@ background-color: var(--cros-bg-color); } + html:has(body.jelly-enabled) { + background-color: var(--cros-sys-app_base_shaded); + } + html, body { height: 100%;
diff --git a/ash/webui/diagnostics_ui/resources/input_card.html b/ash/webui/diagnostics_ui/resources/input_card.html index b2075db..7fbae69 100644 --- a/ash/webui/diagnostics_ui/resources/input_card.html +++ b/ash/webui/diagnostics_ui/resources/input_card.html
@@ -1,4 +1,9 @@ <style include="diagnostics-shared"> + :host-context(body.jelly-enabled) .device #deviceIcon { + --iron-icon-fill-color: var(--cros-icon-color-prominent); + background-color: var(--cros-sys-highlight_shape); + } + paper-tooltip { --paper-tooltip-background: var(--cros-tooltip-background-color); --paper-tooltip-min-width: 0px;
diff --git a/ash/webui/diagnostics_ui/resources/text_badge.html b/ash/webui/diagnostics_ui/resources/text_badge.html index 9a1cdc6..9ee09d73 100644 --- a/ash/webui/diagnostics_ui/resources/text_badge.html +++ b/ash/webui/diagnostics_ui/resources/text_badge.html
@@ -1,4 +1,31 @@ <style include="diagnostics-shared"> + :host-context(body.jelly-enabled) .error { + background-color: var(--cros-sys-error_container); + color: var(--cros-sys-on_error_container); + } + + :host-context(body.jelly-enabled) .queued, + :host-context(body.jelly-enabled) .skipped, + :host-context(body.jelly-enabled) .stopped { + background-color: var(--cros-sys-disabled_container); + color: var(--cros-sys-disabled); + } + + :host-context(body.jelly-enabled) .running { + background-color: var(--cros-sys-progress_container); + color: var(--cros-sys-on_progress_container); + } + + :host-context(body.jelly-enabled) .success { + background-color: var(--cros-sys-positive_container); + color: var(--cros-sys-on_positive_container); + } + + :host-context(body.jelly-enabled) .warning { + background-color: var(--cros-sys-warning_container); + color: var(--cros-sys-on_warning_container); + } + .error { background-color: var(--google-red-50); color: var(--cros-text-color-alert); @@ -40,6 +67,33 @@ } @media (prefers-color-scheme: dark) { + :host-context(body.jelly-enabled) .error { + background-color: var(--cros-sys-error_container); + color: var(--cros-sys-on_error_container); + } + + :host-context(body.jelly-enabled) .queued, + :host-context(body.jelly-enabled) .skipped, + :host-context(body.jelly-enabled) .stopped { + background-color: var(--cros-sys-disabled_container); + color: var(--cros-sys-disabled); + } + + :host-context(body.jelly-enabled) .running { + background-color: var(--cros-sys-progress_container); + color: var(--cros-sys-on_progress_container); + } + + :host-context(body.jelly-enabled) .success { + background-color: var(--cros-sys-positive_container); + color: var(--cros-sys-on_positive_container); + } + + :host-context(body.jelly-enabled) .warning { + background-color: var(--cros-sys-warning_container); + color: var(--cros-sys-on_warning_container); + } + .error { background-color: rgba(var(--google-red-300-rgb), var(--cros-second-tone-opacity));
diff --git a/ash/webui/diagnostics_ui/resources/touchpad_tester.html b/ash/webui/diagnostics_ui/resources/touchpad_tester.html index 6ea6de1f..02340a0 100644 --- a/ash/webui/diagnostics_ui/resources/touchpad_tester.html +++ b/ash/webui/diagnostics_ui/resources/touchpad_tester.html
@@ -1,4 +1,8 @@ <style include="diagnostics-shared"> +:host-context(body.jelly-enabled) .tester { + background: var(--cros-highlight-color_shape); +} + .canvas-container { align-items: center; display: flex;
diff --git a/ash/webui/eche_app_ui/eche_notification_click_handler.cc b/ash/webui/eche_app_ui/eche_notification_click_handler.cc index abac5854..ed0a567 100644 --- a/ash/webui/eche_app_ui/eche_notification_click_handler.cc +++ b/ash/webui/eche_app_ui/eche_notification_click_handler.cc
@@ -12,8 +12,7 @@ #include "chromeos/ash/components/multidevice/logging/logging.h" #include "chromeos/ash/components/phonehub/phone_hub_manager.h" -namespace ash { -namespace eche_app { +namespace ash::eche_app { EcheNotificationClickHandler::EcheNotificationClickHandler( phonehub::PhoneHubManager* phone_hub_manager, @@ -47,6 +46,7 @@ const LaunchAppHelper::AppLaunchProhibitedReason prohibited_reason = launch_app_helper_->CheckAppLaunchProhibitedReason( feature_status_provider_->GetStatus()); + switch (prohibited_reason) { case LaunchAppHelper::AppLaunchProhibitedReason::kNotProhibited: base::UmaHistogramEnumeration( @@ -57,7 +57,7 @@ launch_app_helper_->LaunchEcheApp( notification_id, app_metadata.package_name, app_metadata.visible_app_name, app_metadata.user_id, - app_metadata.icon, + app_metadata.color_icon, phone_model_->phone_name().value_or(std::u16string()), apps_launch_info_provider_); break; @@ -95,5 +95,4 @@ status == FeatureStatus::kConnected; } -} // namespace eche_app -} // namespace ash +} // namespace ash::eche_app
diff --git a/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc b/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc index ff46b5d..24cdf4ec 100644 --- a/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc
@@ -168,7 +168,8 @@ base::HistogramTester histogram_tester; phonehub::Notification::AppMetadata app_meta_data = phonehub::Notification::AppMetadata(app_name, package_name, - /*icon=*/gfx::Image(), + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id); HandleNotificationClick(notification_id, app_meta_data);
diff --git a/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc b/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc index 2cf87742..172f9f83 100644 --- a/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc +++ b/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc
@@ -91,7 +91,7 @@ launch_app_helper_->LaunchEcheApp( /*notification_id=*/absl::nullopt, app_metadata.package_name, app_metadata.visible_app_name, app_metadata.user_id, - app_metadata.icon, + app_metadata.color_icon, phone_hub_manager_->GetPhoneModel()->phone_name().value_or( std::u16string()), apps_launch_info_provider_);
diff --git a/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc b/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc index 9f974b3..9de093b 100644 --- a/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc
@@ -191,7 +191,8 @@ const char package_name[] = "com.fakeapp"; base::HistogramTester histogram_tester; auto fake_app_metadata = phonehub::Notification::AppMetadata( - app_visible_name, package_name, gfx::Image(), + app_visible_name, package_name, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id); std::vector<phonehub::Notification::AppMetadata> app_metadata = @@ -239,7 +240,8 @@ const char16_t app_visible_name[] = u"Fake App"; const char package_name[] = "com.fakeapp"; auto fake_app_metadata = phonehub::Notification::AppMetadata( - app_visible_name, package_name, gfx::Image(), + app_visible_name, package_name, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id); // Keep notification's metadata in handler if the stream has not started yet. @@ -266,7 +268,8 @@ const char16_t app_visible_name[] = u"Fake App"; const char package_name[] = "com.fakeapp"; auto fake_app_metadata = phonehub::Notification::AppMetadata( - app_visible_name, package_name, gfx::Image(), + app_visible_name, package_name, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id); // Update notification's metadata to recents list directly when the stream is @@ -289,7 +292,8 @@ const char package_name[] = "com.fakeapp"; base::HistogramTester histogram_tester; auto fake_app_metadata = phonehub::Notification::AppMetadata( - app_visible_name, package_name, gfx::Image(), + app_visible_name, package_name, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id); SetAppLaunchProhibitedReason(
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc index 016323c..7604066 100644 --- a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc +++ b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc
@@ -673,26 +673,18 @@ // search + esc -> search + esc {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, SHOW_TASK_MANAGER}, - // shift + zoom -> shift + search + F3 - {/*trigger_on_press=*/true, ui::VKEY_F3, + // shift + zoom -> shift + search + VKEY_ZOOM + {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN, TOGGLE_FULLSCREEN}, - // zoom -> search + F3 - {/*trigger_on_press=*/true, ui::VKEY_F3, ui::EF_COMMAND_DOWN, - TOGGLE_FULLSCREEN}, - // brightness_up -> search + F6 - {/*trigger_on_press=*/true, ui::VKEY_F6, ui::EF_COMMAND_DOWN, - BRIGHTNESS_UP}, - // alt + brightness_up -> alt + search + F6 - {/*trigger_on_press=*/true, ui::VKEY_F6, - ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, KEYBOARD_BRIGHTNESS_UP}, - // When [search] is part of the original accelerator, no remapping is - // done. - // search + alt + brightness_up -> search + alt + brightness_up - {/*trigger_on_press=*/true, ui::VKEY_BRIGHTNESS_UP, - ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, KEYBOARD_BRIGHTNESS_UP}, - // search + zoom -> search + zoom + // zoom -> search + VKEY_ZOOM {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_COMMAND_DOWN, TOGGLE_FULLSCREEN}, + // brightness_up -> search + VKEY_BRIGHTNESS_UP + {/*trigger_on_press=*/true, ui::VKEY_BRIGHTNESS_UP, ui::EF_COMMAND_DOWN, + BRIGHTNESS_UP}, + // alt + brightness_up -> alt + search + VKEY_BRIGHTNESS_UP + {/*trigger_on_press=*/true, ui::VKEY_BRIGHTNESS_UP, + ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, KEYBOARD_BRIGHTNESS_UP}, }; EXPECT_EQ(3, mojo_observer.num_times_notified()); @@ -937,6 +929,7 @@ EXPECT_EQ(u"page down", ash::GetKeyDisplay(ui::VKEY_NEXT)); EXPECT_EQ(u"meta", ash::GetKeyDisplay(ui::VKEY_LWIN)); EXPECT_EQ(u"Menu", ash::GetKeyDisplay(ui::VKEY_MENU)); + EXPECT_EQ(u"MediaPlay", ash::GetKeyDisplay(ui::VKEY_MEDIA_PLAY)); } TEST_F(AcceleratorConfigurationProviderTest, NonConfigurableActions) {
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc index f691f52b..93459ad 100644 --- a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc +++ b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table.cc
@@ -54,6 +54,7 @@ {ui::KeyboardCode::VKEY_ESCAPE, u"esc"}, {ui::KeyboardCode::VKEY_RETURN, u"enter"}, {ui::KeyboardCode::VKEY_BACK, u"backspace"}, + {ui::KeyboardCode::VKEY_MEDIA_PLAY, u"MediaPlay"}, })); return *key_display_map; }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_lookup_manager.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_lookup_manager.ts index 645d256b..0886faae 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_lookup_manager.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_lookup_manager.ts
@@ -158,6 +158,7 @@ // Reset the lookup maps every time we update the accelerator mappings. this.reverseAcceleratorLookup.clear(); this.standardAcceleratorLookup.clear(); + this.textAcceleratorLookup.clear(); for (const [source, accelInfoMap] of Object.entries(acceleratorConfig)) { // When calling Object.entries on an object with optional enum keys,
diff --git a/ash/webui/shortcut_customization_ui/resources/js/fake_shortcut_provider.ts b/ash/webui/shortcut_customization_ui/resources/js/fake_shortcut_provider.ts index 10e98af..8f22414 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/fake_shortcut_provider.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/fake_shortcut_provider.ts
@@ -8,7 +8,7 @@ import {AcceleratorResultData, AcceleratorsUpdatedObserverRemote} from '../mojom-webui/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom-webui.js'; -import {Accelerator, AcceleratorConfigResult, AcceleratorSource, MojoAcceleratorConfig, MojoLayoutInfo, ShortcutProviderInterface} from './shortcut_types.js'; +import {Accelerator, AcceleratorConfig, AcceleratorConfigResult, AcceleratorSource, MojoAcceleratorConfig, MojoLayoutInfo, ShortcutProviderInterface} from './shortcut_types.js'; /** @@ -59,6 +59,10 @@ this.registerObservables(); } + triggerOnAcceleratorUpdated(): void { + this.observables.trigger(ON_ACCELERATORS_UPDATED_METHOD_NAME); + } + getAcceleratorLayoutInfos(): Promise<{layoutInfos: MojoLayoutInfo[]}> { return this.methods.resolveMethod('getAcceleratorLayoutInfos'); } @@ -79,8 +83,7 @@ addObserver(observer: AcceleratorsUpdatedObserverRemote): void { this.acceleratorsUpdatedPromise = this.observe( - ON_ACCELERATORS_UPDATED_METHOD_NAME, - (config: MojoAcceleratorConfig) => { + ON_ACCELERATORS_UPDATED_METHOD_NAME, (config: AcceleratorConfig) => { observer.onAcceleratorsUpdated(config); }); } @@ -92,7 +95,7 @@ // Set the value that will be retuned when `onAcceleratorsUpdated()` is // called. - setFakeAcceleratorsUpdated(config: MojoAcceleratorConfig[]): void { + setFakeAcceleratorsUpdated(config: AcceleratorConfig[]): void { this.observables.setObservableData( ON_ACCELERATORS_UPDATED_METHOD_NAME, config); }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.html b/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.html index 81d10d9..94e12f1 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.html +++ b/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.html
@@ -40,6 +40,11 @@ overflow: hidden; } + /* Fade out long accelerators on the left for RTL languages. */ + :host-context([dir=rtl]) #accelerators { + -webkit-mask-image: linear-gradient(to right, transparent, white 32px); + } + .accelerator-keys { align-items: center; display: flex; @@ -56,6 +61,11 @@ width: var(--cr-toolbar-icon-container-size); } + /* Flip the arrow icon for RTL languages. */ + :host-context([dir=rtl]) #actionIcon { + transform: scaleX(-1); + } + /* Bolding occurs in the JS. */ b { color: var(--cros-text-color-primary);
diff --git a/ash/wm/desks/templates/saved_desk_controller.cc b/ash/wm/desks/templates/saved_desk_controller.cc index 2595676..ce827e8 100644 --- a/ash/wm/desks/templates/saved_desk_controller.cc +++ b/ash/wm/desks/templates/saved_desk_controller.cc
@@ -105,7 +105,8 @@ .name = base::UTF8ToUTF16(base::StringPiece(kPlaceholderName))}}; } -bool SavedDeskController::LaunchAdminTemplate(const base::GUID& template_uuid) { +bool SavedDeskController::LaunchAdminTemplate(const base::GUID& template_uuid, + int64_t default_display_id) { auto admin_template = GetAdminTemplate(template_uuid); if (!admin_template) { return false;
diff --git a/ash/wm/desks/templates/saved_desk_controller.h b/ash/wm/desks/templates/saved_desk_controller.h index 43da70f2..83cbcfe 100644 --- a/ash/wm/desks/templates/saved_desk_controller.h +++ b/ash/wm/desks/templates/saved_desk_controller.h
@@ -38,8 +38,10 @@ virtual std::vector<AdminTemplateMetadata> GetAdminTemplateMetadata() const; // Launch the template identified by `template_uuid`. Returns false if the - // template doesn't exist. - virtual bool LaunchAdminTemplate(const base::GUID& template_uuid); + // template doesn't exist. By default, windows will open on the display + // identified by `default_display_id`. + virtual bool LaunchAdminTemplate(const base::GUID& template_uuid, + int64_t default_display_id); private: friend class SavedDeskControllerTestApi;
diff --git a/base/power_monitor/thermal_state_observer_mac.h b/base/power_monitor/thermal_state_observer_mac.h index 97ae1bd..a6710e0b 100644 --- a/base/power_monitor/thermal_state_observer_mac.h +++ b/base/power_monitor/thermal_state_observer_mac.h
@@ -6,7 +6,8 @@ #define BASE_POWER_MONITOR_THERMAL_STATE_OBSERVER_MAC_H_ #include <dispatch/dispatch.h> -#include <objc/objc.h> + +#include <memory> #include <IOKit/pwr_mgt/IOPMLib.h> #include "base/base_export.h" @@ -44,8 +45,10 @@ PowerThermalObserver::DeviceThermalState::kUnknown; const char* const power_notification_key_; - id thermal_state_update_observer_; int speed_limit_notification_token_ = 0; + + struct ObjCStorage; + std::unique_ptr<ObjCStorage> objc_storage_; }; } // namespace base
diff --git a/base/power_monitor/thermal_state_observer_mac.mm b/base/power_monitor/thermal_state_observer_mac.mm index 249f79e..0047f6a4 100644 --- a/base/power_monitor/thermal_state_observer_mac.mm +++ b/base/power_monitor/thermal_state_observer_mac.mm
@@ -12,6 +12,8 @@ #include <IOKit/pwr_mgt/IOPMLibDefs.h> #include <notify.h> +#include <memory> + #include "base/logging.h" #include "base/mac/scoped_cftyperef.h" #include "base/power_monitor/power_monitor.h" @@ -40,11 +42,16 @@ namespace base { +struct ThermalStateObserverMac::ObjCStorage { + id thermal_state_update_observer_ = nil; +}; + ThermalStateObserverMac::ThermalStateObserverMac( StateUpdateCallback state_update_callback, SpeedLimitUpdateCallback speed_limit_update_callback, - const char* power_notification_key) NS_AVAILABLE_MAC(10_10_3) - : power_notification_key_(power_notification_key) { + const char* power_notification_key) + : power_notification_key_(power_notification_key), + objc_storage_(std::make_unique<ObjCStorage>()) { auto on_state_change_block = ^(NSNotification* notification) { auto state = PowerThermalObserver::DeviceThermalState::kUnknown; // |thermalState| is basically a scale of power usage and its associated @@ -61,11 +68,12 @@ state_update_callback.Run(state); }; - thermal_state_update_observer_ = [[NSNotificationCenter defaultCenter] - addObserverForName:NSProcessInfoThermalStateDidChangeNotification - object:nil - queue:nil - usingBlock:on_state_change_block]; + objc_storage_->thermal_state_update_observer_ = + [[NSNotificationCenter defaultCenter] + addObserverForName:NSProcessInfoThermalStateDidChangeNotification + object:nil + queue:nil + usingBlock:on_state_change_block]; auto on_speed_change_block = ^() { int speed_limit = GetCurrentSpeedLimit(); @@ -89,12 +97,12 @@ ThermalStateObserverMac::~ThermalStateObserverMac() { [[NSNotificationCenter defaultCenter] - removeObserver:thermal_state_update_observer_]; + removeObserver:objc_storage_->thermal_state_update_observer_]; notify_cancel(speed_limit_notification_token_); } PowerThermalObserver::DeviceThermalState -ThermalStateObserverMac::GetCurrentThermalState() NS_AVAILABLE_MAC(10_10_3) { +ThermalStateObserverMac::GetCurrentThermalState() { if (state_for_testing_ != PowerThermalObserver::DeviceThermalState::kUnknown) return state_for_testing_; NSProcessInfoThermalState nsinfo_state =
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh index 33ba6a3..c59f9a8 100755 --- a/build/install-build-deps.sh +++ b/build/install-build-deps.sh
@@ -112,7 +112,9 @@ if [ 0 -eq "${do_unsupported-0}" ] && [ 0 -eq "${do_quick_check-0}" ] ; then if [[ ! $distro_codename =~ $supported_codenames && ! $distro_id =~ $supported_ids ]]; then - echo -e "ERROR: The only supported distros are\n" \ + echo -e "WARNING: The following distributions are supported, + but distributions not in the list below can also try to install + dependencies by passing the `--unsupported` parameter\n" \ "\tUbuntu 18.04 LTS (bionic with EoL April 2028)\n" \ "\tUbuntu 20.04 LTS (focal with EoL April 2030)\n" \ "\tUbuntu 22.04 LTS (jammy with EoL April 2032)\n" \
diff --git a/build/lacros/test_runner.py b/build/lacros/test_runner.py index 7786b326..ab319dec 100755 --- a/build/lacros/test_runner.py +++ b/build/lacros/test_runner.py
@@ -9,7 +9,7 @@ to setup build directory with the lacros-chrome-on-linux build configuration, and corresponding test targets are built successfully. - * Example usages: +Example usages ./build/lacros/test_runner.py test out/lacros/url_unittests ./build/lacros/test_runner.py test out/lacros/browser_tests @@ -44,6 +44,13 @@ will try to find the ash major version and Lacros major version. If ash is newer(major version larger), the runner will not run any tests and just returns success. + +Interactively debugging tests + + Any of the previous examples accept the switches + --gdb + --lldb + to run the tests in the corresponding debugger. """ import argparse @@ -431,6 +438,59 @@ os.remove(e.path) +def _LaunchDebugger(args, forward_args, test_env): + """Launches the requested debugger. + + This is used to wrap the test invocation in a debugger. It returns the + created Popen class of the debugger process. + + Args: + args (dict): Args for this script. + forward_args (list): Args to be forwarded to the test command. + test_env (dict): Computed environment variables for the test. + """ + logging.info('Starting debugger.') + + # Force the tests into single-process-test mode for debugging unless manually + # specified. Otherwise the tests will run in a child process that the debugger + # won't be attached to and the debugger won't do anything. + if not ("--single-process" in forward_args + or "--single-process-tests" in forward_args): + forward_args += ["--single-process-tests"] + + # Adding --single-process-tests can cause some tests to fail when they're + # run in the same process. Forcing the user to specify a filter will prevent + # a later error. + if not [i for i in forward_args if i.startswith("--gtest_filter")]: + logging.error("""Interactive debugging requested without --gtest_filter + +This script adds --single-process-tests to support interactive debugging but +some tests will fail in this mode unless run independently. To debug a test +specify a --gtest_filter=Foo.Bar to name the test you want to debug. +""") + sys.exit(1) + + # This code attempts to source the debugger configuration file. Some + # users will have this in their init but sourcing it more than once is + # harmless and helps people that haven't configured it. + if args.gdb: + gdbinit_file = os.path.normpath( + os.path.join(os.path.realpath(__file__), "../../../tools/gdb/gdbinit")) + debugger_command = [ + 'gdb', '--init-eval-command', 'source ' + gdbinit_file, '--args' + ] + else: + lldbinit_dir = os.path.normpath( + os.path.join(os.path.realpath(__file__), "../../../tools/lldb")) + debugger_command = [ + 'lldb', '-O', + "script sys.path[:0] = ['%s']" % lldbinit_dir, '-O', + 'script import lldbinit', '--' + ] + debugger_command += [args.command] + forward_args + return subprocess.Popen(debugger_command, env=test_env) + + def _RunTestWithAshChrome(args, forward_args): """Runs tests with ash-chrome. @@ -534,6 +594,8 @@ ash_log = None ash_log_path = None + run_tests_in_debugger = args.gdb or args.lldb + if args.ash_logging_path: ash_log_path = args.ash_logging_path # Put ash logs in a separate file on bots. @@ -544,6 +606,12 @@ if summary_file: ash_log_path = os.path.join(os.path.dirname(summary_file), 'ash_chrome.log') + elif run_tests_in_debugger: + # The debugger is unusable when all Ash logs are getting dumped to the + # same terminal. Redirect to a log file if there isn't one specified. + logging.info("Running in the debugger and --ash-logging-path is not " + + "specified, defaulting to the current directory.") + ash_log_path = 'ash_chrome.log' if ash_log_path: ash_log = open(ash_log_path, 'a') @@ -614,17 +682,21 @@ test_env['WAYLAND_DISPLAY'] = ash_wayland_socket_name test_env['EGL_PLATFORM'] = 'surfaceless' test_env['XDG_RUNTIME_DIR'] = tmp_xdg_dir_name - logging.info('Starting test process.') - test_process = subprocess.Popen([args.command] + forward_args, - env=test_env, - stdout=test_stdout, - stderr=subprocess.STDOUT) - if should_symbolize: - logging.info('Symbolizing test logs with asan symbolizer.') - test_symbolize_process = subprocess.Popen([_ASAN_SYMBOLIZER_PATH], - stdin=test_process.stdout) - # Allow test_process to receive a SIGPIPE if symbolize process exits. - test_process.stdout.close() + + if run_tests_in_debugger: + test_process = _LaunchDebugger(args, forward_args, test_env) + else: + logging.info('Starting test process.') + test_process = subprocess.Popen([args.command] + forward_args, + env=test_env, + stdout=test_stdout, + stderr=subprocess.STDOUT) + if should_symbolize: + logging.info('Symbolizing test logs with asan symbolizer.') + test_symbolize_process = subprocess.Popen([_ASAN_SYMBOLIZER_PATH], + stdin=test_process.stdout) + # Allow test_process to receive a SIGPIPE if symbolize process exits. + test_process.stdout.close() return test_process.wait() finally: @@ -740,6 +812,14 @@ help='Path to an locally built ash-chrome to use for testing. ' 'In general you should build //chrome/test:test_ash_chrome.') + debugger_group = test_parser.add_mutually_exclusive_group() + debugger_group.add_argument('--gdb', + action='store_true', + help='Run the test in GDB.') + debugger_group.add_argument('--lldb', + action='store_true', + help='Run the test in LLDB.') + # This is for version skew testing. The current CI/CQ builder builds # an ash chrome and pass it using --ash-chrome-path. In order to use the same # builder for version skew testing, we use a new argument to override @@ -764,6 +844,11 @@ help='Whether to run subprocess log outputs through the asan symbolizer.') args = arg_parser.parse_known_args() + if not hasattr(args[0], "func"): + # No command specified. + print(__doc__) + sys.exit(1) + return args[0].func(args[0], args[1])
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index 6b6ff83..280ba61 100644 --- a/buildtools/deps_revisions.gni +++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@ declare_args() { # Used to cause full rebuilds on libc++ rolls. This should be kept in sync # with the libcxx_revision vars in //DEPS. - libcxx_revision = "4156a29aabacb1365718dcc6c2d54cbe878f5e76" + libcxx_revision = "a112d60e2f99bce2892f6aa75b7a6999cdcf8961" }
diff --git a/cc/input/input_handler.cc b/cc/input/input_handler.cc index 998f685..58673c6 100644 --- a/cc/input/input_handler.cc +++ b/cc/input/input_handler.cc
@@ -127,7 +127,7 @@ bool unification_enabled = base::FeatureList::IsEnabled(features::kScrollUnification); - if (target_element_id && !scroll_state->is_main_thread_hit_tested()) { + if (target_element_id && !scroll_state->main_thread_hit_tested_reasons()) { TRACE_EVENT_INSTANT0("cc", "Latched scroll node provided", TRACE_EVENT_SCOPE_THREAD); // If the caller passed in an element_id we can skip all the hit-testing @@ -154,7 +154,7 @@ // scroll in the given direction. This mode is only used when scroll // unification is enabled and the targeted scroller comes back from a // main thread hit test. - DCHECK(scroll_state->data()->is_main_thread_hit_tested); + DCHECK(scroll_state->main_thread_hit_tested_reasons()); DCHECK(unification_enabled); starting_node = scroll_tree.FindNodeFromElementId(target_element_id); @@ -177,7 +177,7 @@ compositor_delegate_->DeviceScaleFactor()); if (unification_enabled) { - if (scroll_state->data()->is_main_thread_hit_tested) { + if (scroll_state->main_thread_hit_tested_reasons()) { // The client should have discarded the scroll when the hit test came // back with an invalid element id. If we somehow get here, we should // drop the scroll as continuing could cause us to infinitely bounce @@ -199,7 +199,9 @@ TRACE_EVENT_SCOPE_THREAD); scroll_status.thread = InputHandler::ScrollThread::SCROLL_ON_IMPL_THREAD; - scroll_status.needs_main_thread_hit_test = true; + DCHECK(scroll_hit_test.main_thread_hit_test_reasons); + scroll_status.main_thread_hit_test_reasons = + scroll_hit_test.main_thread_hit_test_reasons; return scroll_status; } @@ -325,7 +327,7 @@ // Since we provided an ElementId, there should never be a need to perform a // hit test. - DCHECK(!scroll_status.needs_main_thread_hit_test); + DCHECK(!scroll_status.main_thread_hit_test_reasons); return scroll_status; } @@ -1459,6 +1461,8 @@ // this, we have to get a hit test from the main thread. if (!IsInitialScrollHitTestReliable(layer_impl, scroller_layer)) { TRACE_EVENT_INSTANT0("cc", "Failed Hit Test", TRACE_EVENT_SCOPE_THREAD); + result.main_thread_hit_test_reasons = + MainThreadScrollingReason::kFailedHitTest; return result; } @@ -1468,6 +1472,8 @@ // failure. if (ActiveTree().PointHitsNonFastScrollableRegion(device_viewport_point, *layer_impl)) { + result.main_thread_hit_test_reasons = + MainThreadScrollingReason::kNonFastScrollableRegion; return result; } }
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h index 4589fd7..4ad1b7e 100644 --- a/cc/input/input_handler.h +++ b/cc/input/input_handler.h
@@ -207,31 +207,16 @@ InputHandler& operator=(const InputHandler&) = delete; struct ScrollStatus { - ScrollStatus() = default; - ScrollStatus(ScrollThread thread, uint32_t main_thread_scrolling_reasons) - : thread(thread), - main_thread_scrolling_reasons(main_thread_scrolling_reasons) {} - ScrollStatus(ScrollThread thread, - uint32_t main_thread_scrolling_reasons, - bool needs_main_thread_hit_test) - : thread(thread), - main_thread_scrolling_reasons(main_thread_scrolling_reasons), - needs_main_thread_hit_test(needs_main_thread_hit_test) {} ScrollThread thread = ScrollThread::SCROLL_ON_IMPL_THREAD; // This should be set to nonzero iff `thread` is SCROLL_ON_MAIN_THREAD. uint32_t main_thread_scrolling_reasons = MainThreadScrollingReason::kNotScrollingOnMain; - // TODO(crbug.com/1155758): This is a temporary workaround for GuestViews - // as they create viewport nodes and want to bubble scroll if the - // viewport cannot scroll in the given delta directions. There should be - // a parameter to ThreadInputHandler to specify whether unused delta is - // consumed by the viewport or bubbles to the parent. - bool viewport_cannot_scroll = false; - // Used only in scroll unification. Tells the caller that the input handler - // detected a case where it cannot reliably target a scroll node and needs - // the main thread to perform a hit test. - bool needs_main_thread_hit_test = false; + // Used only in scroll unification. If nonzero, it tells the caller that + // the input handler detected a case where it cannot reliably target a + // scroll node and needs the main thread to perform a hit test. + uint32_t main_thread_hit_test_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; // Used only in scroll unification. A nonzero value means we have performed // the scroll (i.e. updated the offset in the scroll tree) on the compositor @@ -241,7 +226,15 @@ // from the MainThreadScrollingReason enum. (Unification avoids setting // main_thread_scrolling_reasons, to keep that field consistent with // semantics of ScrollThread::SCROLL_ON_IMPL_THREAD.) - uint32_t main_thread_repaint_reasons = 0; + uint32_t main_thread_repaint_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; + + // TODO(crbug.com/1155758): This is a temporary workaround for GuestViews + // as they create viewport nodes and want to bubble scroll if the + // viewport cannot scroll in the given delta directions. There should be + // a parameter to ThreadInputHandler to specify whether unused delta is + // consumed by the viewport or bubbles to the parent. + bool viewport_cannot_scroll = false; }; enum class TouchStartOrMoveEventListenerType { @@ -638,6 +631,8 @@ struct ScrollHitTestResult { raw_ptr<ScrollNode> scroll_node; bool hit_test_successful; + uint32_t main_thread_hit_test_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; }; ScrollHitTestResult HitTestScrollNode( const gfx::PointF& device_viewport_point) const;
diff --git a/cc/input/scroll_state.h b/cc/input/scroll_state.h index 4b67824..85cf70b 100644 --- a/cc/input/scroll_state.h +++ b/cc/input/scroll_state.h
@@ -93,8 +93,8 @@ return data_.current_native_scrolling_element(); } - bool is_main_thread_hit_tested() const { - return data_.is_main_thread_hit_tested; + uint32_t main_thread_hit_tested_reasons() const { + return data_.main_thread_hit_tested_reasons; } ScrollStateData* data() { return &data_; }
diff --git a/cc/input/scroll_state_data.cc b/cc/input/scroll_state_data.cc index 24dfd0a..54c0e2b 100644 --- a/cc/input/scroll_state_data.cc +++ b/cc/input/scroll_state_data.cc
@@ -26,8 +26,7 @@ delta_granularity(ui::ScrollGranularity::kScrollByPrecisePixel), caused_scroll_x(false), caused_scroll_y(false), - is_scroll_chain_cut(false), - is_main_thread_hit_tested(false) {} + is_scroll_chain_cut(false) {} ScrollStateData::ScrollStateData(const ScrollStateData&) = default;
diff --git a/cc/input/scroll_state_data.h b/cc/input/scroll_state_data.h index 00b7fb9b..39a8f87 100644 --- a/cc/input/scroll_state_data.h +++ b/cc/input/scroll_state_data.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include "cc/cc_export.h" +#include "cc/input/main_thread_scrolling_reason.h" #include "cc/trees/property_tree.h" #include "ui/events/types/scroll_types.h" @@ -72,9 +73,10 @@ void set_current_native_scrolling_element(ElementId element_id); // Used in scroll unification to specify that a scroll state has been hit - // tested on the main thread. If this is true, the hit test result will be + // tested on the main thread. If this is nonzero, the hit test result will be // placed in the current_native_scrolling_element_. - bool is_main_thread_hit_tested; + uint32_t main_thread_hit_tested_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; private: // The id of the last native element to respond to a scroll, or 0 if none
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 2758dab..aa37389 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -657,8 +657,8 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const { // The output is consumed at least by // 1. DevTools for showing layer tree information for frame snapshots in - // performance timeline (third_party/devtools_frontend/src/front_end/ - // timeline_model/TracingLayerTree.js), + // performance timeline (third_party/devtools-frontend/src/front_end/ + // models/timeline_model/TracingLayerTree.ts), // 2. trace_viewer // (third_party/catapult/tracing/tracing/extras/chrome/cc/layer_impl.html) // Note that trace_viewer uses "namingStyle" style instead of
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 7db48ad..4b3b837 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -571,7 +571,8 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -586,7 +587,8 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -1348,7 +1350,8 @@ scroll_state.get(), ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ( MainThreadScrollingReason::kThreadedScrollingDisabled, host_impl_->CurrentlyScrollingNode()->main_thread_scrolling_reasons); @@ -1676,7 +1679,10 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_scrolling_reasons); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, host_impl_->CurrentlyScrollingNode()->main_thread_scrolling_reasons); @@ -1693,7 +1699,10 @@ ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_scrolling_reasons); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, host_impl_->CurrentlyScrollingNode()->main_thread_scrolling_reasons); @@ -1752,7 +1761,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -1906,7 +1916,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -1922,7 +1933,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -1987,7 +1999,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2016,7 +2029,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); GetInputHandler().ScrollUpdate(UpdateState(gfx::Point(), gfx::Vector2d(0, 1), ui::ScrollInputType::kWheel) @@ -2033,7 +2047,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2092,7 +2107,8 @@ ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2147,7 +2163,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2222,7 +2239,8 @@ ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -2278,7 +2296,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -2339,7 +2358,8 @@ ASSERT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { ASSERT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2394,7 +2414,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, @@ -2487,7 +2508,8 @@ EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -3378,7 +3400,8 @@ // We don't have a layer for the scroller but we didn't hit a non-fast // scrolling region or fail hit testing the layer - we don't need a main // thread hit test in this case. - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer, @@ -8306,10 +8329,15 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_scrolling_reasons); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, host_impl_->CurrentlyScrollingNode()->main_thread_scrolling_reasons); + EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, + status.main_thread_repaint_reasons); } else { // Scrolling fails because the content layer is asking to be scrolled on the // main thread. @@ -11991,7 +12019,8 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -12034,7 +12063,8 @@ ui::ScrollInputType::kWheel); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, @@ -17910,8 +17940,9 @@ ScrollStatus status = GetInputHandler().ScrollBegin( scroll_state.get(), ui::ScrollInputType::kWheel); - if (status.needs_main_thread_hit_test) + if (status.main_thread_hit_test_reasons) { to_be_continued_scroll_begin_ = std::move(scroll_state); + } return status; } @@ -17924,7 +17955,8 @@ std::move(to_be_continued_scroll_begin_); scroll_state->data()->set_current_native_scrolling_element(element_id); - scroll_state->data()->is_main_thread_hit_tested = true; + scroll_state->data()->main_thread_hit_tested_reasons = + MainThreadScrollingReason::kFailedHitTest; return GetInputHandler().ScrollBegin(scroll_state.get(), ui::ScrollInputType::kWheel); @@ -18018,7 +18050,8 @@ ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); // The scroll hasn't started yet though. EXPECT_FALSE(CurrentlyScrollingNode()); @@ -18031,7 +18064,8 @@ ScrollStatus status = ContinuedScrollBegin(ScrollerElementId()); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_TRUE(CurrentlyScrollingNode()); EXPECT_EQ(ScrollerNode(), CurrentlyScrollingNode()); @@ -18076,7 +18110,8 @@ { ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); - ASSERT_TRUE(status.needs_main_thread_hit_test); + ASSERT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); status = ContinuedScrollBegin(ScrollerElementId()); // Since the hit tested scroller in ContinuedScrollBegin was fully @@ -18150,7 +18185,8 @@ { ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_hit_test_reasons); } // Resolving the hit test should allow the scroller underneath to scroll as @@ -18158,7 +18194,8 @@ { ScrollStatus status = ContinuedScrollBegin(ScrollerElementId()); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_TRUE(CurrentlyScrollingNode()); EXPECT_EQ(ScrollerNode(), CurrentlyScrollingNode()); @@ -18175,7 +18212,8 @@ { ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); } } @@ -18202,8 +18240,9 @@ // test parameter. { ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10)); - if (status.needs_main_thread_hit_test) + if (status.main_thread_hit_test_reasons) { ContinuedScrollBegin(ScrollerElementId()); + } ASSERT_EQ(ScrollerNode(), CurrentlyScrollingNode());
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index c9d0e87..dd5adcd 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1613,7 +1613,8 @@ ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); impl->GetInputHandler().ScrollEnd(); } else { EXPECT_EQ(ScrollThread::SCROLL_ON_MAIN_THREAD, status.thread); @@ -1625,7 +1626,8 @@ BeginState(gfx::Point(21, 21), gfx::Vector2dF(0, 1)).get(), ui::ScrollInputType::kTouchscreen); EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, status.main_thread_scrolling_reasons); @@ -1687,7 +1689,9 @@ &scroll_state, ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(impl->CurrentlyScrollingNode(), scroller_scroll_node); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); + ; } else { // Despite the fact that we hit the scroller, which has no main thread // scrolling reason, we still must fallback to main thread scrolling due @@ -1710,7 +1714,9 @@ &scroll_state, ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); + ; EXPECT_EQ(impl->CurrentlyScrollingNode(), impl->OuterViewportScrollNode()); } else { @@ -2815,7 +2821,9 @@ // Hitting a non fast region should request a hit test from the main // thread. EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_TRUE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion, + status.main_thread_hit_test_reasons); + ; impl->GetInputHandler().ScrollEnd(); } else { // Prior to scroll unification, this forces scrolling to the main @@ -2834,7 +2842,9 @@ ui::ScrollInputType::kTouchscreen); if (base::FeatureList::IsEnabled(features::kScrollUnification)) { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); + ; } else { EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, @@ -2854,7 +2864,9 @@ // layer is scrollable from the compositor thread so no need to involve // the main thread. EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread); - EXPECT_FALSE(status.needs_main_thread_hit_test); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_hit_test_reasons); + ; EXPECT_EQ(scroll_node, impl->CurrentlyScrollingNode()); impl->GetInputHandler().ScrollEnd(); } else {
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java index e1af1ad..48692ba 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java
@@ -57,9 +57,8 @@ import org.chromium.ui.resources.ResourceManager; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.LinkedList; +import java.util.Collections; import java.util.List; import java.util.Locale; @@ -253,7 +252,7 @@ LayoutTab sourceLayoutTab = createLayoutTab( mTabModelSelector.getCurrentTabId(), mTabModelSelector.isIncognitoSelected()); sourceLayoutTab.setDecorationAlpha(0); - + updateCacheVisibleIds(Collections.singletonList(mTabModelSelector.getCurrentTabId())); mLayoutTabs = new LayoutTab[] {sourceLayoutTab}; boolean quick; @@ -375,7 +374,9 @@ sourceLayoutTab.setDecorationAlpha(0); List<LayoutTab> layoutTabs = new ArrayList<>(); + List<Integer> tabIds = new ArrayList<>(); layoutTabs.add(sourceLayoutTab); + tabIds.add(sourceLayoutTab.getId()); if (sourceTabId != mTabModelSelector.getCurrentTabId()) { // Keep the original tab in mLayoutTabs to unblock thumbnail taking at the end of @@ -385,10 +386,10 @@ originalTab.setScale(0); originalTab.setDecorationAlpha(0); layoutTabs.add(originalTab); + tabIds.add(originalTab.getId()); } mLayoutTabs = layoutTabs.toArray(new LayoutTab[0]); - - updateCacheVisibleIds(new LinkedList<>(Arrays.asList(sourceTabId))); + updateCacheVisibleIds(tabIds); mIsAnimatingHide = true; if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext())) {
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherCoordinator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherCoordinator.java index 5f48e48..5d7c133 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherCoordinator.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherCoordinator.java
@@ -183,8 +183,17 @@ public void setVisibility(boolean isVisible) { if (!mIsTablet) return; - mContainer.setVisibility(isVisible ? View.VISIBLE : View.GONE); - mMediatorOnTablet.setVisibility(isVisible); + boolean visible = mMediatorOnTablet.setVisibility(isVisible); + mContainer.setVisibility(visible ? View.VISIBLE : View.GONE); + } + + /** + * Update the most recent tab to track in the single tab card. + * @param tabToTrack The tab to track as the most recent tab. + */ + public void updateTrackingTab(Tab tabToTrack) { + assert mIsTablet; + mMediatorOnTablet.setTab(tabToTrack); } @VisibleForTesting
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherOnTabletMediator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherOnTabletMediator.java index f1d96bb..1cd1d379 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherOnTabletMediator.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherOnTabletMediator.java
@@ -21,6 +21,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider; +import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.url.GURL; @@ -38,24 +39,22 @@ mTabListFaviconProvider = tabListFaviconProvider; mMostRecentTab = mostRecentTab; - if (mMostRecentTab != null) { - mPropertyModel.set(CLICK_LISTENER, v -> { - TabModel currentTabModel = tabModelSelector.getModel(false); - TabModelUtils.setIndex(currentTabModel, - TabModelUtils.getTabIndexById(currentTabModel, mMostRecentTab.getId()), - false); - }); - } + mPropertyModel.set(CLICK_LISTENER, v -> { + TabModel currentTabModel = tabModelSelector.getModel(false); + TabModelUtils.setIndex(currentTabModel, + TabModelUtils.getTabIndexById(currentTabModel, mMostRecentTab.getId()), false); + }); } /** * Set the visibility of the single tab card of the {@link NewTabPageLayout} on tablet. * @param isVisible Whether the single tab card is visible. + * @return Whether the single tab card has been set visible. */ - void setVisibility(boolean isVisible) { + boolean setVisibility(boolean isVisible) { if (!isVisible || mMostRecentTab == null) { mPropertyModel.set(IS_VISIBLE, false); - return; + return false; } if (!mInitialized) { mInitialized = true; @@ -63,6 +62,7 @@ updateFavicon(); } mPropertyModel.set(IS_VISIBLE, true); + return true; } boolean isVisible() { @@ -70,6 +70,28 @@ } /** + * Update the most recent tab to track in the single tab card. + * @param tabToTrack The tab to track as the most recent tab. + */ + void setTab(Tab tabToTrack) { + if (UrlUtilities.isNTPUrl(tabToTrack.getUrl())) { + tabToTrack = null; + } + + if (mMostRecentTab == tabToTrack) return; + + if (tabToTrack == null) { + mMostRecentTab = null; + mPropertyModel.set(TITLE, ""); + mPropertyModel.set(FAVICON, mTabListFaviconProvider.getDefaultFaviconDrawable(false)); + } else { + mMostRecentTab = tabToTrack; + updateTitle(); + updateFavicon(); + } + } + + /** * Update the favicon of the single tab switcher. */ private void updateFavicon() {
diff --git a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/tasks/SingleTabSwitcherOnTabletMediatorUnitTest.java b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/tasks/SingleTabSwitcherOnTabletMediatorUnitTest.java index 58705456..8a8efe1 100644 --- a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/tasks/SingleTabSwitcherOnTabletMediatorUnitTest.java +++ b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/tasks/SingleTabSwitcherOnTabletMediatorUnitTest.java
@@ -119,7 +119,7 @@ public void testWhenMostRecentTabIsNull() { SingleTabSwitcherOnTabletMediator mediator = new SingleTabSwitcherOnTabletMediator( mPropertyModel, mTabModelSelector, mTabListFaviconProvider, null); - assertNull(mPropertyModel.get(CLICK_LISTENER)); + assertNotNull(mPropertyModel.get(CLICK_LISTENER)); mediator.setVisibility(true); @@ -156,6 +156,7 @@ public void testUpdateSingleTabSwitcherTitleOnTablet() { doReturn(true).when(mTab3).isLoading(); doReturn("").when(mTab3).getTitle(); + doReturn(mUrl).when(mTab3).getUrl(); SingleTabSwitcherOnTabletMediator mediator = new SingleTabSwitcherOnTabletMediator( mPropertyModel, mTabModelSelector, mTabListFaviconProvider, mTab3); mediator.updateTitle();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java index d0c8e90..85e3412 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java
@@ -53,9 +53,8 @@ import org.chromium.ui.resources.ResourceManager; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.LinkedList; +import java.util.Collections; import java.util.List; import java.util.Locale; @@ -222,7 +221,7 @@ LayoutTab sourceLayoutTab = createLayoutTab( mTabModelSelector.getCurrentTabId(), mTabModelSelector.isIncognitoSelected()); sourceLayoutTab.setDecorationAlpha(0); - + updateCacheVisibleIds(Collections.singletonList(mTabModelSelector.getCurrentTabId())); mLayoutTabs = new LayoutTab[] {sourceLayoutTab}; boolean quick = mGridTabListDelegate.prepareTabSwitcherView(); @@ -300,7 +299,9 @@ sourceLayoutTab.setDecorationAlpha(0); List<LayoutTab> layoutTabs = new ArrayList<>(); + List<Integer> tabIds = new ArrayList<>(); layoutTabs.add(sourceLayoutTab); + tabIds.add(sourceLayoutTab.getId()); if (sourceTabId != mTabModelSelector.getCurrentTabId()) { // Keep the original tab in mLayoutTabs to unblock thumbnail taking at the end of @@ -310,10 +311,10 @@ originalTab.setScale(0); originalTab.setDecorationAlpha(0); layoutTabs.add(originalTab); + tabIds.add(originalTab.getId()); } mLayoutTabs = layoutTabs.toArray(new LayoutTab[0]); - - updateCacheVisibleIds(new LinkedList<>(Arrays.asList(sourceTabId))); + updateCacheVisibleIds(tabIds); mIsAnimatingHide = true; if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext())) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java index 441d516..fa82583 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java
@@ -36,6 +36,7 @@ contentLayout.addView(contentView); contentLayout.setBackgroundResource(R.drawable.bg_white_dialog); + contentLayout.setClipToOutline(true); // We need an outer layout for two things: // * centering the content
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index 94dfa38f..57da77e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -871,8 +871,8 @@ @Override public void destroy() { assert !mIsDestroyed; - assert !ViewCompat - .isAttachedToWindow(getView()) : "Destroy called before removed from window"; + assert !ViewCompat.isAttachedToWindow(getView()) + : "Destroy called before removed from window"; if (mIsLoaded && !mTab.isHidden()) recordNTPHidden(); mNewTabPageManager.onDestroy(); @@ -1056,6 +1056,11 @@ public void showHomeSurfaceUi() { if (mSingleTabSwitcherCoordinator == null) { initializeSingleTabCard(); + } else { + Tab mostRecentTab = + TabModelUtils.getMostRecentTab(mTabModelSelector.getModel(false), mTab.getId()); + mSingleTabSwitcherCoordinator.updateTrackingTab(mostRecentTab); + setSingleTabCardVisibility(true); } } @@ -1083,7 +1088,7 @@ private void initializeSingleTabCardImpl() { Tab mostRecentTab = TabModelUtils.getMostRecentTab(mTabModelSelector.getModel(false), mTab.getId()); - if (mostRecentTab == null) { + if (mostRecentTab == null || UrlUtilities.isNTPUrl(mostRecentTab.getUrl())) { return; } mSingleTabCardContainer = (FrameLayout) ((ViewStub) mNewTabPageLayout.findViewById(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index ca065ed6..9912ef6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -83,6 +83,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tab.TabSelectionType; +import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.chrome.browser.util.BrowserUiUtils; import org.chromium.chrome.browser.util.BrowserUiUtils.ModuleTypeOnStartAndNTP; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; @@ -104,6 +105,7 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestTouchUtils; import org.chromium.content_public.browser.test.util.TouchCommon; +import org.chromium.content_public.common.ContentUrlConstants; import org.chromium.net.test.EmbeddedTestServer; import org.chromium.net.test.util.TestWebServer; import org.chromium.ui.base.PageTransition; @@ -813,6 +815,40 @@ } /** + * Test whether the clicking action on the profile button in {@link NewTabPage} is been + * recorded in histogram correctly. + */ + @Test + @SmallTest + public void testRecordHistogramProfileButtonClick_Ntp() { + HistogramWatcher histogramWatcher = HistogramWatcher.newSingleRecordWatcher( + HISTOGRAM_NTP_MODULE_CLICK, BrowserUiUtils.ModuleTypeOnStartAndNTP.PROFILE_BUTTON); + onView(withId(R.id.optional_toolbar_button)).perform(click()); + histogramWatcher.assertExpected(HISTOGRAM_NTP_MODULE_CLICK + + " is not recorded correctly when click on the profile button."); + } + + /** + * Test whether the clicking action on Logo in {@link NewTabPage} is been recorded in + * histogram correctly. + */ + @Test + @SmallTest + @Feature({"NewTabPage"}) + public void testRecordHistogramLogoClick_Ntp() { + mJniMocker.mock(LogoBridgeJni.TEST_HOOKS, mLogoBridgeJniMock); + NewTabPageLayout ntpLayout = mNtp.getNewTabPageLayout(); + LogoCoordinator logoCoordinator = ntpLayout.getLogoCoordinatorForTesting(); + logoCoordinator.setLogoBridgeForTesting(mLogoBridge); + logoCoordinator.setOnLogoClickUrlForTesting(TEST_URL); + HistogramWatcher histogramWatcher = HistogramWatcher.newSingleRecordWatcher( + HISTOGRAM_NTP_MODULE_CLICK, ModuleTypeOnStartAndNTP.DOODLE); + TestThreadUtils.runOnUiThreadBlocking(() -> logoCoordinator.onLogoClickedForTesting(true)); + histogramWatcher.assertExpected(HISTOGRAM_NTP_MODULE_CLICK + + " is not recorded correctly when click on Logo with doodle enabled."); + } + + /** * Test show and click on the single tab card on the {@link NewTabPage} in the tablet. */ @Test @@ -917,37 +953,102 @@ } /** - * Test whether the clicking action on the profile button in {@link NewTabPage} is been - * recorded in histogram correctly. + * Test update the most recent tab of the single tab card with the regular tab information. */ @Test - @SmallTest - public void testRecordHistogramProfileButtonClick_Ntp() { - HistogramWatcher histogramWatcher = HistogramWatcher.newSingleRecordWatcher( - HISTOGRAM_NTP_MODULE_CLICK, BrowserUiUtils.ModuleTypeOnStartAndNTP.PROFILE_BUTTON); - onView(withId(R.id.optional_toolbar_button)).perform(click()); - histogramWatcher.assertExpected(HISTOGRAM_NTP_MODULE_CLICK - + " is not recorded correctly when click on the profile button."); + @MediumTest + @Feature({"NewTabPage"}) + public void testSingleTabCardUpdateMostRecentTab_NotNtp() { + ChromeTabbedActivity activity = mActivityTestRule.getActivity(); + mActivityTestRule.loadUrl(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL); + Tab originalMostRecentTab = activity.getActivityTab(); + Tab tab = mActivityTestRule.loadUrlInNewTab(UrlConstants.NTP_URL); + NewTabPageTestUtils.waitForNtpLoaded(tab); + NewTabPage ntp = (NewTabPage) tab.getNativePage(); + NewTabPageLayout ntpLayout = ntp.getNewTabPageLayout(); + + TestThreadUtils.runOnUiThreadBlocking(ntp::showHomeSurfaceUi); + + View singleTabCardView = ntpLayout.findViewById(R.id.single_tab_view); + assertEquals("The single tab card is still invisible after initialization.", View.VISIBLE, + singleTabCardView.getVisibility()); + TextView title = singleTabCardView.findViewById(R.id.tab_title_view); + TestThreadUtils.runOnUiThreadBlocking(() -> { + String originalMostRecentTabTitleForCheck = originalMostRecentTab.getTitle(); + assertEquals("The title of the single tab card is wrong after initialization.", + originalMostRecentTabTitleForCheck, title.getText()); + }); + + Tab newMostRecentTab = mActivityTestRule.loadUrlInNewTab(TEST_URL); + TestThreadUtils.runOnUiThreadBlocking(() -> { + TabModelUtils.setIndex(activity.getCurrentTabModel(), + TabModelUtils.getTabIndexById(activity.getCurrentTabModel(), tab.getId()), + false); + ntp.showHomeSurfaceUi(); + }); + + assertEquals("The single tab card is invisible after updating the single tab card.", + View.VISIBLE, singleTabCardView.getVisibility()); + TextView newTitle = singleTabCardView.findViewById(R.id.tab_title_view); + TestThreadUtils.runOnUiThreadBlocking(() -> { + String newMostRecentTabTitleForCheck = newMostRecentTab.getTitle(); + assertEquals("The title of the single tab card is wrong after updating.", + newMostRecentTabTitleForCheck, newTitle.getText()); + }); } /** - * Test whether the clicking action on Logo in {@link NewTabPage} is been recorded in - * histogram correctly. + * Test update the most recent tab of the single tab card with the new tab page information. */ @Test - @SmallTest + @MediumTest @Feature({"NewTabPage"}) - public void testRecordHistogramLogoClick_Ntp() { - mJniMocker.mock(LogoBridgeJni.TEST_HOOKS, mLogoBridgeJniMock); - NewTabPageLayout ntpLayout = mNtp.getNewTabPageLayout(); - LogoCoordinator logoCoordinator = ntpLayout.getLogoCoordinatorForTesting(); - logoCoordinator.setLogoBridgeForTesting(mLogoBridge); - logoCoordinator.setOnLogoClickUrlForTesting(TEST_URL); - HistogramWatcher histogramWatcher = HistogramWatcher.newSingleRecordWatcher( - HISTOGRAM_NTP_MODULE_CLICK, ModuleTypeOnStartAndNTP.DOODLE); - TestThreadUtils.runOnUiThreadBlocking(() -> logoCoordinator.onLogoClickedForTesting(true)); - histogramWatcher.assertExpected(HISTOGRAM_NTP_MODULE_CLICK - + " is not recorded correctly when click on Logo with doodle enabled."); + public void testSingleTabCardUpdateMostRecentTab_Ntp() { + ChromeTabbedActivity activity = mActivityTestRule.getActivity(); + mActivityTestRule.loadUrl(TEST_URL); + Tab originalMostRecentTab = activity.getActivityTab(); + Tab tab = mActivityTestRule.loadUrlInNewTab(UrlConstants.NTP_URL); + NewTabPageTestUtils.waitForNtpLoaded(tab); + NewTabPage ntp = (NewTabPage) tab.getNativePage(); + NewTabPageLayout ntpLayout = ntp.getNewTabPageLayout(); + + TestThreadUtils.runOnUiThreadBlocking(ntp::showHomeSurfaceUi); + + ViewGroup singleTabCardViewContainer = + ntpLayout.findViewById(R.id.tab_switcher_module_container); + assertEquals("The single tab card container is still invisible after initialization.", + View.VISIBLE, singleTabCardViewContainer.getVisibility()); + View singleTabCardView = ntpLayout.findViewById(R.id.single_tab_view); + assertEquals("The single tab card is still invisible after initialization.", View.VISIBLE, + singleTabCardView.getVisibility()); + TextView title = singleTabCardView.findViewById(R.id.tab_title_view); + TestThreadUtils.runOnUiThreadBlocking(() -> { + String originalMostRecentTabTitleForCheck = originalMostRecentTab.getTitle(); + assertEquals("The title of the single tab card is wrong after initialization.", + originalMostRecentTabTitleForCheck, title.getText()); + }); + + mActivityTestRule.loadUrlInNewTab(UrlConstants.NTP_URL); + TestThreadUtils.runOnUiThreadBlocking(() -> { + TabModelUtils.setIndex(activity.getCurrentTabModel(), + TabModelUtils.getTabIndexById(activity.getCurrentTabModel(), tab.getId()), + false); + ntp.showHomeSurfaceUi(); + }); + + assertEquals("The single tab card container is still visible after updating with " + + "the new tab page information.", + View.GONE, singleTabCardViewContainer.getVisibility()); + assertEquals("The single tab card is still visible after updating with the new tab " + + "page information.", + View.GONE, singleTabCardView.getVisibility()); + TextView new_title = singleTabCardView.findViewById(R.id.tab_title_view); + TestThreadUtils.runOnUiThreadBlocking(() -> { + String newMostRecentTabTitleForCheck = ""; + assertEquals("The title of the single tab card is wrong after updating with " + + "the new tab page information.", + newMostRecentTabTitleForCheck, new_title.getText()); + }); } private void captureThumbnail() {
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 425813c9..daaefb1 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -2940,6 +2940,15 @@ desc="Accessibility label for retry button."> Retry <ph name="FILE_NAME">$1<ex>bla.exe</ex></ph> </message> + <message name="IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW" desc="Text shown on the download bubble to allow users to never show the bubble at download completion"> + Don't show when downloads are done + </message> + <message name="IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_REMINDER" desc="Text shown on the download bubble to remind users they can customize whether the bubble appears from Chrome settings"> + You can change this anytime in <ph name="SETTINGS_LINK">$1<ex>settings</ex></ph> + </message> + <message name="IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_LINK" desc="Link text to Chrome settings in the download bubble, within IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_REMINDER"> + settings + </message> <!-- Tailored Warning in Download Bubble --> <message name="IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_COOKIE_THEFT"
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW.png.sha1 new file mode 100644 index 0000000..c7339829 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW.png.sha1
@@ -0,0 +1 @@ +52a9998beb382fb58a0983a1a1b084e05148b288 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_LINK.png.sha1 new file mode 100644 index 0000000..c7339829 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_LINK.png.sha1
@@ -0,0 +1 @@ +52a9998beb382fb58a0983a1a1b084e05148b288 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_REMINDER.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_REMINDER.png.sha1 new file mode 100644 index 0000000..c7339829 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_REMINDER.png.sha1
@@ -0,0 +1 @@ +52a9998beb382fb58a0983a1a1b084e05148b288 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index fa9fd16..8636b6b2 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -22,6 +22,9 @@ <message name="IDS_SETTINGS_LEARN_MORE" desc="The label in the settings UI if users can obtain more information."> Learn more </message> + <message name="IDS_OS_SETTINGS_OPENS_IN_NEW_TAB_A11Y_LABEL" desc="ARIA (accessibility) label describing an external link which opens in a new tab."> + Opens in new tab + </message> <!--Main Page--> <message name="IDS_SETTINGS_SECONDARY_USER_BANNER" desc="Banner displayed in settings page when the user is secondary in a multi-profile session."> @@ -1189,12 +1192,39 @@ <message name="IDS_SETTINGS_CHROMEVOX_MENU_ENABLE_EVENT_STREAM_LOGGING" desc="In the ChromeVox settings subpage, under developer options the label for the toggle that enables event stream logging."> Enable event stream logging </message> + <message name="IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_DESCRIPTION" desc="In the ChromeVox settings subpage, the label for the braille table type list box and braille table selection list box. A braille table describes how text gets converted from a unicode encoding into a pattern of dots. This varies based on locale and contraction. See http://en.wikipedia.org/wiki/Braille for more."> + Select a braille table + </message> + <message name="IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_6_DOT" desc="In the ChromeVox settings subpage, the label for the braille table type list item for 6-dot braille. A braille table describes how text gets converted from a unicode encoding into a pattern of dots. This varies based on locale and contraction. See http://en.wikipedia.org/wiki/Braille for more."> + 6-dot + </message> + <message name="IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_8_DOT" desc="In the ChromeVox settings subpage, the label for the braille table type list item for 8-dot braille. A braille table describes how text gets converted from a unicode encoding into a pattern of dots. This varies based on locale and contraction. See http://en.wikipedia.org/wiki/Braille for more."> + 8-dot + </message> <message name="IDS_SETTINGS_CHROMEVOX_BRAILLE_WORD_WRAP" desc="In the ChromeVox settings subpage, the label for the toggle that enables wrapping of words if a whole line doesn't fit on a braille display. When this option is enabled, an effort is made to keep the characters of words together on the display. Otherwise, as many characters as possible are put on each braille display line, possible splitting words between lines."> Enable word wrap </message> <message name="IDS_SETTINGS_CHROMEVOX_MENU_BRAILLE_COMMANDS" desc="In the ChromeVox settings subpage, the label for the toggle that enables displaying Perkins Brailler commands in the ChromeVox menus."> Show braille commands in the ChromeVox menus </message> + <message name="IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECT" desc="Labels a button which when pressed, connects to a selected bluetooth braille display."> + Connect + </message> + <message name="IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_DISCONNECT" desc="Labels a button which when pressed, disconnects from a selected bluetooth braille display."> + Disconnect + </message> + <message name="IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECTING" desc="Labels a button which is disabled and indicates the system is connecting to a bluetooth braille display."> + Connecting + </message> + <message name="IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_FORGET" desc="Labels a button which when pressed, forgets the selected bluetooth braille display."> + Forget + </message> + <message name="IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_PINCODE_LABEL" desc="Labels a text field which prompts the user for a pincode when pairing a bluetooth braille display."> + Please enter a pin + </message> + <message name="IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_SELECT_LABEL" desc="Labels a select control which lists all bluetooth braille displays."> + Select a bluetooth braille display + </message> <message name="IDS_SETTINGS_CHROMEVOX_VIRTUAL_BRAILLE_DISPLAY" desc="In the ChromeVox settings subpage, a section header for options about the ChromeVox virtual braille display. This section lets users change the rows, columns, and display style of the virtual braille display."> Virtual Braille Display </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_OPENS_IN_NEW_TAB_A11Y_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_OPENS_IN_NEW_TAB_A11Y_LABEL.png.sha1 new file mode 100644 index 0000000..012077c --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_OPENS_IN_NEW_TAB_A11Y_LABEL.png.sha1
@@ -0,0 +1 @@ +f0584402ff919354996ceed2c2983b0ab79ff3be \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECT.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECT.png.sha1 new file mode 100644 index 0000000..5344205 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECT.png.sha1
@@ -0,0 +1 @@ +ae27d3394e0df8d8cf9377d4acd5fcae931ff2f6 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECTING.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECTING.png.sha1 new file mode 100644 index 0000000..8a67581 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECTING.png.sha1
@@ -0,0 +1 @@ +38a2a0ea6e3a4d0e57b8c4332face04e20587949 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_DISCONNECT.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_DISCONNECT.png.sha1 new file mode 100644 index 0000000..af3d3e0 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_DISCONNECT.png.sha1
@@ -0,0 +1 @@ +4ded663a6af6dcbcf10b3e6aebcffe6bd741b311 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_FORGET.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_FORGET.png.sha1 new file mode 100644 index 0000000..5344205 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_FORGET.png.sha1
@@ -0,0 +1 @@ +ae27d3394e0df8d8cf9377d4acd5fcae931ff2f6 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_PINCODE_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_PINCODE_LABEL.png.sha1 new file mode 100644 index 0000000..6d0fce2 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_PINCODE_LABEL.png.sha1
@@ -0,0 +1 @@ +056e734aa6ea29f685ea2cbfc40af956b3a56499 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_SELECT_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_SELECT_LABEL.png.sha1 new file mode 100644 index 0000000..5344205 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_SELECT_LABEL.png.sha1
@@ -0,0 +1 @@ +ae27d3394e0df8d8cf9377d4acd5fcae931ff2f6 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_6_DOT.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_6_DOT.png.sha1 new file mode 100644 index 0000000..4ad71a4 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_6_DOT.png.sha1
@@ -0,0 +1 @@ +970cca08379269d713c4adb7f5c292295ca9faac \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_8_DOT.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_8_DOT.png.sha1 new file mode 100644 index 0000000..4ad71a4 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_8_DOT.png.sha1
@@ -0,0 +1 @@ +970cca08379269d713c4adb7f5c292295ca9faac \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_DESCRIPTION.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..4ad71a4 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +970cca08379269d713c4adb7f5c292295ca9faac \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 8f91c97..97872091 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -840,8 +840,6 @@ "navigation_predictor/navigation_predictor_preconnect_client.h", "navigation_predictor/search_engine_preconnector.cc", "navigation_predictor/search_engine_preconnector.h", - "net/cert_verifier_configuration.cc", - "net/cert_verifier_configuration.h", "net/chrome_mojo_proxy_resolver_factory.cc", "net/chrome_mojo_proxy_resolver_factory.h", "net/chrome_network_delegate.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index b2c9494b..1a9d02f 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -7807,6 +7807,15 @@ flag_descriptions::kSearchResultInlineIconDescription, kOsCrOS, FEATURE_VALUE_TYPE(app_list_features::kSearchResultInlineIcon)}, + {"smds-support", flag_descriptions::kSmdsSupportName, + flag_descriptions::kSmdsSupportDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kSmdsSupport)}, + + {"smds-support-euicc-upload", + flag_descriptions::kSmdsSupportEuiccUploadName, + flag_descriptions::kSmdsSupportEuiccUploadDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kSmdsSupportEuiccUpload)}, + {"smds-dbus-migration", flag_descriptions::kSmdsDbusMigrationName, flag_descriptions::kSmdsDbusMigrationDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kSmdsDbusMigration)},
diff --git a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc index 7878a73e..90859e1 100644 --- a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc +++ b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
@@ -268,6 +268,10 @@ enabled = ::features::IsAccessibilityDeprecateChromeVoxTabsEnabled(); break; case accessibility_private::AccessibilityFeature:: + ACCESSIBILITY_FEATURE_CHROMEVOXSETTINGSMIGRATION: + enabled = ::features::IsAccessibilityChromeVoxPageMigrationEnabled(); + break; + case accessibility_private::AccessibilityFeature:: ACCESSIBILITY_FEATURE_NONE: return RespondNow(Error("Unrecognized feature")); }
diff --git a/chrome/browser/android/compositor/layer/content_layer.cc b/chrome/browser/android/compositor/layer/content_layer.cc index 57edf426..992b17d 100644 --- a/chrome/browser/android/compositor/layer/content_layer.cc +++ b/chrome/browser/android/compositor/layer/content_layer.cc
@@ -24,10 +24,11 @@ static void SetOpacityOnLeaf(scoped_refptr<cc::slim::Layer> layer, float alpha) { const auto& children = layer->children(); - if (children.size() > 0) { + if (!children.empty()) { layer->SetOpacity(1.0f); - for (uint i = 0; i < children.size(); ++i) - SetOpacityOnLeaf(children[i], alpha); + for (const auto& child : children) { + SetOpacityOnLeaf(child, alpha); + } } else { layer->SetOpacity(alpha); } @@ -35,24 +36,29 @@ static cc::slim::Layer* GetDrawsContentLeaf( scoped_refptr<cc::slim::Layer> layer) { - if (!layer.get()) + if (!layer.get()) { return nullptr; + } // If the subtree is hidden, then any layers in this tree will not be drawn. - if (layer->hide_layer_and_subtree()) + if (layer->hide_layer_and_subtree()) { return nullptr; + } - if (layer->opacity() == 0.0f) + if (layer->opacity() == 0.0f) { return nullptr; + } - if (layer->draws_content()) + if (layer->draws_content()) { return layer.get(); + } const auto& children = layer->children(); - for (unsigned i = 0; i < children.size(); i++) { - cc::slim::Layer* leaf = GetDrawsContentLeaf(children[i]); - if (leaf) + for (const auto& child : children) { + cc::slim::Layer* leaf = GetDrawsContentLeaf(child); + if (leaf) { return leaf; + } } return nullptr; } @@ -67,16 +73,18 @@ const gfx::Rect& clip) { scoped_refptr<cc::slim::Layer> live_layer = tab_content_manager_->GetLiveLayer(id); - if (live_layer) + if (live_layer) { live_layer->SetHideLayerAndSubtree(!can_use_live_layer); + } bool live_layer_draws = GetDrawsContentLeaf(live_layer); float content_opacity = should_override_content_alpha ? content_alpha_override : 1.0f; float static_opacity = should_override_content_alpha ? content_alpha_override : 1.0f; - if (live_layer_draws) + if (live_layer_draws) { static_opacity = static_to_view_blend; + } layer_->RemoveAllChildren(); @@ -89,14 +97,15 @@ } if (static_opacity > 0) { - scoped_refptr<ThumbnailLayer> static_layer = + ThumbnailLayer* static_layer = tab_content_manager_->GetOrCreateStaticLayer(id, !live_layer_draws); - if (static_layer.get()) { + if (static_layer) { static_layer->layer()->SetIsDrawable(true); - if (should_clip) + if (should_clip) { static_layer->Clip(clip); - else + } else { static_layer->ClearClip(); + } SetOpacityOnLeaf(static_layer->layer(), static_opacity); std::vector<cc::slim::Filter> filters; @@ -115,13 +124,14 @@ scoped_refptr<cc::slim::Layer> live_layer = tab_content_manager_->GetLiveLayer(id); cc::slim::Layer* leaf_that_draws = GetDrawsContentLeaf(live_layer); - if (leaf_that_draws) + if (leaf_that_draws) { size.SetToMax(leaf_that_draws->bounds()); + } - scoped_refptr<ThumbnailLayer> static_layer = - tab_content_manager_->GetStaticLayer(id); - if (static_layer.get() && GetDrawsContentLeaf(static_layer->layer())) + ThumbnailLayer* static_layer = tab_content_manager_->GetStaticLayer(id); + if (static_layer && GetDrawsContentLeaf(static_layer->layer())) { size.SetToMax(static_layer->layer()->bounds()); + } return size; } @@ -134,7 +144,6 @@ : layer_(cc::slim::Layer::Create()), tab_content_manager_(tab_content_manager) {} -ContentLayer::~ContentLayer() { -} +ContentLayer::~ContentLayer() = default; } // namespace android
diff --git a/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc index 66ab55f..72a847c 100644 --- a/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc +++ b/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc
@@ -28,8 +28,7 @@ background_color_(SK_ColorWHITE), brightness_(1.f) {} -StaticTabSceneLayer::~StaticTabSceneLayer() { -} +StaticTabSceneLayer::~StaticTabSceneLayer() = default; bool StaticTabSceneLayer::ShouldShowBackground() { scoped_refptr<cc::slim::Layer> root = layer_->RootLayer(); @@ -40,17 +39,16 @@ return background_color_; } -void StaticTabSceneLayer::UpdateTabLayer( - JNIEnv* env, - const JavaParamRef<jobject>& jobj, - jint id, - jboolean can_use_live_layer, - jint default_background_color, - jfloat x, - jfloat y, - jfloat static_to_view_blend, - jfloat saturation, - jfloat brightness) { +void StaticTabSceneLayer::UpdateTabLayer(JNIEnv* env, + const JavaParamRef<jobject>& jobj, + jint id, + jboolean can_use_live_layer, + jint default_background_color, + jfloat x, + jfloat y, + jfloat static_to_view_blend, + jfloat saturation, + jfloat brightness) { DCHECK(tab_content_manager_) << "TabContentManager must be set before updating the layer"; @@ -66,10 +64,10 @@ bool should_override_content_alpha = last_set_tab_id_ != id; last_set_tab_id_ = id; - content_layer_->SetProperties( - id, can_use_live_layer, static_to_view_blend, - should_override_content_alpha, content_alpha_override, saturation, - false, gfx::Rect()); + content_layer_->SetProperties(id, can_use_live_layer, static_to_view_blend, + should_override_content_alpha, + content_alpha_override, saturation, false, + gfx::Rect()); content_layer_->layer()->SetPosition(gfx::PointF(x, y)); content_layer_->layer()->SetIsDrawable(true);
diff --git a/chrome/browser/android/compositor/tab_content_manager.cc b/chrome/browser/android/compositor/tab_content_manager.cc index f7a60be..2f409362 100644 --- a/chrome/browser/android/compositor/tab_content_manager.cc +++ b/chrome/browser/android/compositor/tab_content_manager.cc
@@ -13,8 +13,10 @@ #include "base/android/callback_android.h" #include "base/android/jni_android.h" +#include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" +#include "base/containers/contains.h" #include "base/cxx17_backports.h" #include "base/feature_list.h" #include "base/functional/bind.h" @@ -170,18 +172,28 @@ return live_layer_list_[tab_id]; } -scoped_refptr<ThumbnailLayer> TabContentManager::GetStaticLayer(int tab_id) { - return static_layer_cache_[tab_id]; +ThumbnailLayer* TabContentManager::GetStaticLayer(int tab_id) { + if (tab_id == -1) { + return nullptr; + } + auto it = static_layer_cache_.find(tab_id); + if (base::FeatureList::IsEnabled(thumbnail::kThumbnailCacheRefactor)) { + // Use a DCHECK to try to prevent this from happening during development, + // but it is not guranteed that every possible failure case was eliminated + // when adding this CHECK so leave as a DCHECK of now. + DCHECK(it != static_layer_cache_.end()) + << "Static layer should be created with UpdateVisibleIds before being" + "requested"; + } + return it == static_layer_cache_.end() ? nullptr : it->second.get(); } -// TODO(crbug.com/1402843): ThumbnailCache::PruneCache() shouldn't cause issues -// with `static_layer_cache_` as Thumbnails referenced by this cache may already -// expire even without eager pruning. Investigate whether entries in -// `static_layer_cache_` can and should be removed when their thumbnail is -// dropped from the ThumbnailCache. -scoped_refptr<ThumbnailLayer> TabContentManager::GetOrCreateStaticLayer( +ThumbnailLayer* TabContentManager::GetOrCreateStaticLayer( int tab_id, bool force_disk_read) { + if (base::FeatureList::IsEnabled(thumbnail::kThumbnailCacheRefactor)) { + return GetStaticLayer(tab_id); + } thumbnail::Thumbnail* thumbnail = thumbnail_cache_->Get(tab_id, force_disk_read, true); scoped_refptr<ThumbnailLayer> static_layer = static_layer_cache_[tab_id]; @@ -200,7 +212,7 @@ } static_layer->SetThumbnail(thumbnail); - return static_layer; + return static_layer.get(); } void TabContentManager::AttachTab(JNIEnv* env, @@ -329,15 +341,31 @@ JNIEnv* env, const JavaParamRef<jintArray>& priority, jint primary_tab_id) { - std::list<int> priority_ids; - jsize length = env->GetArrayLength(priority); - jint* ints = env->GetIntArrayElements(priority, nullptr); - for (jsize i = 0; i < length; ++i) { - priority_ids.push_back(static_cast<int>(ints[i])); - } - - env->ReleaseIntArrayElements(priority, ints, JNI_ABORT); + std::vector<int> priority_ids; + base::android::JavaIntArrayToIntVector(env, priority, &priority_ids); thumbnail_cache_->UpdateVisibleIds(priority_ids, primary_tab_id); + if (!base::FeatureList::IsEnabled(thumbnail::kThumbnailCacheRefactor)) { + return; + } + std::erase_if(static_layer_cache_, [&priority_ids](const auto& pair) { + bool not_priority = !base::Contains(priority_ids, pair.first); + if (not_priority && pair.second) { + pair.second->layer()->RemoveFromParent(); + } + return not_priority; + }); + for (int tab_id : priority_ids) { + auto static_layer = static_layer_cache_[tab_id]; + if (!static_layer) { + static_layer = ThumbnailLayer::Create(); + static_layer_cache_[tab_id] = static_layer; + } + thumbnail::Thumbnail* thumbnail = + thumbnail_cache_->Get(tab_id, false, false); + if (thumbnail) { + static_layer->SetThumbnail(thumbnail); + } + } } void TabContentManager::NativeRemoveTabThumbnail(int tab_id) { @@ -370,6 +398,18 @@ thumbnail_cache_->OnUIResourcesWereEvicted(); } +void TabContentManager::OnThumbnailAddedToCache(int tab_id) { + if (!base::FeatureList::IsEnabled(thumbnail::kThumbnailCacheRefactor)) { + return; + } + auto it = static_layer_cache_.find(tab_id); + if (it != static_layer_cache_.end()) { + thumbnail::Thumbnail* thumbnail = + thumbnail_cache_->Get(tab_id, false, false); + it->second->SetThumbnail(thumbnail); + } +} + void TabContentManager::OnFinishedThumbnailRead(int tab_id) { JNIEnv* env = base::android::AttachCurrentThread(); Java_TabContentManager_notifyListenersOfThumbnailChange(
diff --git a/chrome/browser/android/compositor/tab_content_manager.h b/chrome/browser/android/compositor/tab_content_manager.h index ecd4ae6..0c7a8c5 100644 --- a/chrome/browser/android/compositor/tab_content_manager.h +++ b/chrome/browser/android/compositor/tab_content_manager.h
@@ -60,11 +60,17 @@ // Get the live layer from the cache. scoped_refptr<cc::slim::Layer> GetLiveLayer(int tab_id); - scoped_refptr<ThumbnailLayer> GetStaticLayer(int tab_id); + // Returns the static ThumbnailLayer for a `tab_id`. Note that the lifecycle + // of the thumbnail is managed by the ThumbnailCache and not the + // ThumbnailLayer. When displaying a layer it is important that + // UpdateVisibleIds is called with all the Tab IDs that are required for + // before calling GetStaticLayer. ThumbnailLayer's should not be retained as + // their lifecycle is managed by this class. + ThumbnailLayer* GetStaticLayer(int tab_id); + // Deprecated: This will be replace by just GetStaticLayer soon. // Get the static thumbnail from the cache, or the NTP. - scoped_refptr<ThumbnailLayer> GetOrCreateStaticLayer(int tab_id, - bool force_disk_read); + ThumbnailLayer* GetOrCreateStaticLayer(int tab_id, bool force_disk_read); // JNI methods. // Should be called when a tab gets a new live layer that should be served @@ -108,6 +114,7 @@ jint GetPendingReadbacksForTesting(JNIEnv* env); // ThumbnailCacheObserver implementation; + void OnThumbnailAddedToCache(thumbnail::TabId tab_id) override; void OnFinishedThumbnailRead(thumbnail::TabId tab_id) override; private:
diff --git a/chrome/browser/android/compositor/tab_content_manager_unittest.cc b/chrome/browser/android/compositor/tab_content_manager_unittest.cc new file mode 100644 index 0000000..3e1d039 --- /dev/null +++ b/chrome/browser/android/compositor/tab_content_manager_unittest.cc
@@ -0,0 +1,144 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/android/compositor/tab_content_manager.h" + +#include <memory> +#include <utility> +#include <vector> + +#include "base/android/jni_android.h" +#include "base/android/jni_array.h" +#include "base/memory/weak_ptr.h" +#include "base/test/scoped_feature_list.h" +#include "cc/resources/ui_resource_client.h" +#include "chrome/browser/thumbnail/cc/features.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/android/ui_android_export.h" + +namespace android { +namespace { + +#if DCHECK_IS_ON() +#define EXPECT_DCHECK(statement, regex) \ + EXPECT_DEATH_IF_SUPPORTED(statement, regex) +#else +#define EXPECT_DCHECK(statement, regex) \ + { statement; } +#endif + +constexpr int kDefaultCacheSize = 3; +constexpr int kApproximationCacheSize = 0; +constexpr int kCompressionQueueMaxSize = 2; +constexpr int kWriteQueueMaxSize = 2; +constexpr bool kUseApproximationThumbnail = false; +constexpr bool kSaveJpegThumbnails = true; +constexpr double kJpegAspectRatio = 0.85; + +class MockUIResourceProvider : public ui::UIResourceProvider { + public: + MOCK_METHOD(cc::UIResourceId, + CreateUIResource, + (cc::UIResourceClient*), + (override)); + MOCK_METHOD(void, DeleteUIResource, (cc::UIResourceId), (override)); + MOCK_METHOD(bool, SupportsETC1NonPowerOfTwo, (), (const, override)); + + base::WeakPtr<UIResourceProvider> GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } + + private: + base::WeakPtrFactory<MockUIResourceProvider> weak_factory_{this}; +}; + +} // namespace + +class TabContentManagerTest : public ::testing::Test { + protected: + void SetUp() override { + JNIEnv* env = base::android::AttachCurrentThread(); + tab_content_manager_ = std::make_unique<TabContentManager>( + env, nullptr, kDefaultCacheSize, kApproximationCacheSize, + kCompressionQueueMaxSize, kWriteQueueMaxSize, + kUseApproximationThumbnail, kSaveJpegThumbnails, kJpegAspectRatio); + tab_content_manager_->SetUIResourceProvider( + ui_resource_provider_.GetWeakPtr()); + + EXPECT_CALL(ui_resource_provider_, CreateUIResource(::testing::_)) + .WillRepeatedly(::testing::Return(1)); + scoped_feature_list_.InitWithFeatures({thumbnail::kThumbnailCacheRefactor}, + {}); + } + + TabContentManager& tab_content_manager() { return *tab_content_manager_; } + + content::BrowserTaskEnvironment task_environment_; + + private: + base::test::ScopedFeatureList scoped_feature_list_; + MockUIResourceProvider ui_resource_provider_; + std::unique_ptr<TabContentManager> tab_content_manager_; +}; + +TEST_F(TabContentManagerTest, UpdateTabIdsForStaticLayerCache) { + JNIEnv* env = base::android::AttachCurrentThread(); + constexpr int kTabId1 = 6; + constexpr int kTabId2 = 7; + EXPECT_DCHECK( + { + EXPECT_FALSE( + tab_content_manager().GetOrCreateStaticLayer(kTabId1, true)); + }, + ""); + EXPECT_DCHECK( + { EXPECT_FALSE(tab_content_manager().GetStaticLayer(kTabId1)); }, ""); + EXPECT_DCHECK( + { + EXPECT_FALSE( + tab_content_manager().GetOrCreateStaticLayer(kTabId2, true)); + }, + ""); + EXPECT_DCHECK( + { EXPECT_FALSE(tab_content_manager().GetStaticLayer(kTabId2)); }, ""); + + auto jarr = base::android::ToJavaIntArray(env, std::vector<int>({kTabId1})); + tab_content_manager().UpdateVisibleIds( + env, base::android::JavaParamRef<jintArray>(env, jarr.obj()), kTabId1); + EXPECT_TRUE(tab_content_manager().GetStaticLayer(kTabId1)); + EXPECT_DCHECK( + { EXPECT_FALSE(tab_content_manager().GetStaticLayer(kTabId2)); }, ""); + + tab_content_manager().UpdateVisibleIds( + env, base::android::JavaParamRef<jintArray>(env, jarr.obj()), -1); + EXPECT_TRUE(tab_content_manager().GetStaticLayer(kTabId1)); + EXPECT_DCHECK( + { EXPECT_FALSE(tab_content_manager().GetStaticLayer(kTabId2)); }, ""); + + jarr = + base::android::ToJavaIntArray(env, std::vector<int>({kTabId1, kTabId2})); + tab_content_manager().UpdateVisibleIds( + env, base::android::JavaParamRef<jintArray>(env, jarr.obj()), -1); + EXPECT_TRUE(tab_content_manager().GetStaticLayer(kTabId1)); + EXPECT_TRUE(tab_content_manager().GetStaticLayer(kTabId2)); + + jarr = base::android::ToJavaIntArray(env, std::vector<int>({kTabId2})); + tab_content_manager().UpdateVisibleIds( + env, base::android::JavaParamRef<jintArray>(env, jarr.obj()), -1); + EXPECT_DCHECK( + { EXPECT_FALSE(tab_content_manager().GetStaticLayer(kTabId1)); }, ""); + EXPECT_TRUE(tab_content_manager().GetStaticLayer(kTabId2)); + + jarr = base::android::ToJavaIntArray(env, std::vector<int>({})); + tab_content_manager().UpdateVisibleIds( + env, base::android::JavaParamRef<jintArray>(env, jarr.obj()), -1); + EXPECT_DCHECK( + { EXPECT_FALSE(tab_content_manager().GetStaticLayer(kTabId1)); }, ""); + EXPECT_DCHECK( + { EXPECT_FALSE(tab_content_manager().GetStaticLayer(kTabId2)); }, ""); +} + +} // namespace android
diff --git a/chrome/browser/android/httpclient/java/src/org/chromium/chrome/browser/android/httpclient/AnnotatedSimpleHttpClient.java b/chrome/browser/android/httpclient/java/src/org/chromium/chrome/browser/android/httpclient/AnnotatedSimpleHttpClient.java index 42d8eddf..d173b53 100644 --- a/chrome/browser/android/httpclient/java/src/org/chromium/chrome/browser/android/httpclient/AnnotatedSimpleHttpClient.java +++ b/chrome/browser/android/httpclient/java/src/org/chromium/chrome/browser/android/httpclient/AnnotatedSimpleHttpClient.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.android.httpclient; +import org.chromium.base.task.PostTask; +import org.chromium.base.task.TaskTraits; import org.chromium.chrome.browser.android.httpclient.SimpleHttpClient.HttpResponse; import org.chromium.net.NetError; import org.chromium.net.NetworkTrafficAnnotationTag; @@ -32,10 +34,12 @@ // Also mask network stack error codes as HTTP status code (better than // swallowing it and third_party code does not know about chrome's // network stack errors enum). - SimpleHttpClient.get().send( - gurl, requestType, body, headers, mAnnotation, (HttpResponse response) -> { - callback.accept(getStatusCode(response), response.mBody, response.mHeaders); - }); + PostTask.runOrPostTask(TaskTraits.UI_DEFAULT, () -> { + SimpleHttpClient.get().send( + gurl, requestType, body, headers, mAnnotation, (HttpResponse response) -> { + callback.accept(getStatusCode(response), response.mBody, response.mHeaders); + }); + }); } private static int getStatusCode(HttpResponse response) {
diff --git a/chrome/browser/ash/app_list/search/desks_admin_template_provider.cc b/chrome/browser/ash/app_list/search/desks_admin_template_provider.cc index 4032c67..99406eb 100644 --- a/chrome/browser/ash/app_list/search/desks_admin_template_provider.cc +++ b/chrome/browser/ash/app_list/search/desks_admin_template_provider.cc
@@ -10,6 +10,7 @@ #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/wm/desks/templates/saved_desk_controller.h" +#include "chrome/browser/ash/app_list/app_list_controller_delegate.h" #include "chrome/browser/ash/app_list/search/common/icon_constants.h" #include "chrome/browser/ash/app_list/search/types.h" #include "chrome/browser/profiles/profile.h" @@ -26,10 +27,13 @@ DesksAdminTemplateResult::DesksAdminTemplateResult( Profile* profile, + AppListControllerDelegate* list_controller, const base ::GUID& template_uuid, const std::u16string& title, const gfx::ImageSkia& icon) - : profile_(profile), template_uuid_(template_uuid) { + : profile_(profile), + list_controller_(list_controller), + template_uuid_(template_uuid) { DCHECK(profile_); set_id(kAdminTemplateResultPrefix + template_uuid.AsLowercaseString()); SetCategory(Category::kUnknown); @@ -44,11 +48,14 @@ DesksAdminTemplateResult::~DesksAdminTemplateResult() = default; void DesksAdminTemplateResult::Open(int event_flags) { - ash::SavedDeskController::Get()->LaunchAdminTemplate(template_uuid_); + ash::SavedDeskController::Get()->LaunchAdminTemplate( + template_uuid_, list_controller_->GetAppListDisplayId()); } -DesksAdminTemplateProvider::DesksAdminTemplateProvider(Profile* profile) - : profile_(profile) { +DesksAdminTemplateProvider::DesksAdminTemplateProvider( + Profile* profile, + AppListControllerDelegate* list_controller) + : profile_(profile), list_controller_(list_controller) { DCHECK(profile_); } @@ -74,7 +81,7 @@ // With productivity launcher enabled, release notes are shown in continue // section. search_results.emplace_back(std::make_unique<DesksAdminTemplateResult>( - profile_, metadata.uuid, metadata.name, icon)); + profile_, list_controller_, metadata.uuid, metadata.name, icon)); } SwapResults(&search_results);
diff --git a/chrome/browser/ash/app_list/search/desks_admin_template_provider.h b/chrome/browser/ash/app_list/search/desks_admin_template_provider.h index 5539cdc8..fb52e06 100644 --- a/chrome/browser/ash/app_list/search/desks_admin_template_provider.h +++ b/chrome/browser/ash/app_list/search/desks_admin_template_provider.h
@@ -13,6 +13,7 @@ #include "chrome/browser/ash/app_list/search/chrome_search_result.h" #include "chrome/browser/ash/app_list/search/search_provider.h" +class AppListControllerDelegate; class Profile; namespace gfx { @@ -25,6 +26,7 @@ class DesksAdminTemplateResult : public ChromeSearchResult { public: DesksAdminTemplateResult(Profile* profile, + AppListControllerDelegate* list_controller, const base::GUID& template_uuid, const std::u16string& title, const gfx::ImageSkia& icon); @@ -39,6 +41,7 @@ private: Profile* const profile_; + AppListControllerDelegate* const list_controller_; base::GUID template_uuid_; }; @@ -47,7 +50,8 @@ // admin templates will appear in the continue section view. class DesksAdminTemplateProvider : public SearchProvider { public: - explicit DesksAdminTemplateProvider(Profile* profile); + DesksAdminTemplateProvider(Profile* profile, + AppListControllerDelegate* list_controller); ~DesksAdminTemplateProvider() override; DesksAdminTemplateProvider(const DesksAdminTemplateProvider&) = delete; @@ -60,6 +64,7 @@ private: Profile* const profile_; + AppListControllerDelegate* const list_controller_; }; } // namespace app_list
diff --git a/chrome/browser/ash/app_list/search/desks_admin_template_provider_unittest.cc b/chrome/browser/ash/app_list/search/desks_admin_template_provider_unittest.cc index fd04b7fa..461161c 100644 --- a/chrome/browser/ash/app_list/search/desks_admin_template_provider_unittest.cc +++ b/chrome/browser/ash/app_list/search/desks_admin_template_provider_unittest.cc
@@ -7,6 +7,7 @@ #include "ash/wm/desks/templates/saved_desk_controller.h" #include "chrome/browser/ash/app_list/search/test/test_search_controller.h" +#include "chrome/browser/ash/app_list/test/test_app_list_controller_delegate.h" #include "chrome/browser/profiles/profile.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" @@ -36,7 +37,7 @@ (const, override)); MOCK_METHOD(bool, LaunchAdminTemplate, - (const base::GUID& template_uuid), + (const base::GUID& template_uuid, int64_t default_display_id), (override)); }; @@ -54,7 +55,8 @@ ASSERT_TRUE(profile_manager_->SetUp()); profile_ = profile_manager_->CreateTestingProfile("name"); - auto provider = std::make_unique<DesksAdminTemplateProvider>(profile_); + auto provider = std::make_unique<DesksAdminTemplateProvider>( + profile_, &list_controller_); provider_ = provider.get(); search_controller_->AddProvider(std::move(provider)); @@ -84,6 +86,7 @@ private: std::unique_ptr<TestingProfileManager> profile_manager_; TestingProfile* profile_; + ::test::TestAppListControllerDelegate list_controller_; DesksAdminTemplateProvider* provider_ = nullptr; }; @@ -110,7 +113,7 @@ .uuid = base::GUID::GenerateRandomV4(), .name = u"test admin template"}}; EXPECT_CALL(mock, GetAdminTemplateMetadata()).WillOnce(Return(results)); - EXPECT_CALL(mock, LaunchAdminTemplate(results[0].uuid)) + EXPECT_CALL(mock, LaunchAdminTemplate(results[0].uuid, _)) .WillOnce(Return(true)); StartZeroStateSearch();
diff --git a/chrome/browser/ash/app_list/search/search_controller_factory.cc b/chrome/browser/ash/app_list/search/search_controller_factory.cc index b50fb43..79c23b3 100644 --- a/chrome/browser/ash/app_list/search/search_controller_factory.cc +++ b/chrome/browser/ash/app_list/search/search_controller_factory.cc
@@ -138,7 +138,7 @@ if (base::FeatureList::IsEnabled(ash::features::kAppLaunchAutomation)) { controller->AddProvider( - std::make_unique<DesksAdminTemplateProvider>(profile)); + std::make_unique<DesksAdminTemplateProvider>(profile, list_controller)); } if (search_features::IsLauncherGameSearchEnabled()) {
diff --git a/chrome/browser/ash/crosapi/crosapi_util.cc b/chrome/browser/ash/crosapi/crosapi_util.cc index c4d6e547..af4adbf 100644 --- a/chrome/browser/ash/crosapi/crosapi_util.cc +++ b/chrome/browser/ash/crosapi/crosapi_util.cc
@@ -147,6 +147,7 @@ #include "components/version_info/version_info.h" #include "content/public/common/content_switches.h" #include "device/bluetooth/floss/floss_features.h" +#include "media/base/media_switches.h" #include "media/capture/mojom/video_capture.mojom.h" #include "media/mojo/mojom/stable/stable_video_decoder.mojom.h" #include "printing/buildflags/buildflags.h" @@ -530,7 +531,9 @@ // lacros for runtime handling instead. std::vector<crosapi::mojom::BuildFlag> build_flags; #if BUILDFLAG(ENABLE_PLATFORM_HEVC) - build_flags.emplace_back(crosapi::mojom::BuildFlag::kEnablePlatformHevc); + if (base::FeatureList::IsEnabled(media::kPlatformHEVCDecoderSupport)) { + build_flags.emplace_back(crosapi::mojom::BuildFlag::kEnablePlatformHevc); + } #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) #if BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA) build_flags.emplace_back(
diff --git a/chrome/browser/ash/crosapi/parent_access_ash.cc b/chrome/browser/ash/crosapi/parent_access_ash.cc index ae58b1e0..613ca1e 100644 --- a/chrome/browser/ash/crosapi/parent_access_ash.cc +++ b/chrome/browser/ash/crosapi/parent_access_ash.cc
@@ -39,6 +39,11 @@ crosapi::mojom::ParentAccessErrorResult::New( crosapi::mojom::ParentAccessErrorResult::Type::kUnknown)); break; + case ash::ParentAccessDialog::Result::Status::kDisabled: + // TODO(b/262450337): Implement disabled case when extension approvals is + // implemented. Disabled state is not possible for the current callers of + // ParentAccessAsh. + NOTREACHED_NORETURN(); } return parent_access_result;
diff --git a/chrome/browser/ash/login/chrome_restart_request.cc b/chrome/browser/ash/login/chrome_restart_request.cc index 63770499..5f472dd7 100644 --- a/chrome/browser/ash/login/chrome_restart_request.cc +++ b/chrome/browser/ash/login/chrome_restart_request.cc
@@ -248,26 +248,39 @@ } } -// Adds allowlisted features to `out_command_line` if they are enabled in the +// Adds allowlisted features to `out_command_line` if they are overridden in the // current session. -void DeriveEnabledFeatures(base::CommandLine* out_command_line) { - std::vector<const base::Feature*> kForwardEnabledFeatures{ - &features::kAutoNightLight, &features::kLacrosOnly, - &features::kLacrosPrimary, &features::kLacrosSupport, - &::features::kPluginVm, +void DeriveFeatures(base::CommandLine* out_command_line) { + auto kForwardFeatures = { + &features::kAutoNightLight, + &features::kLacrosOnly, + &features::kLacrosPrimary, + &features::kLacrosSupport, + &::features::kPluginVm, +#if BUILDFLAG(ENABLE_PLATFORM_HEVC) + &media::kPlatformHEVCDecoderSupport, +#endif }; - std::vector<std::string> enabled_features; - for (const auto* feature : kForwardEnabledFeatures) { - if (base::FeatureList::IsEnabled(*feature)) - enabled_features.push_back(feature->name); + std::vector<std::string> disabled_features; + for (const auto* feature : kForwardFeatures) { + if (auto state = base::FeatureList::GetStateIfOverridden(*feature)) { + if (*state) { + enabled_features.push_back(feature->name); + } else { + disabled_features.push_back(feature->name); + } + } } - if (enabled_features.empty()) - return; - - out_command_line->AppendSwitchASCII("enable-features", - base::JoinString(enabled_features, ",")); + if (!enabled_features.empty()) { + out_command_line->AppendSwitchASCII( + "enable-features", base::JoinString(enabled_features, ",")); + } + if (!disabled_features.empty()) { + out_command_line->AppendSwitchASCII( + "disable-features", base::JoinString(disabled_features, ",")); + } } // Simulates a session manager restart by launching give command line @@ -387,7 +400,7 @@ GURL(chrome::kChromeUINewTabURL).spec()); DeriveCommandLine(start_url, base_command_line, otr_switches, command_line); - DeriveEnabledFeatures(command_line); + DeriveFeatures(command_line); } void RestartChrome(const base::CommandLine& command_line,
diff --git a/chrome/browser/ash/login/demo_mode/demo_session.cc b/chrome/browser/ash/login/demo_mode/demo_session.cc index 7479f48..f724618 100644 --- a/chrome/browser/ash/login/demo_mode/demo_session.cc +++ b/chrome/browser/ash/login/demo_mode/demo_session.cc
@@ -691,7 +691,8 @@ } void DemoSession::ShowSplashScreen(base::FilePath image_path) { - WallpaperControllerClientImpl::Get()->ShowAlwaysOnTopWallpaper(image_path); + WallpaperControllerClientImpl::Get()->ShowOverrideWallpaper( + image_path, /*always_on_top=*/true); remove_splash_screen_fallback_timer_->Start( FROM_HERE, kRemoveSplashScreenTimeout, base::BindOnce(&DemoSession::RemoveSplashScreen, @@ -717,7 +718,7 @@ void DemoSession::RemoveSplashScreen() { if (splash_screen_removed_) return; - WallpaperControllerClientImpl::Get()->RemoveAlwaysOnTopWallpaper(); + WallpaperControllerClientImpl::Get()->RemoveOverrideWallpaper(); remove_splash_screen_fallback_timer_.reset(); app_window_registry_observations_.RemoveAllObservations(); splash_screen_removed_ = true;
diff --git a/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc b/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc index 37735e9..9c9b151 100644 --- a/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc +++ b/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc
@@ -180,22 +180,21 @@ std::make_unique<base::MockOneShotTimer>(); demo_session->SetTimerForTesting(std::move(timer)); - EXPECT_EQ(0, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(0, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(0, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(0, test_wallpaper_controller_.remove_override_wallpaper_count()); session_manager_->SetSessionState( session_manager::SessionState::LOGIN_PRIMARY); - EXPECT_EQ(0, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(0, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(0, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(0, test_wallpaper_controller_.remove_override_wallpaper_count()); ASSERT_TRUE(FinishResourcesComponentLoad( base::FilePath(kTestDemoModeResourcesMountPoint))); // Wait for splash screen image to load and timer to be set task_environment_.RunUntilIdle(); - EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(0, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count( + /*always_on_top=*/true)); + EXPECT_EQ(0, test_wallpaper_controller_.remove_override_wallpaper_count()); TestingProfile* profile = LoginDemoUser(); scoped_refptr<const extensions::Extension> screensaver_app = @@ -213,13 +212,15 @@ screensaver_app.get()); demo_session->OnAppWindowActivated(app_window); // The splash screen is not removed until active session starts. - EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(0, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count( + /*always_on_top=*/true)); + EXPECT_EQ(0, test_wallpaper_controller_.remove_override_wallpaper_count()); session_manager_->SetSessionState(session_manager::SessionState::ACTIVE); - EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(1, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count( + /*always_on_top=*/true)); + EXPECT_EQ(1, test_wallpaper_controller_.remove_override_wallpaper_count()); // The timer is cleared after splash screen is removed. EXPECT_FALSE(demo_session->GetTimerForTesting()); @@ -234,30 +235,30 @@ std::make_unique<base::MockOneShotTimer>(); demo_session->SetTimerForTesting(std::move(timer)); - EXPECT_EQ(0, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(0, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(0, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(0, test_wallpaper_controller_.remove_override_wallpaper_count()); session_manager_->SetSessionState( session_manager::SessionState::LOGIN_PRIMARY); - EXPECT_EQ(0, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(0, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(0, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(0, test_wallpaper_controller_.remove_override_wallpaper_count()); ASSERT_TRUE(FinishResourcesComponentLoad( base::FilePath(kTestDemoModeResourcesMountPoint))); // Wait for splash screen image to load and timer to be set task_environment_.RunUntilIdle(); - EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(0, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count( + /*always_on_top=*/true)); + EXPECT_EQ(0, test_wallpaper_controller_.remove_override_wallpaper_count()); base::MockOneShotTimer* timer_ptr = static_cast<base::MockOneShotTimer*>(demo_session->GetTimerForTesting()); ASSERT_TRUE(timer_ptr); timer_ptr->Fire(); - EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(1, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count( + /*always_on_top=*/true)); + EXPECT_EQ(1, test_wallpaper_controller_.remove_override_wallpaper_count()); // Launching the screensaver will not trigger splash screen removal anymore. TestingProfile* profile = LoginDemoUser(); @@ -275,14 +276,16 @@ std::make_unique<ChromeAppDelegate>(profile, true /* keep_alive */), screensaver_app.get()); demo_session->OnAppWindowActivated(app_window); - EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(1, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count( + /*always_on_top=*/true)); + EXPECT_EQ(1, test_wallpaper_controller_.remove_override_wallpaper_count()); // Entering active session will not trigger splash screen removal anymore. session_manager_->SetSessionState(session_manager::SessionState::ACTIVE); - EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); - EXPECT_EQ(1, - test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count()); + EXPECT_EQ(1, test_wallpaper_controller_.show_override_wallpaper_count( + /*always_on_top=*/true)); + EXPECT_EQ(1, test_wallpaper_controller_.remove_override_wallpaper_count()); app_window->OnNativeClose(); }
diff --git a/chrome/browser/ash/net/apn_migrator.cc b/chrome/browser/ash/net/apn_migrator.cc index 90e444c2..9f15a4e 100644 --- a/chrome/browser/ash/net/apn_migrator.cc +++ b/chrome/browser/ash/net/apn_migrator.cc
@@ -20,6 +20,10 @@ namespace { +using chromeos::network_config::mojom::ApnPropertiesPtr; +using chromeos::network_config::mojom::ApnState; +using chromeos::network_config::mojom::ManagedApnPropertiesPtr; + void OnSetShillCustomApnListSuccess() {} void OnSetShillCustomApnListFailure(const std::string& guid, @@ -29,6 +33,19 @@ << guid << ": [" << error_name << ']'; } +absl::optional<ApnPropertiesPtr> GetApnFromDict( + const base::Value::Dict* cellular_dict, + const char* key, + bool is_apn_revamp_enabled) { + const base::Value::Dict* apn_dict = + chromeos::network_config::GetDictionary(cellular_dict, key); + if (!apn_dict || !apn_dict->Find(::onc::cellular_apn::kAccessPointName)) { + return absl::nullopt; + } + return chromeos::network_config::GetApnProperties(*apn_dict, + is_apn_revamp_enabled); +} + } // namespace ApnMigrator::ApnMigrator( @@ -194,25 +211,25 @@ return; } + ApnPropertiesPtr pre_revamp_custom_apn = + chromeos::network_config::GetApnProperties( + custom_apn_list->front().GetDict(), + /*is_apn_revamp_enabled=*/false); + const base::Value::Dict* cellular_dict = + chromeos::network_config::GetDictionary(&properties.value(), + ::onc::network_config::kCellular); + if (network->IsManagedByPolicy()) { - chromeos::network_config::mojom::ApnPropertiesPtr pre_revamp_custom_apn = - chromeos::network_config::GetApnProperties( - custom_apn_list->front().GetDict(), - /*is_apn_revamp_enabled=*/false); - const base::Value::Dict* cellular_dict = - chromeos::network_config::GetDictionary( - &properties.value(), ::onc::network_config::kCellular); - chromeos::network_config::mojom::ManagedApnPropertiesPtr selected_apn = + ManagedApnPropertiesPtr selected_apn = chromeos::network_config::GetManagedApnProperties( cellular_dict, ::onc::cellular::kAPN); if (selected_apn && pre_revamp_custom_apn->access_point_name == selected_apn->access_point_name->active_value) { NET_LOG(EVENT) << "Managed network's selected APN matches the saved " << "custom APN, migrating APN: " << guid; - // Ensure the network is enabled when it's migrated so that it's attempted + // Ensure the APN is enabled when it's migrated so that it's attempted // to be used by the new UI. - pre_revamp_custom_apn->state = - chromeos::network_config::mojom::ApnState::kEnabled; + pre_revamp_custom_apn->state = ApnState::kEnabled; remote_cros_network_config_->CreateCustomApn( guid, std::move(pre_revamp_custom_apn)); } else { @@ -223,8 +240,45 @@ SetShillCustomApnListForNetwork(*network, &empty_apn_list); } } else { - // TODO(b/162365553): Implement this case. + absl::optional<ApnPropertiesPtr> last_connected_attach_apn = GetApnFromDict( + cellular_dict, ::onc::cellular::kLastConnectedAttachApnProperty, + /*is_apn_revamp_enabled=*/false); + + absl::optional<ApnPropertiesPtr> last_connected_default_apn = + GetApnFromDict(cellular_dict, + ::onc::cellular::kLastConnectedDefaultApnProperty, + /*is_apn_revamp_enabled=*/false); + + if (!last_connected_attach_apn && !last_connected_default_apn) { + absl::optional<ApnPropertiesPtr> last_good_apn = + GetApnFromDict(cellular_dict, ::onc::cellular::kLastGoodAPN, + /*is_apn_revamp_enabled=*/false); + + if (last_good_apn && pre_revamp_custom_apn->access_point_name == + (*last_good_apn)->access_point_name) { + NET_LOG(EVENT) << "Network's last good APN matches the saved " + << "custom APN, migrating APN: " << guid + << "in the Enabled state"; + // Ensure the APN is enabled when it's migrated so that it's + // attempted to be used by the new UI. + pre_revamp_custom_apn->state = ApnState::kEnabled; + } else { + NET_LOG(EVENT) << "Network's last good APN does not match the saved " + << "custom APN, migrating APN: " << guid + << "in the Disabled state"; + // The custom APN was last unsuccessful in connecting when the flag was + // off. Preserve the details of the custom APN but with a state of + // Disabled. + pre_revamp_custom_apn->state = ApnState::kDisabled; + // TODO(b/162365553): Surface a notification to the user indicating that + // their APN configuration was changed. + } + remote_cros_network_config_->CreateCustomApn( + guid, std::move(pre_revamp_custom_apn)); + } } + // TODO(b/162365553): Implement other cases of |last_connected_attach_apn| + // and |last_connected_default_apn|. managed_cellular_pref_handler_->AddApnMigratedIccid(iccid); iccids_in_migration_.erase(iccid);
diff --git a/chrome/browser/ash/net/apn_migrator_unittest.cc b/chrome/browser/ash/net/apn_migrator_unittest.cc index 0dd781b..92dd7b2 100644 --- a/chrome/browser/ash/net/apn_migrator_unittest.cc +++ b/chrome/browser/ash/net/apn_migrator_unittest.cc
@@ -802,4 +802,143 @@ EXPECT_EQ(ApnState::kEnabled, custom_apns[0]->state); } +TEST_F( + ApnMigratorTest, + MigrateNonManagedNetwork_NoLastConnectedAttachApnAndDefaultApn_MatchingLastGoodApn) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kApnRevamp); + + const std::string cellular_service_path_1 = AddTestCellularDeviceAndService( + kCellularName1, kTestCellularPath1, kTestCellularIccid1, + kTestCellularGuid1, /*is_managed=*/false); + + // We will use this delegate to simulate a late async reply + network_handler::PropertiesCallback get_managed_properties_callback; + + // Start the migration process for |cellular_service_path_1|. This will + // trigger a GetManagedProperties call. + EXPECT_CALL(*managed_cellular_pref_handler(), + ContainsApnMigratedIccid(Eq(kTestCellularIccid1))) + .WillRepeatedly(Return(false)); + const std::string access_point_name = "apn_1"; + base::Value::Dict custom_apn; + custom_apn.Set(::onc::cellular_apn::kAccessPointName, access_point_name); + base::Value::List populated_apn_list; + populated_apn_list.Append(std::move(custom_apn)); + EXPECT_CALL(*network_metadata_store(), + GetPreRevampCustomApnList(kTestCellularGuid1)) + .Times(2) + .WillRepeatedly(Return(&populated_apn_list)); + EXPECT_CALL(*managed_network_configuration_handler(), + GetManagedProperties(LoginState::Get()->primary_user_hash(), + cellular_service_path_1, _)) + .Times(1) + .WillOnce( + WithArg<2>(Invoke([&](network_handler::PropertiesCallback callback) { + ASSERT_TRUE(get_managed_properties_callback.is_null()); + get_managed_properties_callback = std::move(callback); + ASSERT_FALSE(get_managed_properties_callback.is_null()); + }))); + // Function under test. + TriggerNetworkListChanged(); + + // Execute the GetManagedProperties callback with no last connected attach + // APN, no last connected default APN, and a last good APN that matches the + // persisted APN. This should trigger a call to CreateCustomApns() with the + // APN in the enabled state. + EXPECT_CALL(*managed_network_configuration_handler(), + SetProperties(cellular_service_path_1, _, _, _)) + .Times(0); + EXPECT_CALL(*managed_cellular_pref_handler(), + AddApnMigratedIccid(Eq(kTestCellularIccid1))) + .Times(1); + EXPECT_TRUE(GetCustomApns().empty()); + + absl::optional<base::Value::Dict> properties = base::Value::Dict(); + base::Value::Dict last_good_apn_dict; + last_good_apn_dict.Set(::onc::cellular_apn::kAccessPointName, + access_point_name); + base::Value::Dict cellular; + cellular.Set(::onc::cellular::kLastGoodAPN, std::move(last_good_apn_dict)); + + properties->Set(::onc::network_config::kCellular, std::move(cellular)); + std::move(get_managed_properties_callback) + .Run(cellular_service_path_1, std::move(properties), + /*error=*/absl::nullopt); + base::RunLoop().RunUntilIdle(); + const std::vector<ApnPropertiesPtr>& custom_apns = GetCustomApns(); + ASSERT_EQ(1u, custom_apns.size()); + EXPECT_EQ(access_point_name, custom_apns[0]->access_point_name); + EXPECT_EQ(ApnState::kEnabled, custom_apns[0]->state); +} + +TEST_F( + ApnMigratorTest, + MigrateNonManagedNetwork_NoLastConnectedAttachApnAndDefaultApn_NonMatchingLastGoodApn) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kApnRevamp); + + const std::string cellular_service_path_1 = AddTestCellularDeviceAndService( + kCellularName1, kTestCellularPath1, kTestCellularIccid1, + kTestCellularGuid1, /*is_managed=*/false); + + // We will use this delegate to simulate a late async reply + network_handler::PropertiesCallback get_managed_properties_callback; + + // Start the migration process for |cellular_service_path_1|. This will + // trigger a GetManagedProperties call. + EXPECT_CALL(*managed_cellular_pref_handler(), + ContainsApnMigratedIccid(Eq(kTestCellularIccid1))) + .WillRepeatedly(Return(false)); + const std::string access_point_name = "apn_1"; + base::Value::Dict custom_apn; + custom_apn.Set(::onc::cellular_apn::kAccessPointName, access_point_name); + base::Value::List populated_apn_list; + populated_apn_list.Append(std::move(custom_apn)); + EXPECT_CALL(*network_metadata_store(), + GetPreRevampCustomApnList(kTestCellularGuid1)) + .Times(2) + .WillRepeatedly(Return(&populated_apn_list)); + EXPECT_CALL(*managed_network_configuration_handler(), + GetManagedProperties(LoginState::Get()->primary_user_hash(), + cellular_service_path_1, _)) + .Times(1) + .WillOnce( + WithArg<2>(Invoke([&](network_handler::PropertiesCallback callback) { + ASSERT_TRUE(get_managed_properties_callback.is_null()); + get_managed_properties_callback = std::move(callback); + ASSERT_FALSE(get_managed_properties_callback.is_null()); + }))); + // Function under test. + TriggerNetworkListChanged(); + + // Execute the GetManagedProperties callback with no last connected attach + // APN, no last connected default APN, and a last good APN that does NOT match + // the persisted APN. This should trigger a call to CreateCustomApns() with + // the APN in the disabled state. + EXPECT_CALL(*managed_network_configuration_handler(), + SetProperties(cellular_service_path_1, _, _, _)) + .Times(0); + EXPECT_CALL(*managed_cellular_pref_handler(), + AddApnMigratedIccid(Eq(kTestCellularIccid1))) + .Times(1); + EXPECT_TRUE(GetCustomApns().empty()); + + absl::optional<base::Value::Dict> properties = base::Value::Dict(); + base::Value::Dict last_good_apn_dict; + last_good_apn_dict.Set(::onc::cellular_apn::kAccessPointName, "apn_2"); + base::Value::Dict cellular; + cellular.Set(::onc::cellular::kLastGoodAPN, std::move(last_good_apn_dict)); + + properties->Set(::onc::network_config::kCellular, std::move(cellular)); + std::move(get_managed_properties_callback) + .Run(cellular_service_path_1, std::move(properties), + /*error=*/absl::nullopt); + base::RunLoop().RunUntilIdle(); + const std::vector<ApnPropertiesPtr>& custom_apns = GetCustomApns(); + ASSERT_EQ(1u, custom_apns.size()); + EXPECT_EQ(access_point_name, custom_apns[0]->access_point_name); + EXPECT_EQ(ApnState::kDisabled, custom_apns[0]->state); +} + } // namespace ash
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 9cd2cb8..1ca24f8 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -87,7 +87,6 @@ #include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h" #include "chrome/browser/metrics/chrome_feature_list_creator.h" #include "chrome/browser/navigation_predictor/anchor_element_preloader.h" -#include "chrome/browser/net/cert_verifier_configuration.h" #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/net/profile_network_context_service.h" #include "chrome/browser/net/profile_network_context_service_factory.h" @@ -3545,17 +3544,6 @@ return content::GeneratedCodeCacheSettings(true, size_in_bytes, cache_path); } -cert_verifier::mojom::CertVerifierServiceParamsPtr -ChromeContentBrowserClient::GetCertVerifierServiceParams() { - PrefService* local_state; - if (g_browser_process) { - local_state = g_browser_process->local_state(); - } else { - local_state = startup_data_.chrome_feature_list_creator()->local_state(); - } - return GetChromeCertVerifierServiceParams(local_state); -} - void ChromeContentBrowserClient::AllowCertificateError( content::WebContents* web_contents, int cert_error,
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 2536b72d..b195175c 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -364,8 +364,6 @@ #endif content::GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( content::BrowserContext* context) override; - cert_verifier::mojom::CertVerifierServiceParamsPtr - GetCertVerifierServiceParams() override; void AllowCertificateError( content::WebContents* web_contents, int cert_error,
diff --git a/chrome/browser/companion/core/companion_url_builder.cc b/chrome/browser/companion/core/companion_url_builder.cc index b29c0ae..3d4ea840 100644 --- a/chrome/browser/companion/core/companion_url_builder.cc +++ b/chrome/browser/companion/core/companion_url_builder.cc
@@ -70,6 +70,36 @@ GURL CompanionUrlBuilder::BuildCompanionURL(GURL page_url, const std::string& text_query) { + GURL url_with_query_params = GetHomepageURLForCompanion(); + + // Fill the protobuf with the required query params. + std::string base64_encoded_proto = BuildCompanionUrlParamProto(page_url); + url_with_query_params = net::AppendOrReplaceQueryParameter( + url_with_query_params, kCompanionRequestQueryParameterKey, + base64_encoded_proto); + + // Add origin as a param allowing the page to be iframed. + url_with_query_params = net::AppendOrReplaceQueryParameter( + url_with_query_params, kOriginQueryParameterKey, + kOriginQueryParameterValue); + + // TODO(b/274714162): Remove URL param. + bool is_msbb_enabled = + IsUserPermittedToSharePageInfoWithCompanion(pref_service_); + if (is_msbb_enabled && IsValidPageURLForCompanion(page_url)) { + url_with_query_params = net::AppendOrReplaceQueryParameter( + url_with_query_params, kUrlQueryParameterKey, page_url.spec()); + } + + if (!text_query.empty()) { + url_with_query_params = net::AppendOrReplaceQueryParameter( + url_with_query_params, kTextQueryParameterKey, text_query); + } + + return url_with_query_params; +} + +std::string CompanionUrlBuilder::BuildCompanionUrlParamProto(GURL page_url) { // Fill the protobuf with the required query params. companion::proto::CompanionUrlParams url_params; bool is_msbb_enabled = @@ -89,30 +119,9 @@ promo_state->set_exps_promo_denial_count( pref_service_->GetInteger(kExpsPromoDeclinedCountPref)); - GURL url_with_query_params = GetHomepageURLForCompanion(); std::string base64_encoded_proto; base::Base64Encode(url_params.SerializeAsString(), &base64_encoded_proto); - url_with_query_params = net::AppendOrReplaceQueryParameter( - url_with_query_params, kCompanionRequestQueryParameterKey, - base64_encoded_proto); - - // Add origin as a param allowing the page to be iframed. - url_with_query_params = net::AppendOrReplaceQueryParameter( - url_with_query_params, kOriginQueryParameterKey, - kOriginQueryParameterValue); - - // TODO(b/274714162): Remove URL param. - if (is_msbb_enabled && IsValidPageURLForCompanion(page_url)) { - url_with_query_params = net::AppendOrReplaceQueryParameter( - url_with_query_params, kUrlQueryParameterKey, page_url.spec()); - } - - if (!text_query.empty()) { - url_with_query_params = net::AppendOrReplaceQueryParameter( - url_with_query_params, kTextQueryParameterKey, text_query); - } - - return url_with_query_params; + return base64_encoded_proto; } GURL CompanionUrlBuilder::GetHomepageURLForCompanion() {
diff --git a/chrome/browser/companion/core/companion_url_builder.h b/chrome/browser/companion/core/companion_url_builder.h index fb7a7d1..a9ea90f 100644 --- a/chrome/browser/companion/core/companion_url_builder.h +++ b/chrome/browser/companion/core/companion_url_builder.h
@@ -26,10 +26,16 @@ // Returns the companion URL that will be loaded in the side panel with the // query parameter set to the protobuf representation of the `page_url` and - // associated state. + // associated state. Invokes `BuildCompanionUrlParamProto` internally to + // create the proto. GURL BuildCompanionURL(GURL page_url); GURL BuildCompanionURL(GURL page_url, const std::string& text_query); + // Returns the protobuf representation of the `page_url` and + // associated state. Used to notify the companion page both during initial + // load and subsequent state updates. + std::string BuildCompanionUrlParamProto(GURL page_url); + private: // The base URL for companion. GURL GetHomepageURLForCompanion();
diff --git a/chrome/browser/companion/core/companion_url_builder_unittest.cc b/chrome/browser/companion/core/companion_url_builder_unittest.cc index c561687f..1285a6e5 100644 --- a/chrome/browser/companion/core/companion_url_builder_unittest.cc +++ b/chrome/browser/companion/core/companion_url_builder_unittest.cc
@@ -61,9 +61,13 @@ void VerifyPageUrlSent(GURL page_url, bool expect_was_sent) { GURL companion_url = url_builder_->BuildCompanionURL(page_url); + std::string companion_query_param; + EXPECT_TRUE(net::GetValueForKeyInQuery(companion_url, "companion_query", + &companion_query_param)); + // Deserialize the query param into protobuf. companion::proto::CompanionUrlParams proto = - DeserializeCompanionRequest(companion_url); + DeserializeCompanionRequest(companion_query_param); if (expect_was_sent) { EXPECT_EQ(proto.page_url(), page_url.spec()); @@ -74,12 +78,10 @@ EXPECT_TRUE(proto.has_msbb_enabled()); } // Deserialize the query param into proto::CompanionUrlParams. - proto::CompanionUrlParams DeserializeCompanionRequest(GURL companion_url) { + proto::CompanionUrlParams DeserializeCompanionRequest( + std::string companion_url_param) { companion::proto::CompanionUrlParams proto; - std::string url_param; - EXPECT_TRUE(net::GetValueForKeyInQuery(companion_url, "companion_query", - &url_param)); - auto base64_decoded = base::Base64Decode(url_param); + auto base64_decoded = base::Base64Decode(companion_url_param); auto serialized_proto = std::string(base64_decoded.value().begin(), base64_decoded.value().end()); EXPECT_TRUE(proto.ParseFromString(serialized_proto)); @@ -107,9 +109,18 @@ EXPECT_TRUE(net::GetValueForKeyInQuery(companion_url, "origin", &value)); EXPECT_EQ(value, kOrigin); + std::string companion_url_param; + EXPECT_TRUE(net::GetValueForKeyInQuery(companion_url, "companion_query", + &companion_url_param)); + + // Verify that both helper methods generate the same proto. + std::string encoded_proto = + url_builder_->BuildCompanionUrlParamProto(page_url); + EXPECT_EQ(encoded_proto, companion_url_param); + // Deserialize the query param into protobuf. companion::proto::CompanionUrlParams proto = - DeserializeCompanionRequest(companion_url); + DeserializeCompanionRequest(companion_url_param); // URL shouldn't be sent when MSBB is off. EXPECT_EQ(proto.page_url(), std::string()); @@ -130,9 +141,18 @@ EXPECT_TRUE(net::GetValueForKeyInQuery(companion_url, "origin", &value)); EXPECT_EQ(value, kOrigin); + std::string companion_url_param; + EXPECT_TRUE(net::GetValueForKeyInQuery(companion_url, "companion_query", + &companion_url_param)); + + // Verify that both helper methods generate the same proto. + std::string encoded_proto = + url_builder_->BuildCompanionUrlParamProto(page_url); + EXPECT_EQ(encoded_proto, companion_url_param); + // Deserialize the query param into protobuf. companion::proto::CompanionUrlParams proto = - DeserializeCompanionRequest(companion_url); + DeserializeCompanionRequest(companion_url_param); // Verify fields inside protobuf. EXPECT_EQ(proto.page_url(), page_url.spec());
diff --git a/chrome/browser/companion/core/constants.h b/chrome/browser/companion/core/constants.h index 6ee0a55..47a1a9ba 100644 --- a/chrome/browser/companion/core/constants.h +++ b/chrome/browser/companion/core/constants.h
@@ -15,6 +15,10 @@ const char kExpsPromoDeclinedCountPref[] = "Companion.Promo.Exps.Declined.Count"; +// Pref name for storing experience opt-in status. +const char kExpsOptInStatusGrantedPref[] = + "Companion.Exps.OptIn.Status.Granted"; + } // namespace companion #endif // CHROME_BROWSER_COMPANION_CORE_CONSTANTS_H_
diff --git a/chrome/browser/companion/core/mojom/companion.mojom b/chrome/browser/companion/core/mojom/companion.mojom index 2aca54f..b4d86e38 100644 --- a/chrome/browser/companion/core/mojom/companion.mojom +++ b/chrome/browser/companion/core/mojom/companion.mojom
@@ -15,6 +15,9 @@ // Method called in response to user clicking on the region search button. kOnRegionSearchClicked = 2, + + // Method called when user's experience opt-in status is available. + kOnExpsOptInStatusAvailable = 3, }; // Types of promos shown in the companion UI. @@ -63,11 +66,20 @@ // Called to notify the browser that user has clicked on region search button. OnRegionSearchClicked(); + + // Called to notify the browser that the user's experience opt-in status is + // available. + OnExpsOptInStatusAvailable(bool is_exps_opted_in); }; // WebUI page handler for request from Browser side. (C++ -> TypeScript) interface CompanionPage { // Pass the companion URL needed to request the iframe to the frontend for - // rendering. - OnURLChanged(url.mojom.Url new_url); + // rendering. Results in a full reload of the companion side panel. + LoadCompanionPage(url.mojom.Url new_url); + + // Notifies the companion page about subsequent navigations on the main page. + // Results in a postmessage() call to the companion with the encoded protobuf + // representation of the update params. + UpdateCompanionPage(string companion_update_proto); };
diff --git a/chrome/browser/companion/core/promo_handler.cc b/chrome/browser/companion/core/promo_handler.cc index 9e86aea..7b116ae 100644 --- a/chrome/browser/companion/core/promo_handler.cc +++ b/chrome/browser/companion/core/promo_handler.cc
@@ -27,6 +27,8 @@ registry->RegisterIntegerPref(kMsbbPromoDeclinedCountPref, 0); registry->RegisterIntegerPref(kSigninPromoDeclinedCountPref, 0); registry->RegisterIntegerPref(kExpsPromoDeclinedCountPref, 0); + // TODO(shaktisahu): Move the pref registration to a better location. + registry->RegisterBooleanPref(kExpsOptInStatusGrantedPref, false); } void PromoHandler::OnPromoAction(PromoType promo_type,
diff --git a/chrome/browser/component_updater/pki_metadata_component_installer.cc b/chrome/browser/component_updater/pki_metadata_component_installer.cc index 404c6d7a..10ff8cf 100644 --- a/chrome/browser/component_updater/pki_metadata_component_installer.cc +++ b/chrome/browser/component_updater/pki_metadata_component_installer.cc
@@ -43,9 +43,7 @@ #endif #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) -#include "chrome/browser/net/cert_verifier_configuration.h" #include "mojo/public/cpp/base/big_buffer.h" -#include "net/base/features.h" #include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" #endif @@ -478,21 +476,21 @@ #endif // BUILDFLAG(IS_CT_SUPPORTED) #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - should_install |= GetChromeCertVerifierServiceParams(/*local_state=*/nullptr) - ->use_chrome_root_store; -#else + // If Chrome Root Store is supported, always install the component. + // Note that if CRS is supported but optional, the CRS setting can change + // during runtime based on the enterprise policy, so we still have to install + // the component now so that CRS updates will be processed in case we need + // them later. (Might be possible to refactor to only install component later + // when it's needed and if it's not already installed? Probably not worth the + // trouble though since CRS being optional is only a temporary state.) + // Note: On Android CRS will continue to be optional in code since chrome + // browser and webview use the same binary, but eventually it will just be + // unconditionally enabled in chrome and disabled in webview. This component + // is not registered in webview so setting it to always install here isn't a + // problem. should_install = true; #endif -// Even if we aren't using Chrome Root Store for cert verification, we may be -// trialing it. Check if the trial is enabled. -#if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED) - should_install |= base::FeatureList::IsEnabled( - net::features::kCertDualVerificationTrialFeature); -#endif -#endif - if (!should_install) return;
diff --git a/chrome/browser/component_updater/pki_metadata_component_installer_unittest.cc b/chrome/browser/component_updater/pki_metadata_component_installer_unittest.cc index 4c92d6d..a0b67dd 100644 --- a/chrome/browser/component_updater/pki_metadata_component_installer_unittest.cc +++ b/chrome/browser/component_updater/pki_metadata_component_installer_unittest.cc
@@ -544,28 +544,13 @@ // component updater and KP component updater features are disabled. TEST_F(PKIMetadataComponentInstallerDisabledTest, MaybeDoNotRegisterIfFeatureDisabled) { -#if BUILDFLAG(CHROME_ROOT_STORE_ONLY) - // Chrome Root Store is unconditionally used on this build config, so PKI - // metadata component will always be registered even if the other feature - // flags are disabled. +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) + // If Chrome Root Store is supported on this build config, PKI metadata + // component will always be registered even if the other feature flags are + // disabled. EXPECT_CALL(mock_component_update_, RegisterComponent) .Times(1) .WillOnce(testing::Return(true)); -#elif BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { - // If ChromeRootStoreUsed feature is enabled by default, PKI metadata - // component will always be registered. It is not safe to change the - // kChromeRootStoreUsed flag in unit_tests since multiple tests run in - // the same process, and GetChromeCertVerifierServiceParams will - // globally enforce a single configuration for the lifetime of the - // process. Therefore test that the component is registered if CRS is - // enabled. - EXPECT_CALL(mock_component_update_, RegisterComponent) - .Times(1) - .WillOnce(testing::Return(true)); - } else { - EXPECT_CALL(mock_component_update_, RegisterComponent).Times(0); - } #else EXPECT_CALL(mock_component_update_, RegisterComponent).Times(0); #endif
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 5db4139..2ede7a50 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -6925,6 +6925,16 @@ "expiry_milestone": 120 }, { + "name": "smds-support", + "owners": ["chadduffin", "cros-connectivity@google.com"], + "expiry_milestone": 125 + }, + { + "name": "smds-support-euicc-upload", + "owners": ["chadduffin", "cros-connectivity@google.com"], + "expiry_milestone": 125 + }, + { "name": "smooth-scrolling", "owners": [ "bokan", "input-dev" ], // This flag is needed for debugging scrolling issues. However, it can be
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 78bc4b2..edac55e9 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -6436,6 +6436,19 @@ "Feature to allow MAC address randomization to be enabled for WiFi " "networks."; +const char kSmdsSupportName[] = "SM-DS Support"; +const char kSmdsSupportDescription[] = + "Feature to enable the consumer and enterprise support for provisioning " + "eSIM profiles using Subscription Manager Discovery Service (SM-DS). This " + "flag is a no-op unless the smds-dbus-migration flag is enabled"; + +const char kSmdsSupportEuiccUploadName[] = "SM-DS Support EUICC Upload"; +const char kSmdsSupportEuiccUploadDescription[] = + "Feature to enable tracking when a policy-defined cellular network " + "configured to use SM-DS has already been applied and an eSIM profile for " + "the network was installed. This flag is a no-op unless the smds-support " + "and smds-dbus-migration flags are enabled."; + const char kSmdsDbusMigrationName[] = "SM-DS DBus Migration"; const char kSmdsDbusMigrationDescription[] = "Feature to enable the usage of DBus APIs that improve the stability"
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 0f0b4b7a..9a31853 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -3704,6 +3704,12 @@ extern const char kMacAddressRandomizationName[]; extern const char kMacAddressRandomizationDescription[]; +extern const char kSmdsSupportName[]; +extern const char kSmdsSupportDescription[]; + +extern const char kSmdsSupportEuiccUploadName[]; +extern const char kSmdsSupportEuiccUploadDescription[]; + extern const char kSmdsDbusMigrationName[]; extern const char kSmdsDbusMigrationDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 6f0aca0..7199429 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -1025,7 +1025,7 @@ BASE_FEATURE(kDiscoverFeedMultiColumn, "DiscoverFeedMultiColumn", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kTabStripRedesign, "TabStripRedesign",
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 0de5a489..9c079d8 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -597,7 +597,7 @@ new CachedFlag(COMMAND_LINE_ON_NON_ROOTED, false); public static final CachedFlag sCriticalPersistedTabData = new CachedFlag(CRITICAL_PERSISTED_TAB_DATA, false); - public static final CachedFlag sDiscoverMultiColumn = new CachedFlag(FEED_MULTI_COLUMN, false); + public static final CachedFlag sDiscoverMultiColumn = new CachedFlag(FEED_MULTI_COLUMN, true); public static final CachedFlag sEarlyLibraryLoad = new CachedFlag(EARLY_LIBRARY_LOAD, true); public static final CachedFlag sExperimentsForAgsa = new CachedFlag(EXPERIMENTS_FOR_AGSA, true); public static final CachedFlag sFeedLoadingPlaceholder =
diff --git a/chrome/browser/image_editor/event_capture_mac.h b/chrome/browser/image_editor/event_capture_mac.h index bfafe93..21e4d9f 100644 --- a/chrome/browser/image_editor/event_capture_mac.h +++ b/chrome/browser/image_editor/event_capture_mac.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_IMAGE_EDITOR_EVENT_CAPTURE_MAC_H_ #define CHROME_BROWSER_IMAGE_EDITOR_EVENT_CAPTURE_MAC_H_ +#include <memory> + #include "base/functional/callback.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" @@ -46,11 +48,11 @@ gfx::NativeWindow target_native_window); base::OnceClosure capture_lost_callback_; - NSView* web_contents_view_; - NSWindow* window_; raw_ptr<ui::EventHandler> event_handler_; std::unique_ptr<remote_cocoa::CocoaMouseCapture> mouse_capture_; - id local_keyboard_monitor_ = nil; + + struct ObjCStorage; + std::unique_ptr<ObjCStorage> objc_storage_; base::WeakPtrFactory<EventCaptureMac> factory_{this}; };
diff --git a/chrome/browser/image_editor/event_capture_mac.mm b/chrome/browser/image_editor/event_capture_mac.mm index 01bd2c5f..b2279db 100644 --- a/chrome/browser/image_editor/event_capture_mac.mm +++ b/chrome/browser/image_editor/event_capture_mac.mm
@@ -6,6 +6,8 @@ #import <Cocoa/Cocoa.h> +#include <memory> + #include "base/check.h" #include "base/functional/callback.h" #include "base/memory/ptr_util.h" @@ -15,14 +17,21 @@ namespace image_editor { +struct EventCaptureMac::ObjCStorage { + NSView* web_contents_view_ = nil; + NSWindow* window_ = nil; + id local_keyboard_monitor_ = nil; +}; + EventCaptureMac::EventCaptureMac(ui::EventHandler* event_handler, base::OnceClosure capture_lost_callback, gfx::NativeView web_contents_view, gfx::NativeWindow target_native_window) - : capture_lost_callback_(std::move(capture_lost_callback)) { + : capture_lost_callback_(std::move(capture_lost_callback)), + objc_storage_(std::make_unique<ObjCStorage>()) { event_handler_ = event_handler; - web_contents_view_ = web_contents_view.GetNativeNSView(); - window_ = target_native_window.GetNativeNSWindow(); + objc_storage_->web_contents_view_ = web_contents_view.GetNativeNSView(); + objc_storage_->window_ = target_native_window.GetNativeNSWindow(); mouse_capture_ = std::make_unique<remote_cocoa::CocoaMouseCapture>(this); CreateKeyDownLocalMonitor(event_handler, target_native_window); @@ -62,7 +71,7 @@ }; NSEventMask event_mask = NSEventMaskKeyDown; - local_keyboard_monitor_ = + objc_storage_->local_keyboard_monitor_ = [NSEvent addLocalMonitorForEventsMatchingMask:event_mask handler:block]; } @@ -72,7 +81,7 @@ std::move(capture_lost_callback_).Reset(); mouse_capture_.reset(); // Remove keydown monitor - [NSEvent removeMonitor:local_keyboard_monitor_]; + [NSEvent removeMonitor:objc_storage_->local_keyboard_monitor_]; } bool EventCaptureMac::PostCapturedEvent(NSEvent* event) { @@ -90,10 +99,11 @@ if (type == ui::ET_MOUSE_DRAGGED || type == ui::ET_MOUSE_RELEASED) { event_handler_->OnMouseEvent(ui_event->AsMouseEvent()); } else if ((type == ui::ET_MOUSE_PRESSED || type == ui::ET_MOUSE_MOVED) && - web_contents_view_ == view) { + objc_storage_->web_contents_view_ == view) { // We do not need to record mouse clicks outside of the web contents. event_handler_->OnMouseEvent(ui_event->AsMouseEvent()); - } else if (type == ui::ET_MOUSE_MOVED && web_contents_view_ != view) { + } else if (type == ui::ET_MOUSE_MOVED && + objc_storage_->web_contents_view_ != view) { // Manually set arrow cursor when region search UI is open and cursor is // moved from web contents. [[NSCursor arrowCursor] set]; @@ -111,7 +121,7 @@ } NSWindow* EventCaptureMac::GetWindow() const { - return window_; + return objc_storage_->window_; } void EventCaptureMac::SetCrossCursor() {
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager.cc b/chrome/browser/nearby_sharing/nearby_notification_manager.cc index 30fb34d..01f9feb 100644 --- a/chrome/browser/nearby_sharing/nearby_notification_manager.cc +++ b/chrome/browser/nearby_sharing/nearby_notification_manager.cc
@@ -7,6 +7,7 @@ #include <string> #include "ash/constants/notifier_catalogs.h" +#include "ash/public/cpp/holding_space/holding_space_item.h" #include "ash/public/cpp/notification_utils.h" #include "base/files/file_util.h" #include "base/functional/callback_helpers.h" @@ -1104,7 +1105,9 @@ if (holding_space_keyed_service) { for (const auto& file : share_target.file_attachments) { if (file.file_path().has_value()) - holding_space_keyed_service->AddNearbyShare(file.file_path().value()); + holding_space_keyed_service->AddItemOfType( + ash::HoldingSpaceItem::Type::kNearbyShare, + file.file_path().value()); } } }
diff --git a/chrome/browser/net/cert_verifier_configuration.cc b/chrome/browser/net/cert_verifier_configuration.cc deleted file mode 100644 index c33a553..0000000 --- a/chrome/browser/net/cert_verifier_configuration.cc +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/net/cert_verifier_configuration.h" - -#include "base/no_destructor.h" -#include "chrome/browser/browser_process.h" -#include "chrome/common/buildflags.h" -#include "chrome/common/pref_names.h" -#include "components/prefs/pref_service.h" -#include "net/base/features.h" -#include "net/net_buildflags.h" - -namespace { - -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) -bool ShouldUseChromeRootStore(PrefService* local_state) { -#if BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) - // `local_state` should exist when this is called in the browser, but may be - // null in unit_tests. - if (local_state) { - const PrefService::Preference* chrome_root_store_enabled_pref = - local_state->FindPreference(prefs::kChromeRootStoreEnabled); - if (chrome_root_store_enabled_pref->IsManaged()) - return chrome_root_store_enabled_pref->GetValue()->GetBool(); - } -#endif // BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) - return base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed); -} -#endif // BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - -// Calculates and caches the CertVerifierServiceParams so that all calls to -// GetChromeCertVerifierServiceParams will return the same params. The -// params are controllable by enterprise policies which can change during -// runtime, but dynamic updates are not supported, since changing the value -// would not update any existing verifiers that had already been created. -// -// Aside from just being confusing, there are some implementations where -// creating multiple configurations of the verifier in the same process is not -// possible. (For example, using the NSS trust anchors requires a shared -// library to be loaded, while another configuration that doesn't want to use -// the NSS trust anchors may require that library *not* be loaded. See -// https://crbug.com/1340420.) -class CertVerifierServiceConfigurationStorage { - public: - explicit CertVerifierServiceConfigurationStorage(PrefService* local_state) { - params_ = cert_verifier::mojom::CertVerifierServiceParams::New(); - -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - if (!local_state) { - local_state = g_browser_process->local_state(); - } - params_->use_chrome_root_store = ShouldUseChromeRootStore(local_state); -#endif - } - ~CertVerifierServiceConfigurationStorage() = delete; - - cert_verifier::mojom::CertVerifierServiceParamsPtr Params() const { - return params_.Clone(); - } - - private: - cert_verifier::mojom::CertVerifierServiceParamsPtr params_; -}; - -} // namespace - -cert_verifier::mojom::CertVerifierServiceParamsPtr -GetChromeCertVerifierServiceParams(PrefService* local_state) { - static base::NoDestructor<CertVerifierServiceConfigurationStorage> storage( - local_state); - - return storage->Params(); -}
diff --git a/chrome/browser/net/cert_verifier_configuration.h b/chrome/browser/net/cert_verifier_configuration.h deleted file mode 100644 index e2178f8d..0000000 --- a/chrome/browser/net/cert_verifier_configuration.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_NET_CERT_VERIFIER_CONFIGURATION_H_ -#define CHROME_BROWSER_NET_CERT_VERIFIER_CONFIGURATION_H_ - -#include "components/prefs/pref_service.h" -#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" - -// Gets parameters to use for creating the Chrome Cert Verifier. -// -// `local_state` may be passed in to support running in minimal_browser_mode, -// where some services start up before the Browser process -// (see -// https://docs.google.com/document/d/1ybmGWRWXu0aYNxA99IcHFesDAslIaO1KFP6eGdHTJaE/edit#heading=h.7bk05syrcom). -// -// If `local_state` is null, g_browser_process->local_state() will be used. -cert_verifier::mojom::CertVerifierServiceParamsPtr -GetChromeCertVerifierServiceParams(PrefService* local_state); - -#endif // CHROME_BROWSER_NET_CERT_VERIFIER_CONFIGURATION_H_
diff --git a/chrome/browser/net/cert_verifier_service_browsertest.cc b/chrome/browser/net/cert_verifier_service_browsertest.cc index 05a23ff..96f7b24 100644 --- a/chrome/browser/net/cert_verifier_service_browsertest.cc +++ b/chrome/browser/net/cert_verifier_service_browsertest.cc
@@ -6,7 +6,9 @@ #include "base/test/scoped_feature_list.h" #include "base/test/test_future.h" #include "build/build_config.h" -#include "chrome/browser/net/cert_verifier_configuration.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/interstitials/security_interstitial_page_test_utils.h" +#include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/policy/policy_test_utils.h" #include "chrome/common/buildflags.h" #include "components/policy/core/common/policy_map.h" @@ -14,8 +16,12 @@ #include "content/public/browser/network_service_instance.h" #include "content/public/test/browser_test.h" #include "net/base/features.h" +#include "net/cert/internal/trust_store_chrome.h" #include "net/cert/internal/trust_store_features.h" +#include "net/cert/x509_util.h" #include "net/net_buildflags.h" +#include "net/test/cert_test_util.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -27,6 +33,11 @@ std::tuple<bool, absl::optional<bool>>> { public: void SetUpInProcessBrowserTestFixture() override { + // This test puts a test cert in the Chrome Root Store, which will fail in + // builds where Certificate Transparency is required, so disable CT + // during this test. + SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( + false); scoped_feature_list_.InitWithFeatureState( net::features::kChromeRootStoreUsed, feature_use_chrome_root_store()); @@ -49,33 +60,9 @@ UpdateProviderPolicy(policies); } - void ExpectUseChromeRootStoreCorrect(bool use_chrome_root_store) { - { - cert_verifier::mojom::CertVerifierServiceParamsPtr params = - GetChromeCertVerifierServiceParams(/*local_state=*/nullptr); - ASSERT_TRUE(params); - EXPECT_EQ(use_chrome_root_store, params->use_chrome_root_store); - } - - // Change the policy value, and then test the params returned by - // GetChromeCertVerifierServiceParams do not change. - SetPolicyValue(!use_chrome_root_store); - { - cert_verifier::mojom::CertVerifierServiceParamsPtr params = - GetChromeCertVerifierServiceParams(/*local_state=*/nullptr); - ASSERT_TRUE(params); - EXPECT_EQ(use_chrome_root_store, params->use_chrome_root_store); - } - - // Also test the params the actual CertVerifierServiceFactory was created - // with, to ensure the values are being plumbed through properly. - base::test::TestFuture<cert_verifier::mojom::CertVerifierServiceParamsPtr> - service_params_future; - content::GetCertVerifierServiceFactory()->GetServiceParamsForTesting( - service_params_future.GetCallback()); - ASSERT_TRUE(service_params_future.Get()); - EXPECT_EQ(use_chrome_root_store, - service_params_future.Get()->use_chrome_root_store); + void TearDownInProcessBrowserTestFixture() override { + SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( + absl::nullopt); } bool feature_use_chrome_root_store() const { return std::get<0>(GetParam()); } @@ -97,7 +84,81 @@ IN_PROC_BROWSER_TEST_P(CertVerifierServiceChromeRootStoreFeaturePolicyTest, Test) { - ExpectUseChromeRootStoreCorrect(expected_use_chrome_root_store()); + // IsUsingChromeRootStore return value should match the expected state. + EXPECT_EQ( + expected_use_chrome_root_store(), + SystemNetworkContextManager::GetInstance()->IsUsingChromeRootStore()); + + net::EmbeddedTestServer https_test_server( + net::EmbeddedTestServer::TYPE_HTTPS); + // Use a runtime generated cert, as the pre-generated ok_cert has too long of + // a validity period to be accepted by a publicly trusted root. + https_test_server.SetSSLConfig( + net::test_server::EmbeddedTestServer::CERT_AUTO); + ASSERT_TRUE(https_test_server.Start()); + + // Clear test roots so that cert validation only happens with + // what's in the relevant root store. + net::TestRootCerts::GetInstance()->Clear(); + + { + // Create updated Chrome Root Store with just the test server root cert. + chrome_root_store::RootStore root_store_proto; + root_store_proto.set_version_major(net::CompiledChromeRootStoreVersion() + + 1); + + chrome_root_store::TrustAnchor* anchor = + root_store_proto.add_trust_anchors(); + scoped_refptr<net::X509Certificate> root_cert = + net::ImportCertFromFile(net::EmbeddedTestServer::GetRootCertPemPath()); + ASSERT_TRUE(root_cert); + anchor->set_der(std::string( + net::x509_util::CryptoBufferAsStringPiece(root_cert->cert_buffer()))); + + std::string proto_serialized; + root_store_proto.SerializeToString(&proto_serialized); + cert_verifier::mojom::ChromeRootStorePtr root_store_ptr = + cert_verifier::mojom::ChromeRootStore::New( + base::as_bytes(base::make_span(proto_serialized))); + + base::RunLoop update_run_loop; + content::GetCertVerifierServiceFactory()->UpdateChromeRootStore( + std::move(root_store_ptr), update_run_loop.QuitClosure()); + update_run_loop.Run(); + } + + ASSERT_TRUE(NavigateToUrl(https_test_server.GetURL("/simple.html"), this)); + + // The navigation should show an interstitial if CRS was not in use, since + // the root was only trusted in the test CRS update and won't be trusted by + // the platform roots that are used when CRS is not used. + EXPECT_NE(expected_use_chrome_root_store(), + chrome_browser_interstitials::IsShowingInterstitial( + chrome_test_utils::GetActiveWebContents(this))); + +#if BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) + // Set the policy to the opposite. + bool new_expected_use_chrome_root_store = !expected_use_chrome_root_store(); + SetPolicyValue(new_expected_use_chrome_root_store); + + // IsUsingChromeRootStore return value should match the new policy setting. + EXPECT_EQ( + new_expected_use_chrome_root_store, + SystemNetworkContextManager::GetInstance()->IsUsingChromeRootStore()); + + // The SetUseChromeRootStore message should have been dispatched to the + // CertVerifierServiceFactory but may not have actually been processed yet. + // Doing a round-trip to the CertVerifierServiceFactory and back should + // ensure that the previous message in the queue has already been processed. + content::GetCertVerifierServiceFactoryRemoteForTesting().FlushForTesting(); + + ASSERT_TRUE(NavigateToUrl(https_test_server.GetURL("/title2.html"), this)); + + // Navigating to the test server again should respect the new policy setting. + EXPECT_NE(new_expected_use_chrome_root_store, + chrome_browser_interstitials::IsShowingInterstitial( + chrome_test_utils::GetActiveWebContents(this))); +#endif } INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 4bd6ecde..81851ba 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -111,7 +111,6 @@ #endif // BUILDFLAG(IS_MAC) #if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED) -#include "chrome/browser/net/cert_verifier_configuration.h" #include "chrome/browser/net/trial_comparison_cert_verifier_controller.h" #endif @@ -902,27 +901,8 @@ network_context_params->ct_policy = GetCTPolicy(); #if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED) - // In order for the TrialComparisonCertVerifier to be useful, it needs to - // provide comparisons between two well-defined verifier configurations; this - // means the currently launched cert verifier (and root store) and the - // prospective cert verifier (and root store). - // - // It's possible that, due to user configuration, such as enterprise policies, - // the user may be requesting a non-standard configuration from the current - // default. In these cases, the trial verifier is also disabled, - // because all users in the trial should be running in the same configuration. DCHECK(cert_verifier_creation_params); - bool is_trial_comparison_supported = !in_memory; - - cert_verifier::mojom::CertVerifierServiceParamsPtr - cert_verifier_configuration = - GetChromeCertVerifierServiceParams(/*local_state=*/nullptr); - DCHECK(cert_verifier_configuration); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - is_trial_comparison_supported &= - !cert_verifier_configuration->use_chrome_root_store; -#endif - if (is_trial_comparison_supported && + if (!in_memory && TrialComparisonCertVerifierController::MaybeAllowedForProfile(profile_)) { mojo::PendingRemote< cert_verifier::mojom::TrialComparisonCertVerifierConfigClient>
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc index ed475ffa8..f67f0f7 100644 --- a/chrome/browser/net/system_network_context_manager.cc +++ b/chrome/browser/net/system_network_context_manager.cc
@@ -488,6 +488,20 @@ &SystemNetworkContextManager::UpdateExplicitlyAllowedNetworkPorts, base::Unretained(this))); +#if BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) + pref_change_registrar_.Add( + prefs::kChromeRootStoreEnabled, + base::BindRepeating( + &SystemNetworkContextManager::UpdateChromeRootStoreEnabled, + base::Unretained(this))); + // Call the update function immediately to set the initial value, if any. + // TODO(https://crbug.com/1085233): If CertVerifierServiceFactory is moved to + // a separate process, will need to handle restarts so that the current value + // can be re-initialized into the cert verifier service process when it is + // re-created. + UpdateChromeRootStoreEnabled(); +#endif // BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) + #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) pref_change_registrar_.Add( @@ -932,6 +946,19 @@ #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OFFICIAL_BUILD) } +#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) +bool SystemNetworkContextManager::IsUsingChromeRootStore() { +#if BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) + const PrefService::Preference* chrome_root_store_enabled_pref = + local_state_->FindPreference(prefs::kChromeRootStoreEnabled); + if (chrome_root_store_enabled_pref->IsManaged()) { + return chrome_root_store_enabled_pref->GetValue()->GetBool(); + } +#endif // BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) + return base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed); +} +#endif // BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) + network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateNetworkContextParams() { // TODO(mmenke): Set up parameters here (in memory cookie store, etc). @@ -955,6 +982,13 @@ ConvertExplicitlyAllowedNetworkPortsPref(local_state_)); } +#if BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) +void SystemNetworkContextManager::UpdateChromeRootStoreEnabled() { + content::GetCertVerifierServiceFactory()->SetUseChromeRootStore( + IsUsingChromeRootStore(), base::DoNothing()); +} +#endif // BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) + #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) void SystemNetworkContextManager::UpdateEnforceLocalAnchorConstraintsEnabled() {
diff --git a/chrome/browser/net/system_network_context_manager.h b/chrome/browser/net/system_network_context_manager.h index 48bad7db..15b5e77 100644 --- a/chrome/browser/net/system_network_context_manager.h +++ b/chrome/browser/net/system_network_context_manager.h
@@ -14,6 +14,7 @@ #include "chrome/browser/net/proxy_config_monitor.h" #include "chrome/browser/net/stub_resolver_config_reader.h" #include "chrome/browser/ssl/ssl_config_service_manager.h" +#include "chrome/common/buildflags.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_member.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -172,6 +173,10 @@ stub_resolver_config_reader_for_testing_ = reader; } +#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) + bool IsUsingChromeRootStore(); +#endif // BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) + private: FRIEND_TEST_ALL_PREFIXES( SystemNetworkContextServiceCertVerifierBuiltinPermissionsPolicyTest, @@ -193,6 +198,10 @@ // the network process. void UpdateExplicitlyAllowedNetworkPorts(); +#if BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) + void UpdateChromeRootStoreEnabled(); +#endif // BUILDFLAG(CHROME_ROOT_STORE_POLICY_SUPPORTED) + #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) // Applies the current value of the kEnforceLocalAnchorConstraintsEnabled
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_browsertest.cc b/chrome/browser/net/trial_comparison_cert_verifier_browsertest.cc index 0796e419..a7aaeb5 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_browsertest.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h" +#include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/net/trial_comparison_cert_verifier_controller.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/ssl_browsertest_util.h" @@ -23,7 +24,9 @@ #include "net/base/features.h" #include "net/cert/trial_comparison_cert_verifier.h" #include "net/cert/trial_comparison_cert_verifier_util.h" +#include "net/cert/x509_util.h" #include "net/net_buildflags.h" +#include "net/test/cert_test_util.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/test_data_directory.h" #include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" @@ -174,44 +177,164 @@ #if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) class TrialComparisonCertVerifierFeatureOverridenByChromeRootStoreTest - : public TrialComparisonCertVerifierTest { + : public TrialComparisonCertVerifierTest, + public testing::WithParamInterface<bool> { public: TrialComparisonCertVerifierFeatureOverridenByChromeRootStoreTest() { TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting(true); + // This test puts a test cert in the Chrome Root Store, which will fail in + // builds where Certificate Transparency is required, so disable CT + // during this test. + SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( + false); + + // These tests should generate a report, set the trial to uma_only mode so + // that it won't actually try to send it. + std::vector<base::test::FeatureRefAndParams> enabled_features = { + {net::features::kCertDualVerificationTrialFeature, + {{"uma_only", "true"}}}}; + + std::vector<base::test::FeatureRef> disabled_features; + + if (CRSFeatureStartsEnabled()) { + enabled_features.push_back({net::features::kChromeRootStoreUsed, {}}); + } else { + disabled_features.push_back(net::features::kChromeRootStoreUsed); + } + scoped_feature_ = std::make_unique<base::test::ScopedFeatureList>(); - scoped_feature_->InitWithFeaturesAndParameters( - // None of these tests should generate a report, but set the trial to - // uma_only mode anyway just to be safe. - {{net::features::kCertDualVerificationTrialFeature, - {{"uma_only", "true"}}}, - // Enable the Chrome Root Store. - {net::features::kChromeRootStoreUsed, {}}}, - {}); + scoped_feature_->InitWithFeaturesAndParameters(enabled_features, + disabled_features); } ~TrialComparisonCertVerifierFeatureOverridenByChromeRootStoreTest() override { + SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( + absl::nullopt); TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting( false); } + bool CRSFeatureStartsEnabled() const { return GetParam(); } + protected: std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_; }; -IN_PROC_BROWSER_TEST_F( +IN_PROC_BROWSER_TEST_P( TrialComparisonCertVerifierFeatureOverridenByChromeRootStoreTest, TrialEnabledPrefEnabledBuiltVerifierEnabled) { safe_browsing::SetExtendedReportingPrefForTests( browser()->profile()->GetPrefs(), true); + // Use a runtime generated cert, as the pre-generated ok_cert has too long of + // a validity period to be accepted by a publicly trusted root. + https_test_server_.SetSSLConfig( + net::test_server::EmbeddedTestServer::CERT_AUTO); ASSERT_TRUE(https_test_server_.Start()); - base::HistogramTester histograms; - ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), https_test_server_.GetURL("/title1.html"))); - metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency", 1); - // If both the dual cert verifier trial feature and the Chrome Root Store - // feature are enabled, the dual cert verifier trial should not be used. - histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 0); + + { + // Create updated Chrome Root Store with just the test server root cert. + chrome_root_store::RootStore root_store_proto; + root_store_proto.set_version_major(net::CompiledChromeRootStoreVersion() + + 1); + + chrome_root_store::TrustAnchor* anchor = + root_store_proto.add_trust_anchors(); + scoped_refptr<net::X509Certificate> root_cert = + net::ImportCertFromFile(net::EmbeddedTestServer::GetRootCertPemPath()); + ASSERT_TRUE(root_cert); + anchor->set_der(std::string( + net::x509_util::CryptoBufferAsStringPiece(root_cert->cert_buffer()))); + + std::string proto_serialized; + root_store_proto.SerializeToString(&proto_serialized); + cert_verifier::mojom::ChromeRootStorePtr root_store_ptr = + cert_verifier::mojom::ChromeRootStore::New( + base::as_bytes(base::make_span(proto_serialized))); + + base::RunLoop update_run_loop; + content::GetCertVerifierServiceFactory()->UpdateChromeRootStore( + std::move(root_store_ptr), update_run_loop.QuitClosure()); + update_run_loop.Run(); + } + + // Clear test roots so that cert validation only happens with + // what's in the relevant root store. + net::TestRootCerts::GetInstance()->Clear(); + + // Now verifying the test server certificate should fail with the primary + // verifier and succeed with the trial verifier since only the trial verifier + // uses the RotStore update which contains the test cert. + + { + base::HistogramTester histograms; + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_test_server_.GetURL("/title1.html"))); + metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency", 1); + + if (CRSFeatureStartsEnabled()) { + // Should have loaded successfully. + EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial( + chrome_test_utils::GetActiveWebContents(this))); + // If both the dual cert verifier trial feature and the Chrome Root Store + // feature are enabled, the dual cert verifier trial should not be done. + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", + 0); + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", + 0); + } else { + // Should not have loaded and should show an SSL interstitial. + EXPECT_TRUE(chrome_browser_interstitials::IsShowingInterstitial( + chrome_test_utils::GetActiveWebContents(this))); + // Trial should have been run. + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", + 1); + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", + 1); + } + } + + const bool new_crs_state = !CRSFeatureStartsEnabled(); + { + base::RunLoop run_loop; + content::GetCertVerifierServiceFactory()->SetUseChromeRootStore( + new_crs_state, run_loop.QuitClosure()); + run_loop.Run(); + } + + { + base::HistogramTester histograms; + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_test_server_.GetURL("/title2.html"))); + metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency", 1); + + if (new_crs_state) { + // Should have loaded successfully. + EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial( + chrome_test_utils::GetActiveWebContents(this))); + // If both the dual cert verifier trial feature and the Chrome Root Store + // feature are enabled, the dual cert verifier trial should not be done. + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", + 0); + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", + 0); + } else { + // Should not have loaded and should show an SSL interstitial. + EXPECT_TRUE(chrome_browser_interstitials::IsShowingInterstitial( + chrome_test_utils::GetActiveWebContents(this))); + // Trial should have been run. + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", + 1); + histograms.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", + 1); + } + } } + +INSTANTIATE_TEST_SUITE_P( + All, + TrialComparisonCertVerifierFeatureOverridenByChromeRootStoreTest, + ::testing::Bool()); #endif // BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL)
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_controller.cc b/chrome/browser/net/trial_comparison_cert_verifier_controller.cc index 221084af..ac4110ab 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_controller.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_controller.cc
@@ -14,7 +14,6 @@ #include "build/branding_buildflags.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/net/cert_verifier_configuration.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/certificate_reporting_service.h" #include "chrome/browser/safe_browsing/certificate_reporting_service_factory.h" @@ -66,14 +65,6 @@ is_official_build = true; #endif -#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) - // If the Chrome Root Store is enabled as part of the default verifier, the - // trial does not make sense. - if (GetChromeCertVerifierServiceParams(/*local_state=*/nullptr) - ->use_chrome_root_store) - return false; -#endif - return is_official_build && base::FeatureList::IsEnabled( net::features::kCertDualVerificationTrialFeature) &&
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_controller_unittest.cc b/chrome/browser/net/trial_comparison_cert_verifier_controller_unittest.cc index 770bd9e6..83c80cb 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_controller_unittest.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_controller_unittest.cc
@@ -296,17 +296,6 @@ TEST_P(TrialComparisonCertVerifierControllerTest, NotOfficialBuildTrialEnabled) { -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { - // If ChromeRootStoreUsed feature is enabled by default, - // TrialComparisonCertVerifier will not be allowed. It is not safe to - // change the kChromeRootStoreUsed flag in unit_tests since multiple tests - // run in the same process, and GetChromeCertVerifierServiceParams will - // globally enforce a single configuration for the lifetime of the - // process. Therefore just skip this test if CRS is enabled. - GTEST_SKIP(); - } -#endif scoped_feature_ = std::make_unique<base::test::ScopedFeatureList>(); scoped_feature_->InitAndEnableFeature( net::features::kCertDualVerificationTrialFeature); @@ -345,17 +334,6 @@ } TEST_P(TrialComparisonCertVerifierControllerTest, OfficialBuildTrialEnabled) { -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { - // If ChromeRootStoreUsed feature is enabled by default, - // TrialComparisonCertVerifier will not be allowed. It is not safe to - // change the kChromeRootStoreUsed flag in unit_tests since multiple tests - // run in the same process, and GetChromeCertVerifierServiceParams will - // globally enforce a single configuration for the lifetime of the - // process. Therefore just skip this test if CRS is enabled. - GTEST_SKIP(); - } -#endif TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting(true); scoped_feature_ = std::make_unique<base::test::ScopedFeatureList>(); scoped_feature_->InitAndEnableFeature( @@ -438,17 +416,6 @@ TEST_P(TrialComparisonCertVerifierControllerTest, OfficialBuildTrialEnabledTwoClients) { -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { - // If ChromeRootStoreUsed feature is enabled by default, - // TrialComparisonCertVerifier will not be allowed. It is not safe to - // change the kChromeRootStoreUsed flag in unit_tests since multiple tests - // run in the same process, and GetChromeCertVerifierServiceParams will - // globally enforce a single configuration for the lifetime of the - // process. Therefore just skip this test if CRS is enabled. - GTEST_SKIP(); - } -#endif TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting(true); scoped_feature_ = std::make_unique<base::test::ScopedFeatureList>(); scoped_feature_->InitAndEnableFeature( @@ -561,17 +528,6 @@ TEST_P(TrialComparisonCertVerifierControllerTest, OfficialBuildTrialEnabledUmaOnly) { -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { - // If ChromeRootStoreUsed feature is enabled by default, - // TrialComparisonCertVerifier will not be allowed. It is not safe to - // change the kChromeRootStoreUsed flag in unit_tests since multiple tests - // run in the same process, and GetChromeCertVerifierServiceParams will - // globally enforce a single configuration for the lifetime of the - // process. Therefore just skip this test if CRS is enabled. - GTEST_SKIP(); - } -#endif TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting(true); scoped_feature_ = std::make_unique<base::test::ScopedFeatureList>(); scoped_feature_->InitAndEnableFeatureWithParameters( @@ -609,17 +565,6 @@ TEST_P(TrialComparisonCertVerifierControllerTest, IncognitoOfficialBuildTrialEnabled) { -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { - // If ChromeRootStoreUsed feature is enabled by default, - // TrialComparisonCertVerifier will not be allowed. It is not safe to - // change the kChromeRootStoreUsed flag in unit_tests since multiple tests - // run in the same process, and GetChromeCertVerifierServiceParams will - // globally enforce a single configuration for the lifetime of the - // process. Therefore just skip this test if CRS is enabled. - GTEST_SKIP(); - } -#endif TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting(true); scoped_feature_ = std::make_unique<base::test::ScopedFeatureList>(); scoped_feature_->InitAndEnableFeature(
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index f3aefd41..6404f12 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -255,7 +255,7 @@ return menu; } - // Does not work on ChromeOS. + // Does not work on ChromeOS Ash where there's only one profile. Profile* CreateSecondaryProfile(int profile_num) { base::ScopedAllowBlockingForTesting allow_blocking; ProfileManager* profile_manager = g_browser_process->profile_manager(); @@ -1664,9 +1664,15 @@ profiles_signin_required.end(), i)) { entry->LockForceSigninProfile(true); } else { + // In order for the profile to be counted as active, it needs to have a + // created browser window. The profile isn't marked active until the + // browser is actually open, which we need. + ui_test_utils::BrowserChangeObserver observer( + nullptr, ui_test_utils::BrowserChangeObserver::ChangeType::kAdded); profiles::FindOrCreateNewWindowForProfile( profile, chrome::startup::IsProcessStartup::kNo, chrome::startup::IsFirstRun::kNo, false); + observer.Wait(); profiles_in_menu.push_back(profile); } }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js index 55fcef2..4cdc0779 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
@@ -77,6 +77,13 @@ * @private {?AutomationNode} */ this.imageNode_; + + /** + * To support Command.SHOW_OPTIONS_PAGE, the state of the ChromeVox Page + * Migration Flag. (If enabled, should open in Chrome OS Settings App) + * @private {boolean|undefined} + */ + this.isChromeVoxSettingsMigrationEnabled_; } /** @override */ @@ -94,7 +101,7 @@ this.speakTimeAndDate_(); return false; case Command.SHOW_OPTIONS_PAGE: - chrome.runtime.openOptionsPage(); + this.showOptionsPage_(); break; case Command.TOGGLE_STICKY_MODE: SmartStickyMode.instance.toggle(); @@ -1605,6 +1612,30 @@ } /** + * Launch ChromeVox options page. If migration enabled, launch settings app. + * TODO(268196299): Add test for showing options page. + * @private + */ + async showOptionsPage_() { + if (this.isChromeVoxSettingsMigrationEnabled_ === undefined) { + this.isChromeVoxSettingsMigrationEnabled_ = await new Promise(resolve => { + chrome.accessibilityPrivate.isFeatureEnabled( + chrome.accessibilityPrivate.AccessibilityFeature + .CHROMEVOX_SETTINGS_MIGRATION, + resolve); + }); + } + + if (!this.isChromeVoxSettingsMigrationEnabled_) { + chrome.runtime.openOptionsPage(); + return; + } + + // Launch new ChromeVox settings (inside ChromeOS Settings App). + chrome.accessibilityPrivate.openSettingsSubpage('textToSpeech/chromeVox'); + } + + /** * @param {boolean} isPrevious * @private */
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js index b8cb2f1..e01a640 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js
@@ -847,7 +847,7 @@ * @private */ onOptions_() { - chrome.runtime.openOptionsPage(); + BackgroundBridge.CommandHandler.onCommand(Command.SHOW_OPTIONS_PAGE); this.setMode_(PanelMode.COLLAPSED); }
diff --git a/chrome/browser/resources/chromeos/parent_access/parent_access_disabled.js b/chrome/browser/resources/chromeos/parent_access/parent_access_disabled.js index 44e21e7..a9ffaa8 100644 --- a/chrome/browser/resources/chromeos/parent_access/parent_access_disabled.js +++ b/chrome/browser/resources/chromeos/parent_access/parent_access_disabled.js
@@ -8,8 +8,8 @@ import {ExtensionApprovalsDisabled} from './flows/extension_approvals_disabled.js'; import {ParentAccessScreenInterface} from './parent_access_screen.js'; -import {ParentAccessParams_FlowType} from './parent_access_ui.mojom-webui.js'; -import {getParentAccessParams} from './parent_access_ui_handler.js'; +import {ParentAccessParams_FlowType, ParentAccessResult} from './parent_access_ui.mojom-webui.js'; +import {getParentAccessParams, getParentAccessUIHandler} from './parent_access_ui_handler.js'; /** @implements {ParentAccessScreenInterface} */ class ParentAccessDisabled extends PolymerElement { @@ -42,8 +42,7 @@ /** @private */ onDisabledScreenClosed_() { - // TODO(b/266830608): Implement a Mojo interface for handling the disabled - // state. + getParentAccessUIHandler().onParentAccessDone(ParentAccessResult.kDisabled); } }
diff --git a/chrome/browser/resources/settings/chromeos/OWNERS b/chrome/browser/resources/settings/chromeos/OWNERS index 08aadc4..3c9be034 100644 --- a/chrome/browser/resources/settings/chromeos/OWNERS +++ b/chrome/browser/resources/settings/chromeos/OWNERS
@@ -23,5 +23,6 @@ per-file lazy_load.ts,os_settings.gni,os_settings.ts=file://chrome/browser/resources/settings/chromeos/os_apps_page/OWNERS per-file lazy_load.ts,os_settings.gni,os_settings.ts=file://chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/OWNERS per-file lazy_load.ts,os_settings.gni,os_settings.ts=file://chrome/browser/resources/settings/chromeos/os_bluetooth_page/OWNERS +per-file lazy_load.ts,os_settings.gni,os_settings.ts=file://chrome/browser/resources/settings/chromeos/os_files_page/OWNERS per-file lazy_load.ts,os_settings.gni,os_settings.ts=file://chrome/browser/resources/settings/chromeos/os_languages_page/OWNERS per-file lazy_load.ts,os_settings.gni,os_settings.ts=file://chrome/browser/resources/settings/chromeos/os_printing_page/OWNERS
diff --git a/chrome/browser/resources/settings/chromeos/device_page/device_page.html b/chrome/browser/resources/settings/chromeos/device_page/device_page.html index 587bea8..9608b1a 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/device_page.html +++ b/chrome/browser/resources/settings/chromeos/device_page/device_page.html
@@ -1,4 +1,15 @@ -<style include="settings-shared"></style> +<style include="settings-shared"> + .restore-defaults-button { + border-radius: 16px; + height: 32px; + margin-inline: 16px; + } + + .restore-defaults-icon { + --iron-icon-fill-color: currentColor; + margin-inline-end: 8px; + } +</style> <os-settings-animated-pages id="pages" section="device" focus-config="[[focusConfig_]]"> <div id="main" route-path="default"> @@ -162,7 +173,15 @@ route-path="/per-device-keyboard/remap-keys"> <os-settings-subpage id="perDeviceKeyboardRemapKeysRow" page-title="$i18n{remapKeyboardKeysRowLabel}"> - <settings-per-device-keyboard-remap-keys keyboards="[[keyboards]]"> + <cr-button id="restoreDefaultsButton" slot="subpage-title-extra" + on-click="restoreDefaults" + class="restore-defaults-button"> + <iron-icon icon="os-settings:restore" class="restore-defaults-icon"> + </iron-icon> + <span>$i18n{keyboardRemapRestoreDefaultsLabel}</span> + </cr-button> + <settings-per-device-keyboard-remap-keys keyboards="[[keyboards]]" + id="remap-keys"> </settings-per-device-keyboard-remap-keys> </os-settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/chromeos/device_page/device_page.ts b/chrome/browser/resources/settings/chromeos/device_page/device_page.ts index e285963..7d4ca710 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/device_page.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/device_page.ts
@@ -7,7 +7,10 @@ * peripheral settings. */ import 'chrome://resources/cr_components/settings_prefs/prefs.js'; +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js'; +import 'chrome://resources/cr_elements/icons.html.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import './audio.js'; import './display.js'; import './keyboard.js'; @@ -42,6 +45,7 @@ import {FakeInputDeviceSettingsProvider} from './fake_input_device_settings_provider.js'; import {getInputDeviceSettingsProvider} from './input_device_mojo_interface_provider.js'; import {InputDeviceSettingsProviderInterface, Keyboard, Mouse, PointingStick, Touchpad} from './input_device_settings_types.js'; +import {SettingsPerDeviceKeyboardRemapKeysElement} from './per_device_keyboard_remap_keys.js'; interface SettingsDevicePageElement { $: { @@ -503,6 +507,11 @@ return this.hasPointingStick_ && this.isDeviceSettingsSplitEnabled_; } + protected restoreDefaults(): void { + const remapKeysPage = this.shadowRoot!.querySelector('#remap-keys') as + SettingsPerDeviceKeyboardRemapKeysElement; + remapKeysPage.restoreDefaults(); + } /** * Leaves the pointer subpage if all pointing devices are detached. */
diff --git a/chrome/browser/resources/settings/chromeos/device_page/keyboard.html b/chrome/browser/resources/settings/chromeos/device_page/keyboard.html index a5b29ebd..ba52388e 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/keyboard.html +++ b/chrome/browser/resources/settings/chromeos/device_page/keyboard.html
@@ -154,7 +154,9 @@ </div> <cr-link-row id="keyboardShortcutViewer" class="hr" on-click="onShowKeyboardShortcutViewerClick_" - label="$i18n{showKeyboardShortcutViewer}" external + label="$i18n{showKeyboardShortcutViewer}" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kKeyboardShortcuts]]"></cr-link-row> <cr-link-row id="showLanguagesInput" class="hr" on-click="onShowInputSettingsClick_"
diff --git a/chrome/browser/resources/settings/chromeos/device_page/keyboard.ts b/chrome/browser/resources/settings/chromeos/device_page/keyboard.ts index f0904b9..c19664c 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/keyboard.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/keyboard.ts
@@ -20,9 +20,9 @@ import {afterNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {DropdownMenuOptionList} from '../../controls/settings_dropdown_menu.js'; -import {FocusConfig} from '../../focus_config.js'; import {castExists} from '../assert_extras.js'; import {DeepLinkingMixin} from '../deep_linking_mixin.js'; +import {FocusConfig} from '../focus_config.js'; import {Setting} from '../mojom-webui/setting.mojom-webui.js'; import {routes} from '../os_settings_routes.js'; import {RouteObserverMixin} from '../route_observer_mixin.js';
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.html b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.html index 04ac4c5..2105141 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.html +++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard.html
@@ -56,7 +56,9 @@ </iron-collapse> <cr-link-row id="keyboardShortcutViewer" class="hr" on-click="onShowKeyboardShortcutViewerTap" - label="$i18n{showKeyboardShortcutViewer}" external + label="$i18n{showKeyboardShortcutViewer}" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kKeyboardShortcuts]]"> </cr-link-row> <cr-link-row id="showLanguagesInput"
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.html b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.html index c388682d..16be18e 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.html +++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.html
@@ -5,11 +5,6 @@ padding: 12px 0; } - #restoreDefaultsButton { - margin-inline-end: 6px; - margin-inline-start: auto; - } - .subsection { margin-bottom: 0; margin-top: 8px; @@ -22,10 +17,6 @@ </style> <div id="header"> <div id="description">$i18n{remapKeyboardKeysDescription}</div> - <cr-button id="restoreDefaultsButton" - on-click="restoreDefaults"> - $i18n{keyboardRemapRestoreDefaultsLabel} - </cr-button> </div> <div class="subsection"> <keyboard-remap-modifier-key-row
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.ts b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.ts index c755cb00..624c03e 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.ts
@@ -305,10 +305,10 @@ this.set('fakeMetaPref.value', this.defaultRemappings[ModifierKey.kMeta]); } - private restoreDefaults(): void { - // When defaults are restored, set isInitialized to false while the prefs - // are being updated. Then, once prefs are all done being updated back to - // defaults, make sure onSettingsUpdated is called. + restoreDefaults(): void { + // When defaults are restored, set isInitialized to false while the + // prefs are being updated. Then, once prefs are all done being updated + // back to defaults, make sure onSettingsUpdated is called. this.isInitialized = false; this.defaultInitializePrefs(); this.isInitialized = true;
diff --git a/chrome/browser/resources/settings/chromeos/device_page/storage.html b/chrome/browser/resources/settings/chromeos/device_page/storage.html index 84fee95..0be081a7 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/storage.html +++ b/chrome/browser/resources/settings/chromeos/device_page/storage.html
@@ -172,20 +172,28 @@ </div> <cr-link-row id="myFilesSize" class="hr" on-click="onMyFilesClick_" label="$i18n{storageItemMyFiles}" - sub-label="$i18n{storageSizeComputing}" external> + sub-label="$i18n{storageSizeComputing}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> <cr-link-row id="browsingDataSize" class="hr" on-click="onBrowsingDataClick_" label="$i18n{storageItemBrowsingData}" - sub-label="$i18n{storageSizeComputing}" external> + sub-label="$i18n{storageSizeComputing}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> <cr-link-row id="appsSize" class="hr" on-click="onAppsClick_" label="$i18n{storageItemApps}" - sub-label="$i18n{storageSizeComputing}" external> + sub-label="$i18n{storageSizeComputing}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> <template is="dom-if" if="[[showDriveOfflineStorage_]]"> <cr-link-row id="driveOfflineSize" class="hr" on-click="onDriveOfflineClick_" label="$i18n{storageItemOffline}" - sub-label="$i18n{storageSizeComputing}" external> + sub-label="$i18n{storageSizeComputing}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </template> <template is="dom-if" if="[[showCrostiniStorage_]]">
diff --git a/chrome/browser/resources/settings/chromeos/device_page/stylus.html b/chrome/browser/resources/settings/chromeos/device_page/stylus.html index 8bf5de40..58a5991 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/stylus.html +++ b/chrome/browser/resources/settings/chromeos/device_page/stylus.html
@@ -72,7 +72,10 @@ <cr-link-row id="findMoreAppsLink" class="hr" on-click="onFindAppsClick_" hidden$="[[!prefs.arc.enabled.value]]" label="$i18n{stylusFindMoreAppsPrimary}" - sub-label="$i18n{stylusFindMoreAppsSecondary}" external></cr-link-row> + sub-label="$i18n{stylusFindMoreAppsSecondary}" + external + button-aria-description="$i18n{opensInNewTab}"> +</cr-link-row> <template is="dom-if" if="[[supportsLockScreen_(selectedApp_)]]"> <div id="note-taking-app-lock-screen-settings">
diff --git a/chrome/browser/resources/settings/chromeos/focus_config.ts b/chrome/browser/resources/settings/chromeos/focus_config.ts new file mode 100644 index 0000000..74b08fd --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/focus_config.ts
@@ -0,0 +1,5 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +export type FocusConfig = Map<string, (string|Element|(() => void))>;
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.ts b/chrome/browser/resources/settings/chromeos/lazy_load.ts index 321b99d..eff04013 100644 --- a/chrome/browser/resources/settings/chromeos/lazy_load.ts +++ b/chrome/browser/resources/settings/chromeos/lazy_load.ts
@@ -63,6 +63,8 @@ import './os_a11y_page/keyboard_and_text_input_page.js'; import './os_a11y_page/cursor_and_touchpad_page.js'; import './os_a11y_page/chromevox_subpage.js'; +import './os_a11y_page/bluetooth_braille_display_manager.js'; +import './os_a11y_page/bluetooth_braille_display_ui.js'; import './os_a11y_page/select_to_speak_subpage.js'; import './os_a11y_page/switch_access_action_assignment_dialog.js'; import './os_a11y_page/switch_access_action_assignment_pane.js'; @@ -111,7 +113,10 @@ export {KeyboardShortcutBanner} from './keyboard_shortcut_banner/keyboard_shortcut_banner.js'; export {SettingsMultideviceCombinedSetupItemElement} from './multidevice_page/multidevice_combined_setup_item.js'; export {SettingsAudioAndCaptionsPageElement} from './os_a11y_page/audio_and_captions_page.js'; +export {BluetoothBrailleDisplayListener, BluetoothBrailleDisplayManager} from './os_a11y_page/bluetooth_braille_display_manager.js'; +export {BluetoothBrailleDisplayUiElement} from './os_a11y_page/bluetooth_braille_display_ui.js'; export {SettingsCursorAndTouchpadPageElement} from './os_a11y_page/cursor_and_touchpad_page.js'; +export {SettingsDisplayAndMagnificationElement} from './os_a11y_page/display_and_magnification_page.js'; export {SettingsKeyboardAndTextInputPageElement} from './os_a11y_page/keyboard_and_text_input_page.js'; export {SettingsManageA11yPageElement} from './os_a11y_page/manage_a11y_page.js'; export {SettingsTextToSpeechPageElement} from './os_a11y_page/text_to_speech_page.js';
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.html b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.html index e7a17ce..0976fc6a 100644 --- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.html +++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.html
@@ -160,10 +160,12 @@ id="visibilityDialog" on-close="onVisibilityDialogClose_"> </nearby-share-contact-visibility-dialog> </template> - <cr-link-row id="manageContactsLinkRow" class="hr" external + <cr-link-row id="manageContactsLinkRow" class="hr" on-click="onManageContactsClick_" label="$i18n{nearbyShareManageContactsRowTitle}" sub-label="[[getManageContactsSubLabel_(manageContactsUrl_)]]" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kNearbyShareContacts]]"> </cr-link-row> <div class="settings-box two-line" id="dataUsageRow">
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/bluetooth_braille_display_manager.ts b/chrome/browser/resources/settings/chromeos/os_a11y_page/bluetooth_braille_display_manager.ts new file mode 100644 index 0000000..0730b93 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/bluetooth_braille_display_manager.ts
@@ -0,0 +1,278 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Abstracts away the details of `chrome.bluetooth`, + * `chrome.bluetoothPrivate`, and `ChromeVoxSubpageBrowserProxy` for a UI + * component to interact with a bluetooth braille display. + */ + +import {ChromeVoxSubpageBrowserProxy, ChromeVoxSubpageBrowserProxyImpl, DeviceEventListener, PairingEventListener} from './chromevox_subpage_browser_proxy.js'; + +export interface BluetoothBrailleDisplayListener { + onDisplayListChanged(displays: chrome.bluetooth.Device[]): void; + + /** + * Called when a pincode is requested and a response can be made by calling + * `BluetoothBrailleDisplayManager.finishPairing`. + */ + onPincodeRequested(display: chrome.bluetooth.Device): void; +} + +/** + * Manages interaction with the bluetooth and braille subsystems in ChromeOS. + * A caller can use this class by doing: + * let manager = new BluetoothBrailleDisplayManager(); + * manager.addListener(listenerObject); // listenerObject receives updates + * // on important events in bluetooth. + * manager.start(); // Starts bluetooth discovery. + * manager.connect(); // Connects to a discovered device received in the + * // listenerObject. + * manager.finishPairing(); // If a pairing request is sent to the + * // listenerObject, this is how a caller can + * // respond. + * manager.stop(); // Stops discovery, but persists connections. + * + * TODO(b/270617362): Add tests for BluetoothBrailleDisplayManager. + */ +export class BluetoothBrailleDisplayManager { + /** + * This list of braille display names was taken from other services that + * utilize Brltty (e.g. BrailleBack). + */ + private displayNamePrefixes_: string[] = [ + 'Actilino ALO', + 'Activator AC4', + 'Active Braille AB', + 'Active Star AS', + 'ALVA BC', + 'APH Chameleon', + 'APH Mantis', + 'Basic Braille BB', + 'Basic Braille Plus BP', + 'BAUM Conny', + 'Baum PocketVario', + 'Baum SuperVario', + 'Baum SVario', + 'BrailleConnect', + 'BrailleEDGE', + 'BrailleMe', + 'BMpk', + 'BMsmart', + 'BM32', + 'BrailleNote Touch', + 'BrailleSense', + 'Braille Star', + 'Braillex', + 'Brailliant BI', + 'Brailliant 14', + 'Brailliant 80', + 'Braillino BL', + 'B2G', + 'Conny', + 'Easy Braille EBR', + 'EL12-', + 'Esys-', + 'Focus', + 'Humanware BrailleOne', + 'HWG Brailliant', + 'MB248', + 'NLS eReader', + 'Orbit Reader', + 'Pronto!', + 'Refreshabraille', + 'SmartBeetle', + 'SuperVario', + 'TSM', + 'VarioConnect', + 'VarioUltra', + ]; + private listeners_: BluetoothBrailleDisplayListener[] = []; + + private chromeVoxSubpageBrowserProxy_: ChromeVoxSubpageBrowserProxy; + + private onDeviceAddedListener_: DeviceEventListener; + private onDeviceChangedListener_: DeviceEventListener; + private onDeviceRemovedListener_: DeviceEventListener; + private onPairingListener_: PairingEventListener; + + /** + * The display explicitly preferred by a caller via `this.connect()`. Only one + * such display exists at a time. + */ + private preferredDisplayAddress_?: string; + + /** + * Tracks whether the preferred display is connected. + * https://crsrc.org/c/device/bluetooth/bluetooth_device.h?q=IsConnected + + * Note: This will always be defined - since `chrome.bluetooth` has one type + * `chrome.bluetooth.Device` for all bluetooth events and handlers + * `device.connected` is optional for callers, but present for handlers. + * https://chromiumcodereview.appspot.com/14866002 + */ + private preferredDisplayConnected_?: boolean; + + constructor() { + this.chromeVoxSubpageBrowserProxy_ = + ChromeVoxSubpageBrowserProxyImpl.getInstance(); + + this.onDeviceAddedListener_ = device => this.handleDevicesChanged(device); + this.onDeviceChangedListener_ = device => this.handleDevicesChanged(device); + this.onDeviceRemovedListener_ = device => this.handleDevicesChanged(device); + this.onPairingListener_ = pairingEvent => this.handlePairing(pairingEvent); + + chrome.settingsPrivate + .getPref('settings.a11y.chromevox.preferred_braille_display_address') + .then((pref: chrome.settingsPrivate.PrefObject<string>) => { + this.preferredDisplayAddress_ = pref.value; + }); + } + + addListener(listener: BluetoothBrailleDisplayListener) { + this.listeners_.push(listener); + } + + /** + * Starts listening for changes and discovering bluetooth devices. + */ + start() { + this.chromeVoxSubpageBrowserProxy_.addDeviceAddedListener( + this.onDeviceAddedListener_); + this.chromeVoxSubpageBrowserProxy_.addDeviceChangedListener( + this.onDeviceChangedListener_); + this.chromeVoxSubpageBrowserProxy_.addDeviceRemovedListener( + this.onDeviceRemovedListener_); + this.chromeVoxSubpageBrowserProxy_.addPairingListener( + this.onPairingListener_); + + this.chromeVoxSubpageBrowserProxy_.startDiscovery(); + + // Pick up any devices already in the system including previously paired, + // but out of range displays. + this.handleDevicesChanged(); + } + + /** + * Stops discovering bluetooth devices and listening for changes. + */ + stop() { + this.chromeVoxSubpageBrowserProxy_.stopDiscovery(); + + this.chromeVoxSubpageBrowserProxy_.removeDeviceAddedListener( + this.onDeviceAddedListener_); + this.chromeVoxSubpageBrowserProxy_.removeDeviceChangedListener( + this.onDeviceChangedListener_); + this.chromeVoxSubpageBrowserProxy_.removeDeviceRemovedListener( + this.onDeviceRemovedListener_); + this.chromeVoxSubpageBrowserProxy_.removePairingListener( + this.onPairingListener_); + } + + /** + * Connects to the given bluetooth braille display. + */ + async connect(display: chrome.bluetooth.Device) { + if (this.preferredDisplayAddress_ === display.address || + !this.preferredDisplayAddress_) { + this.connectInternal(display); + } else { + // Disconnect any previously connected bluetooth braille display. + await chrome.bluetoothPrivate.disconnectAll( + this.preferredDisplayAddress_); + this.connectInternal(display); + } + } + + protected async connectInternal(display: chrome.bluetooth.Device) { + this.preferredDisplayAddress_ = display.address; + chrome.settingsPrivate.setPref( + 'settings.a11y.chromevox.preferred_braille_display_address', + display.address); + + if (!display.connected) { + await chrome.bluetoothPrivate.connect(display.address); + } + + if (!display.paired) { + chrome.bluetoothPrivate.pair(display.address); + } + } + + /** + * Disconnects the given display and clears it from Brltty. + */ + disconnect(display: chrome.bluetooth.Device) { + chrome.bluetoothPrivate.disconnectAll(display.address); + this.chromeVoxSubpageBrowserProxy_.updateBluetoothBrailleDisplayAddress(''); + } + + /** + * Forgets the given display. + */ + forget(display: chrome.bluetooth.Device) { + chrome.bluetoothPrivate.forgetDevice(display.address); + this.chromeVoxSubpageBrowserProxy_.updateBluetoothBrailleDisplayAddress(''); + } + + /** + * Finishes pairing in response to + * `BluetoothBrailleDisplayListener.onPincodeRequested`. + */ + finishPairing(display: chrome.bluetooth.Device, pincode: string) { + chrome.bluetoothPrivate.setPairingResponse({ + response: chrome.bluetoothPrivate.PairingResponse.CONFIRM, + device: display, + pincode, + }); + } + + protected async handleDevicesChanged(device?: chrome.bluetooth.Device) { + const devices = await chrome.bluetooth.getDevices(); + const displayList = devices.filter(device => { + return this.displayNamePrefixes_.some(name => { + return device.name && device.name.startsWith(name); + }); + }); + if (displayList.length === 0) { + return; + } + if (device && !displayList.find(i => i.name === device.name)) { + return; + } + + displayList.forEach(display => { + if (this.preferredDisplayAddress_ === display.address) { + this.handlePreferredDisplayConnectionStateChanged(display); + } + }); + this.listeners_.forEach( + listener => listener.onDisplayListChanged(displayList)); + } + + protected handlePairing(pairingEvent: chrome.bluetoothPrivate.PairingEvent) { + if (pairingEvent.pairing === + chrome.bluetoothPrivate.PairingEventType.REQUEST_PINCODE) { + this.listeners_.forEach( + listener => listener.onPincodeRequested(pairingEvent.device)); + } + } + + protected handlePreferredDisplayConnectionStateChanged( + display: chrome.bluetooth.Device) { + if (display.connected === this.preferredDisplayConnected_) { + return; + } + + this.preferredDisplayConnected_ = display.connected; + + // We do not clear the address seen by Brltty unless the caller explicitly + // disconnects or forgets the display via the public methods of this + // class. + if (display.connected) { + this.chromeVoxSubpageBrowserProxy_.updateBluetoothBrailleDisplayAddress( + display.address); + } + } +}
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/bluetooth_braille_display_ui.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/bluetooth_braille_display_ui.html new file mode 100644 index 0000000..5e524c7 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/bluetooth_braille_display_ui.html
@@ -0,0 +1,57 @@ +<style include="settings-shared"> + settings-dropdown-menu { + --md-select-width: 100%; + } + + .container { + align-items: center; + display: flex; + flex: 1; + justify-content: space-between; + margin-inline-end: var(--cr-section-padding); + min-height: var(--cr-section-min-height); + } + + .controls { + align-items: center; + display: flex; + flex: 1; + } + + .menu { + flex: 1; + } + + .menu, + .button { + margin-inline-start: 16px; + } + +</style> + +<div class="container"> + <span class="label">$i18n{chromeVoxBluetoothBrailleDisplaySelectLabel}</span> + <template is="dom-if" if="[[inPinMode_]]"> + <div class="container"> + $i18n{chromeVoxBluetoothBrailleDisplayPincodeLabel} + <cr-input type="text" on-change="onPincodeChanged_"></cr-input> + </div> + </template> + <template is="dom-if" if="[[!inPinMode_]]"> + <div id="controls" class="controls"> + <settings-dropdown-menu + id="displaySelect" + class="menu" + label="$i18n{chromeVoxBluetoothBrailleDisplaySelectLabel}" + pref="{{brailleDisplayAddressPref_}}" + menu-options="[[brailleDisplayMenuOptions_]]"> + </settings-dropdown-menu> + <cr-button id="connectOrDisconnect" class="button"> + $i18n{chromeVoxBluetoothBrailleDisplayConnect} + </cr-button> + <cr-button id="forget" class="button"> + $i18n{chromeVoxBluetoothBrailleDisplayForget} + </cr-button> + </div> + </template> +</div>
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/bluetooth_braille_display_ui.ts b/chrome/browser/resources/settings/chromeos/os_a11y_page/bluetooth_braille_display_ui.ts new file mode 100644 index 0000000..51497df --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/bluetooth_braille_display_ui.ts
@@ -0,0 +1,208 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview A widget that exposes UI for interacting with a list of braille + * displays. + */ + +import 'chrome://resources/cr_components/localized_link/localized_link.js'; +import 'chrome://resources/cr_elements/cr_shared_vars.css.js'; +import '../../settings_shared.css.js'; + +import {PrefsMixin} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js'; +import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js'; +import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js'; +import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {DropdownMenuOptionList, SettingsDropdownMenuElement} from '../../controls/settings_dropdown_menu.js'; +import {DeepLinkingMixin} from '../deep_linking_mixin.js'; + +import {BluetoothBrailleDisplayListener, BluetoothBrailleDisplayManager} from './bluetooth_braille_display_manager.js'; +import {getTemplate} from './bluetooth_braille_display_ui.html.js'; + +const CONNECTED_METRIC_NAME = + 'Accessibility.ChromeVox.BluetoothBrailleDisplayConnectedButtonClick'; +const PINCODE_TIMEOUT_MS = 60000; + +export interface BluetoothBrailleDisplayUiElement { + $: { + connectOrDisconnect: CrButtonElement, + forget: CrButtonElement, + displaySelect: SettingsDropdownMenuElement, + controls: HTMLDivElement, + }; +} + +/** + * A widget used for interacting with bluetooth braille displays. + * TODO(b/270617362): Add tests for BluetoothBrailleDisplayUi. + */ +const BluetoothBrailleDisplayUiElementBase = + DeepLinkingMixin(PrefsMixin(WebUiListenerMixin(I18nMixin(PolymerElement)))); + +export class BluetoothBrailleDisplayUiElement extends + BluetoothBrailleDisplayUiElementBase implements + BluetoothBrailleDisplayListener { + static get is() { + return 'bluetooth-braille-display-ui' as const; + } + + static get template() { + return getTemplate(); + } + + static get properties() { + return { + /** + * The braille display dropdown state as a fake preference object. + */ + brailleDisplayAddressPref_: { + type: Object, + observer: 'updateControls_', + notify: true, + value(): chrome.settingsPrivate.PrefObject { + return { + key: 'BrailleDisplayAddressPref', + type: chrome.settingsPrivate.PrefType.STRING, + value: '', + }; + }, + }, + + /** + * Dropdown menu choices for bluetooth braille display devices. + */ + brailleDisplayMenuOptions_: { + type: Array, + value: [], + }, + }; + } + + static get observers() { + return [ + 'updateControls_(brailleDisplayMenuOptions_)', + 'updateControls_(brailleDisplayAddressPref_.*)', + ]; + } + + private brailleDisplayAddressPref_: chrome.settingsPrivate.PrefObject<string>; + private brailleDisplayMenuOptions_: DropdownMenuOptionList; + private manager_: BluetoothBrailleDisplayManager; + private pincodeRequestedDisplay_?: chrome.bluetooth.Device; + private inPinMode_: boolean = false; + private pincodeTimeoutId_?: number; + private selectedDisplay_?: chrome.bluetooth.Device; + private selectedAndConnectedDisplayAddress_?: string; + + constructor() { + super(); + + this.manager_ = new BluetoothBrailleDisplayManager(); + this.manager_.addListener(this); + } + + override ready() { + super.ready(); + this.manager_.start(); + } + + override disconnectedCallback() { + super.disconnectedCallback(); + this.manager_.stop(); + } + + onDisplayListChanged(displays: chrome.bluetooth.Device[]) { + this.brailleDisplayMenuOptions_ = displays.map(display => ({ + value: display.address, + name: display.name!, + })); + this.updateControls_(); + } + + private onPincodeChanged_(event: Event) { + if (this.pincodeTimeoutId_) { + clearTimeout(this.pincodeTimeoutId_); + } + + const pincodeInput = event.target as CrInputElement; + if (pincodeInput.value) { + this.manager_.finishPairing( + this.pincodeRequestedDisplay_!, pincodeInput.value); + } + this.inPinMode_ = false; + } + + onPincodeRequested(display: chrome.bluetooth.Device) { + this.inPinMode_ = true; + this.pincodeRequestedDisplay_ = display; + + // Also, schedule a timeout for pincode entry. + this.pincodeTimeoutId_ = setTimeout(() => { + this.inPinMode_ = false; + }, PINCODE_TIMEOUT_MS); + } + + private async updateControls_() { + // Only update controls if there is a selected display. + const selectedDisplayAddress = this.brailleDisplayAddressPref_.value; + if (!selectedDisplayAddress) { + this.selectedAndConnectedDisplayAddress_ = undefined; + return; + } + + const display = await chrome.bluetooth.getDevice(selectedDisplayAddress); + this.selectedDisplay_ = display; + + // Record metrics if the display is connected for the first time either + // via a click of the Connect button or re-connection by selection via the + // select. + if (display.connected) { + if (this.selectedAndConnectedDisplayAddress_ !== selectedDisplayAddress) { + this.selectedAndConnectedDisplayAddress_ = selectedDisplayAddress; + chrome.metricsPrivate.recordUserAction(CONNECTED_METRIC_NAME); + } + } else { + // The display is no longer connected. + if (this.selectedAndConnectedDisplayAddress_ === selectedDisplayAddress) { + this.selectedAndConnectedDisplayAddress_ = undefined; + } + } + + const connectOrDisconnect = this.$.connectOrDisconnect; + const displaySelect = this.$.displaySelect; + + connectOrDisconnect.disabled = display.connecting!; + displaySelect.disabled = display.connecting!; + connectOrDisconnect.textContent = loadTimeData.getString( + display.connecting ? + 'chromeVoxBluetoothBrailleDisplayConnecting' : + (display.connected ? 'chromeVoxBluetoothBrailleDisplayDisconnect' : + 'chromeVoxBluetoothBrailleDisplayConnect')); + connectOrDisconnect.onclick = () => { + if (display.connected) { + this.manager_.disconnect(display); + } else { + this.manager_.connect(display); + } + }; + + const forget = this.$.forget; + forget.disabled = (!display.paired || display.connecting)!; + forget.onclick = () => this.manager_.forget(display); + } +} + +declare global { + interface HTMLElementTagNameMap { + [BluetoothBrailleDisplayUiElement.is]: BluetoothBrailleDisplayUiElement; + } +} + +customElements.define( + BluetoothBrailleDisplayUiElement.is, BluetoothBrailleDisplayUiElement);
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage.html index e68c8141..80cc85b2 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage.html
@@ -4,7 +4,7 @@ found in the LICENSE file. --> -<style include="settings-shared"> +<style include="settings-shared md-select"> :host { --cr-section-indent-width: 60px; } @@ -165,11 +165,23 @@ <cr-link-row class="settings-box" label="$i18n{chromeVoxTtsSettingsLink}" sub-label="$i18n{chromeVoxTtsSettingsDescription}" - on-click="onTtsSettingsClick_" external embedded> + on-click="onTtsSettingsClick_" + external + button-aria-description="$i18n{opensInNewTab}" + embedded> </cr-link-row> </div> <h2>$i18n{chromeVoxBrailleLabel}</h2> <div class="sub-item"> + <div class="settings-box continuation"> + <div class="start settings-box-text"> + $i18n{chromeVoxBrailleTableDescription} + </div> + <settings-dropdown-menu id="brailleTableTypeDropdown" + pref="{{prefs.settings.a11y.chromevox.braille_table_type}}" + menu-options="[[brailleTableTypeOptions_]]"> + </settings-dropdown-menu> + </div> <settings-toggle-button id="brailleWordWrapToggle" class="settings-box continuation" @@ -182,6 +194,7 @@ pref="{{prefs.settings.a11y.chromevox.menu_braille_commands}}" label="$i18n{chromeVoxMenuBrailleCommands}"> </settings-toggle-button> + <bluetooth-braille-display-ui></bluetooth-braille-display-ui> <div class="text-row"> <div>$i18n{chromeVoxVirtualBrailleDisplay}</div> <div class="secondary">$i18n{chromeVoxVirtualBrailleDisplayDetails}</div> @@ -244,7 +257,10 @@ <cr-link-row class="settings-box" label="$i18n{chromeVoxEventLogLink}" sub-label="$i18n{chromeVoxEventLogDescription}" - on-click="onEventLogClick_" external embedded> + on-click="onEventLogClick_" + external + button-aria-description="$i18n{opensInNewTab}" + embedded> </cr-link-row> <template is="dom-if" if="[[prefs.settings.a11y.chromevox.enable_event_stream_logging.value]]"> <div class="indented">
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage.ts b/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage.ts index b434cc8e..73b0f10 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage.ts +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage.ts
@@ -23,8 +23,8 @@ import {SettingsToggleButtonElement} from '../../controls/settings_toggle_button.js'; import {DeepLinkingMixin} from '../deep_linking_mixin.js'; import {routes} from '../os_settings_routes.js'; -import {Route, Router} from '../router.js'; import {RouteOriginMixin} from '../route_origin_mixin.js'; +import {Route, Router} from '../router.js'; import {getTemplate} from './chromevox_subpage.html.js'; import {ChromeVoxSubpageBrowserProxy, ChromeVoxSubpageBrowserProxyImpl} from './chromevox_subpage_browser_proxy.js'; @@ -170,6 +170,26 @@ }, /** + * Dropdown menu choices for braille table type options. + */ + brailleTableTypeOptions_: { + readOnly: true, + type: Array, + value() { + return [ + { + value: 'brailleTable6', + name: loadTimeData.getString('chromeVoxBrailleTable6Dot'), + }, + { + value: 'brailleTable8', + name: loadTimeData.getString('chromeVoxBrailleTable8Dot'), + }, + ]; + }, + }, + + /** * Dropdown menu choices for virtual braille display style options. */ virtualBrailleDisplayStyleOptions_: { @@ -282,6 +302,7 @@ private numberReadingStyleOptions_: DropdownMenuOptionList; private punctuationEchoOptions_: DropdownMenuOptionList; private audioStrategyOptions_: DropdownMenuOptionList; + private brailleTableTypeOptions_: DropdownMenuOptionList; private voiceOptions_: DropdownMenuOptionList; private virtualBrailleDisplayStyleOptions_: DropdownMenuOptionList; private chromeVoxBrowserProxy_: ChromeVoxSubpageBrowserProxy;
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage_browser_proxy.ts b/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage_browser_proxy.ts index d70f3a26..4ed6e0e5 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage_browser_proxy.ts +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/chromevox_subpage_browser_proxy.ts
@@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +export type DeviceEventListener = (device?: chrome.bluetooth.Device) => void; +export type PairingEventListener = + (pairingEvent: chrome.bluetoothPrivate.PairingEvent) => void; + export interface ChromeVoxSubpageBrowserProxy { /** * Requests the updated voice data. Returned by the 'all-voice-data-updated' @@ -14,6 +18,25 @@ * through VoicesChanged. */ refreshTtsVoices(): void; + + /** + * Bluetooth API handlers for Bluetooth Braille Display Settings. + */ + addDeviceAddedListener(listener: DeviceEventListener): void; + removeDeviceAddedListener(listener: DeviceEventListener): void; + addDeviceChangedListener(listener: DeviceEventListener): void; + removeDeviceChangedListener(listener: DeviceEventListener): void; + addDeviceRemovedListener(listener: DeviceEventListener): void; + removeDeviceRemovedListener(listener: DeviceEventListener): void; + addPairingListener(listener: PairingEventListener): void; + removePairingListener(listener: PairingEventListener): void; + startDiscovery(): void; + stopDiscovery(): void; + + /** + * Changes the currently selected bluetooth braille display. + */ + updateBluetoothBrailleDisplayAddress(displayAddress: string): void; } let instance: ChromeVoxSubpageBrowserProxy|null = null; @@ -35,4 +58,48 @@ refreshTtsVoices(): void { chrome.send('refreshTtsVoices'); } + + addDeviceAddedListener(listener: DeviceEventListener): void { + chrome.bluetooth.onDeviceAdded.addListener(listener); + } + + removeDeviceAddedListener(listener: DeviceEventListener): void { + chrome.bluetooth.onDeviceAdded.removeListener(listener); + } + + addDeviceChangedListener(listener: DeviceEventListener): void { + chrome.bluetooth.onDeviceChanged.addListener(listener); + } + + removeDeviceChangedListener(listener: DeviceEventListener): void { + chrome.bluetooth.onDeviceChanged.removeListener(listener); + } + + addDeviceRemovedListener(listener: DeviceEventListener): void { + chrome.bluetooth.onDeviceRemoved.addListener(listener); + } + + removeDeviceRemovedListener(listener: DeviceEventListener): void { + chrome.bluetooth.onDeviceRemoved.removeListener(listener); + } + + addPairingListener(listener: PairingEventListener): void { + chrome.bluetoothPrivate.onPairing.addListener(listener); + } + + removePairingListener(listener: PairingEventListener): void { + chrome.bluetoothPrivate.onPairing.removeListener(listener); + } + + startDiscovery(): void { + chrome.bluetooth.startDiscovery(); + } + + stopDiscovery(): void { + chrome.bluetooth.startDiscovery(); + } + + updateBluetoothBrailleDisplayAddress(displayAddress: string): void { + chrome.send('updateBluetoothBrailleDisplayAddress', [displayAddress]); + } }
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.html index 1b9c9fa..1fa080c 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.html
@@ -206,7 +206,9 @@ </cr-link-row> <cr-link-row id="appearanceSubpageButton" class="hr" label="$i18n{appearanceSettingsTitle}" on-click="onAppearanceClick_" - sub-label="$i18n{appearanceSettingsDescription}" external + sub-label="$i18n{appearanceSettingsDescription}" + external + button-aria-description="$i18n{opensInNewTab}" embedded> </cr-link-row> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.ts b/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.ts index fb8b6e45..cd45349 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.ts +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.ts
@@ -33,7 +33,7 @@ const SettingsDisplayAndMagnificationElementBase = DeepLinkingMixin( RouteOriginMixin(WebUiListenerMixin(I18nMixin(PolymerElement)))); -class SettingsDisplayAndMagnificationElement extends +export class SettingsDisplayAndMagnificationElement extends SettingsDisplayAndMagnificationElementBase { static get is() { return 'settings-display-and-magnification-page';
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html index 67eb825..c333b9c 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html
@@ -65,14 +65,18 @@ if="[[!isAccessibilityChromeVoxPageMigrationEnabled_]]"> <cr-link-row id="chromeVoxSubpageButton" class="settings-box" on-click="onChromeVoxSettingsClick_" - label="$i18n{chromeVoxOptionsLabel}" external> + label="$i18n{chromeVoxOptionsLabel}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </template> </div> <div class="sub-item"> <cr-link-row id="chromeVoxTutorialButton" class="settings-box" on-click="onChromeVoxTutorialClick_" - label="$i18n{chromeVoxTutorialLabel}" external> + label="$i18n{chromeVoxTutorialLabel}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </div> </iron-collapse> @@ -98,7 +102,9 @@ if="[[!isAccessibilitySelectToSpeakPageMigrationEnabled_]]"> <cr-link-row id="selectToSpeakSubpageButton" class="settings-box" on-click="onSelectToSpeakSettingsClick_" - label="$i18n{selectToSpeakOptionsLabel}" external> + label="$i18n{selectToSpeakOptionsLabel}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </template> </div> @@ -201,8 +207,11 @@ </cr-link-row> <cr-link-row id="appearanceSubpageButton" class="hr" label="$i18n{appearanceSettingsTitle}" on-click="onAppearanceClick_" - sub-label="$i18n{appearanceSettingsDescription}" external - embedded></cr-link-row> + sub-label="$i18n{appearanceSettingsDescription}" + external + button-aria-description="$i18n{opensInNewTab}" + embedded> + </cr-link-row> </template> <h2>$i18n{keyboardAndTextInputHeading}</h2> @@ -431,6 +440,8 @@ <cr-link-row id="additionalFeaturesLink" class="hr" label="$i18n{additionalFeaturesTitle}" - on-click="onAdditionalFeaturesClick_" external> + on-click="onAdditionalFeaturesClick_" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/os_a11y_page.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/os_a11y_page.html index fb09340d..0850c1a 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/os_a11y_page.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/os_a11y_page.html
@@ -59,7 +59,9 @@ <cr-link-row id="additionalFeaturesLink" class="hr" label="$i18n{additionalFeaturesTitle}" - on-click="onAdditionalFeaturesClick_" external> + on-click="onAdditionalFeaturesClick_" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </template> </div>
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.html index f82c7096..dc9ce26 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/text_to_speech_page.html
@@ -38,14 +38,18 @@ if="[[!isAccessibilityChromeVoxPageMigrationEnabled_]]"> <cr-link-row id="chromeVoxSubpageButton" class="settings-box" on-click="onChromeVoxSettingsClick_" - label="$i18n{chromeVoxOptionsLabel}" external> + label="$i18n{chromeVoxOptionsLabel}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </template> </div> <div class="sub-item"> <cr-link-row id="chromeVoxTutorialButton" class="settings-box" on-click="onChromeVoxTutorialClick_" - label="$i18n{chromeVoxTutorialLabel}" external> + label="$i18n{chromeVoxTutorialLabel}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </div> </iron-collapse> @@ -72,7 +76,9 @@ if="[[!isAccessibilitySelectToSpeakPageMigrationEnabled_]]"> <cr-link-row id="selectToSpeakSubpageButton" class="settings-box" on-click="onSelectToSpeakSettingsClick_" - label="$i18n{selectToSpeakOptionsLabel}" external> + label="$i18n{selectToSpeakOptionsLabel}" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </template> </div>
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html index 6e6b969..4d8476e 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html +++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
@@ -175,7 +175,9 @@ <template is="dom-if" if="[[hasInternetConnection_]]"> <cr-link-row class="hr" id="releaseNotesOnline" on-click="onReleaseNotesClick_" - label="$i18n{aboutShowReleaseNotes}" external + label="$i18n{aboutShowReleaseNotes}" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kSeeWhatsNew]]"> </cr-link-row> </template> @@ -183,30 +185,41 @@ <cr-link-row class="hr" id="releaseNotesOffline" on-click="onReleaseNotesClick_" label="$i18n{aboutShowReleaseNotes}" - title="$i18n{aboutReleaseNotesOffline}" external + title="$i18n{aboutReleaseNotesOffline}" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kSeeWhatsNew]]"> </cr-link-row> </template> <cr-link-row class="hr" id="help" on-click="onHelpClick_" - label="$i18n{aboutGetHelpUsingChromeOs}" external + label="$i18n{aboutGetHelpUsingChromeOs}" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kGetHelpWithChromeOs]]"> </cr-link-row> <if expr="_google_chrome"> <cr-link-row class="hr" id="reportIssue" on-click="onReportIssueClick_" hidden="[[!prefs.feedback_allowed.value]]" - label="[[getReportIssueLabel_()]]" external + label="[[getReportIssueLabel_()]]" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kReportAnIssue]]"> </cr-link-row> </if> <cr-link-row class="hr" id="diagnostics" on-click="onDiagnosticsClick_" - label="$i18n{aboutDiagnostics}" external + label="$i18n{aboutDiagnostics}" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kDiagnostics]]"> </cr-link-row> <cr-link-row class="hr" id="firmwareUpdates" on-click="onFirmwareUpdatesClick_" - label="$i18n{aboutFirmwareUpdates}" external using-slotted-label + label="$i18n{aboutFirmwareUpdates}" + external + button-aria-description="$i18n{opensInNewTab}" + using-slotted-label deep-link-focus-id$="[[Setting.kFirmwareUpdates]]"> <iron-icon id="firmwareUpdateBadge" icon$="[[getFirmwareUpdatesIcon_(firmwareUpdateCount_)]]" @@ -226,7 +239,9 @@ </cr-link-row> <cr-link-row class="hr" on-click="onManagementPageClick_" start-icon="cr:domain" label="$i18n{managementPage}" - hidden$="[[!isManaged_]]" external> + hidden$="[[!isManaged_]]" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </div> <template is="dom-if" route-path="/help/details">
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/android_apps_subpage.html b/chrome/browser/resources/settings/chromeos/os_apps_page/android_apps_subpage.html index 4a1d2b0..253589a7 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/android_apps_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/android_apps_subpage.html
@@ -2,7 +2,9 @@ <template is="dom-if" if="[[androidAppsInfo.settingsAppAvailable]]" restamp> <cr-link-row id="manageApps" label="$i18n{androidAppsManageApps}" - on-click="onManageAndroidAppsClick_" external + on-click="onManageAndroidAppsClick_" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kManageAndroidPreferences]]"> </cr-link-row> </template> @@ -48,4 +50,3 @@ </cr-button> </div> </cr-dialog> -
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html index acdde750..b0d82d18 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html
@@ -60,7 +60,9 @@ </template> <template is="dom-if" if="[[!havePlayStoreApp]]" restamp> <cr-link-row id="manageApps" label="$i18n{androidAppsManageApps}" - on-click="onManageAndroidAppsClick_" external + on-click="onManageAndroidAppsClick_" + external + button-aria-description="$i18n{opensInNewTab}" deep-link-focus-id$="[[Setting.kManageAndroidPreferences]]"> </cr-link-row> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/OWNERS b/chrome/browser/resources/settings/chromeos/os_files_page/OWNERS new file mode 100644 index 0000000..31b8eee --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_files_page/OWNERS
@@ -0,0 +1 @@ +file://ui/file_manager/OWNERS \ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.ts b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.ts index f711b7d..a50ef58e 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.ts +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.ts
@@ -30,9 +30,9 @@ import {DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {SettingsToggleButtonElement} from '../../controls/settings_toggle_button.js'; -import {FocusConfig} from '../../focus_config.js'; import {castExists} from '../assert_extras.js'; import {DeepLinkingMixin} from '../deep_linking_mixin.js'; +import {FocusConfig} from '../focus_config.js'; import {recordSettingChange} from '../metrics_recorder.js'; import {Setting} from '../mojom-webui/setting.mojom-webui.js'; import {routes} from '../os_settings_routes.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.html b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.html index 59bfd16..2c464513 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.html +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.html
@@ -130,7 +130,9 @@ <div class="subsection cr-padded-text"> <cr-link-row id="manageGoogleAccountLanguage" label="$i18n{manageGoogleAccountLanguageLabel}" - external on-click="openManageGoogleAccountLanguage_"> + on-click="openManageGoogleAccountLanguage_" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </div> </div>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.ts b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.ts index 19b7feb..84a85dc8 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.ts +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.ts
@@ -25,7 +25,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {FocusConfig} from '../../focus_config.js'; +import {FocusConfig} from '../focus_config.js'; import {routes} from '../os_settings_routes.js'; import {Router} from '../router.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.html b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.html index b52c724..5abac5e 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.html
@@ -132,7 +132,10 @@ <cr-link-row id="syncDashboardLink" class="hr" label="$i18n{manageSyncedDataTitle}" on-click="onSyncDashboardLinkClick_" - hidden="[[syncStatus.supervisedUser]]" external></cr-link-row> + hidden="[[syncStatus.supervisedUser]]" + external + button-aria-description="$i18n{opensInNewTab}"> + </cr-link-row> <cr-expand-button id="encryptionDescription" hidden="[[syncPrefs.passphraseRequired]]"
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.ts b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.ts index 8ab88f6..6a09bfe8 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.ts +++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.ts
@@ -35,8 +35,8 @@ import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; -import {FocusConfig} from '../../focus_config.js'; import {PageStatus, StatusAction, SyncBrowserProxy, SyncBrowserProxyImpl, SyncPrefs, SyncStatus} from '../../people_page/sync_browser_proxy.js'; +import {FocusConfig} from '../focus_config.js'; import {RouteObserverMixin} from '../route_observer_mixin.js'; import {Router} from '../router.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/os_printing_page.html b/chrome/browser/resources/settings/chromeos/os_printing_page/os_printing_page.html index 1cafdef8..e75064c 100644 --- a/chrome/browser/resources/settings/chromeos/os_printing_page/os_printing_page.html +++ b/chrome/browser/resources/settings/chromeos/os_printing_page/os_printing_page.html
@@ -10,13 +10,17 @@ on-click="onOpenPrintManagement_" label="$i18n{printJobsTitle}" sub-label="$i18n{printJobsSublabel}" - external deep-link-focus-id$="[[Setting.kPrintJobs]]"> + external + button-aria-description="$i18n{opensInNewTab}" + deep-link-focus-id$="[[Setting.kPrintJobs]]"> </cr-link-row> <cr-link-row class="hr" id="scanningApp" on-click="onOpenScanningApp_" label="$i18n{scanAppTitle}" sub-label="$i18n{scanAppSublabel}" - external deep-link-focus-id$="[[Setting.kScanningApp]]"> + external + button-aria-description="$i18n{opensInNewTab}" + deep-link-focus-id$="[[Setting.kScanningApp]]"> </cr-link-row> </div> <template is="dom-if" route-path="/cupsPrinters">
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/google_assistant_subpage.html b/chrome/browser/resources/settings/chromeos/os_search_page/google_assistant_subpage.html index bfb93616..a5381d48 100644 --- a/chrome/browser/resources/settings/chromeos/os_search_page/google_assistant_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_search_page/google_assistant_subpage.html
@@ -110,5 +110,8 @@ </settings-toggle-button> <cr-link-row id="google-assistant-settings" class="hr" on-click="onGoogleAssistantSettingsTapped_" - label="$i18n{googleAssistantSettings}" external></cr-link-row> + label="$i18n{googleAssistantSettings}" + external + button-aria-description="$i18n{opensInNewTab}"> + </cr-link-row> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.html b/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.html index 36fb4982..107f28f 100644 --- a/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.html +++ b/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.html
@@ -12,5 +12,7 @@ <cr-link-row id="browserSearchSettingsLink" label="$i18n{osSearchEngineLabel}" sub-label="[[currentSearchEngine_.name]]" - on-click="onSearchEngineLinkClick_" external> + on-click="onSearchEngineLinkClick_" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row>
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index 4d71d2bc..f263946b 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -117,6 +117,7 @@ "chromeos/os_a11y_page/audio_and_captions_page.ts", "chromeos/os_a11y_page/change_dictation_locale_dialog.ts", "chromeos/os_a11y_page/chromevox_subpage.ts", + "chromeos/os_a11y_page/bluetooth_braille_display_ui.ts", "chromeos/os_a11y_page/cursor_and_touchpad_page.ts", "chromeos/os_a11y_page/display_and_magnification_page.ts", "chromeos/os_a11y_page/keyboard_and_text_input_page.ts", @@ -325,6 +326,7 @@ "chromeos/device_page/input_device_settings_types.ts", "chromeos/device_page/input_device_settings_utils.ts", "chromeos/ensure_lazy_loaded.ts", + "chromeos/focus_config.ts", "chromeos/guest_os/guest_os_browser_proxy.ts", "chromeos/internet_page/cellular_setup_settings_delegate.ts", "chromeos/internet_page/internet_page_browser_proxy.ts", @@ -352,6 +354,7 @@ "chromeos/os_a11y_page/text_to_speech_page_browser_proxy.ts", "chromeos/os_a11y_page/tts_subpage_browser_proxy.ts", "chromeos/os_a11y_page/chromevox_subpage_browser_proxy.ts", + "chromeos/os_a11y_page/bluetooth_braille_display_manager.ts", "chromeos/os_a11y_page/select_to_speak_subpage_browser_proxy.ts", "chromeos/os_about_page/about_page_browser_proxy.ts", "chromeos/os_about_page/device_name_browser_proxy.ts", @@ -413,7 +416,6 @@ "controls/pref_control_mixin.ts", "controls/settings_boolean_control_mixin.ts", "extension_control_browser_proxy.ts", - "focus_config.ts", "i18n_setup.ts", "lifetime_browser_proxy.ts", "people_page/profile_info_browser_proxy.ts",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_animated_pages.ts b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_animated_pages.ts index 4fd438b..e1de3fc 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_animated_pages.ts +++ b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_animated_pages.ts
@@ -21,7 +21,7 @@ import {IronPagesElement} from '//resources/polymer/v3_0/iron-pages/iron-pages.js'; import {DomIf, FlattenedNodesObserver, microTask, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {FocusConfig} from '../../focus_config.js'; +import {FocusConfig} from '../focus_config.js'; import {RouteObserverMixin} from '../route_observer_mixin.js'; import {Route, Router} from '../router.js'; import {getSettingIdParameter} from '../setting_id_param_util.js';
diff --git a/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.html b/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.html index 2cf06ac0a..9a2a0c9 100644 --- a/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.html +++ b/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.html
@@ -13,7 +13,8 @@ start-icon="cr20:kite" label="$i18n{parentalControlsPageTitle}" sub-label="$i18n{parentalControlsPageViewSettingsLabel}" - external> + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </template> <template is="dom-if" if="[[!isChild_]]">
diff --git a/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.html b/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.html index 44810270..fc80f7e 100644 --- a/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.html +++ b/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.html
@@ -3,8 +3,10 @@ <div route-path="default"> <cr-link-row id="personalizationHubButton" label="$i18n{personalizationHubTitle}" - sub-label="$i18n{personalizationHubSubtitle}" external - on-click="openPersonalizationHub_"> + sub-label="$i18n{personalizationHubSubtitle}" + on-click="openPersonalizationHub_" + external + button-aria-description="$i18n{opensInNewTab}"> </cr-link-row> </div>
diff --git a/chrome/browser/resources/side_panel/companion/OWNERS b/chrome/browser/resources/side_panel/companion/OWNERS index 6e913aa..8fa4df68 100644 --- a/chrome/browser/resources/side_panel/companion/OWNERS +++ b/chrome/browser/resources/side_panel/companion/OWNERS
@@ -1,2 +1 @@ -file://components/lens/OWNERS - +file://chrome/browser/companion/OWNERS
diff --git a/chrome/browser/resources/side_panel/companion/companion.ts b/chrome/browser/resources/side_panel/companion/companion.ts index 778a97a..3032681 100644 --- a/chrome/browser/resources/side_panel/companion/companion.ts +++ b/chrome/browser/resources/side_panel/companion/companion.ts
@@ -23,7 +23,7 @@ METHOD_TYPE = 'type', // Optional arguments. - // Arguments for MethodType.kOnExpsOptinStatusChange. + // Arguments for MethodType.kOnExpsOptInStatusAvailable. IS_EXPS_OPTED_IN = 'isExpsOptedIn', // Arguments for MethodType.kOnPromoAction. @@ -35,6 +35,9 @@ // Arguments for MethodType.kOnOpenInNewTabButtonURLChanged. URL_FOR_OPEN_IN_NEW_TAB = 'urlForOpenInNewTab', + + // Arguments for browser -> iframe communcation. + COMPANION_UPDATE_PARAMS = 'companion_update_params', } const companionProxy: CompanionProxy = CompanionProxyImpl.getInstance(); @@ -47,13 +50,29 @@ } function initialize() { - // When the url is changed, we update our iframe src to pass new parameters. - companionProxy.callbackRouter.onURLChanged.addListener((newUrl: Url) => { + // For the initial navigation, we update our iframe src to pass new + // URL. + companionProxy.callbackRouter.loadCompanionPage.addListener((newUrl: Url) => { const frame = document.body.querySelector('iframe'); assert(frame); frame.src = newUrl.url; }); + // For subsequent navigations, we send a post message. + companionProxy.callbackRouter.updateCompanionPage.addListener( + (companionUpdateProto: string) => { + const companionOrigin = + new URL(loadTimeData.getString('companion_origin')).origin; + const message = + {[ParamType.COMPANION_UPDATE_PARAMS]: companionUpdateProto}; + + const frame = document.body.querySelector('iframe'); + assert(frame); + if (frame.contentWindow) { + frame.contentWindow.postMessage(message, companionOrigin); + } + }); + companionProxy.handler.showUI(); } @@ -79,6 +98,9 @@ if (validatePromoArguments(promoType, promoAction)) { companionProxy.handler.onPromoAction(promoType, promoAction); } + } else if (methodType === MethodType.kOnExpsOptInStatusAvailable) { + companionProxy.handler.onExpsOptInStatusAvailable( + data[ParamType.IS_EXPS_OPTED_IN]); } }
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc index 5c833f4..ce4faf70 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc
@@ -71,6 +71,10 @@ void MaybeLogDocumentMetrics(const std::string& request_data, DownloadCheckResultReason reason) { + if (request_data.empty()) { + return; + } + ClientDownloadRequest request; if (!request.ParseFromString(request_data)) return;
diff --git a/chrome/browser/ssl/https_upgrades_browsertest.cc b/chrome/browser/ssl/https_upgrades_browsertest.cc index 113c549..ed1941c 100644 --- a/chrome/browser/ssl/https_upgrades_browsertest.cc +++ b/chrome/browser/ssl/https_upgrades_browsertest.cc
@@ -5,6 +5,7 @@ #include <algorithm> #include <vector> +#include "base/strings/strcat.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/simple_test_clock.h" @@ -106,6 +107,9 @@ mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost( cert, "bad-https.test", verify_result, net::ERR_CERT_COMMON_NAME_INVALID); + mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost( + cert, "www.bad-https.test", verify_result, + net::ERR_CERT_COMMON_NAME_INVALID); http_server_.AddDefaultHandlers(GetChromeTestDataDir()); https_server_.AddDefaultHandlers(GetChromeTestDataDir()); @@ -1533,6 +1537,48 @@ } } +// Regression test for crbug.com/1431026. Triggers a navigation where HTTPS +// upgrades applied multiple times across redirects to different sites. +// Should not crash when DCHECKS are enabled. +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, crbug1431026) { + GURL www_bad_https_url = + https_server()->GetURL("www.bad-https.test", "/simple.html"); + GURL www_http_url = + http_server()->GetURL("www.bad-https.test", "/simple.html"); + + // Configure HTTP and bad-HTTPS URLs which redirect to www. subdomain. + std::string www_redirect_path = + base::StrCat({"/server-redirect?", www_http_url.spec()}); + GURL redirecting_bad_https_url = + https_server()->GetURL("bad-https.test", www_redirect_path); + GURL redirecting_http_url = + http_server()->GetURL("bad-https.test", www_redirect_path); + + // A good HTTPS URL which redirects to an HTTP URL, which also redirects. + GURL initial_redirecting_good_https_url = https_server()->GetURL( + "good-https.test", + base::StrCat({"/server-redirect-301?", redirecting_http_url.spec()})); + + auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_FALSE( + content::NavigateToURL(contents, initial_redirecting_good_https_url)); + + if (IsHttpInterstitialEnabled()) { + // Should be showing interstitial on http://bad-https.test/. + EXPECT_EQ(redirecting_http_url, contents->GetLastCommittedURL()); + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + } else { + // Either due to no upgrades, or due to fast fallback to HTTP, this should + // end up on http://www.bad-https.test. + EXPECT_EQ(www_http_url, contents->GetLastCommittedURL()); + EXPECT_FALSE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + } +} + // A simple test fixture that ensures the kHttpsFirstModeV2 feature is enabled // and constructs a HistogramTester (so that it gets initialized before browser // startup). Used for testing pref tracking logic.
diff --git a/chrome/browser/ssl/https_upgrades_interceptor.cc b/chrome/browser/ssl/https_upgrades_interceptor.cc index 91671f2..66945b3 100644 --- a/chrome/browser/ssl/https_upgrades_interceptor.cc +++ b/chrome/browser/ssl/https_upgrades_interceptor.cc
@@ -563,10 +563,13 @@ mojo::PendingReceiver<network::mojom::URLLoader> receiver, mojo::PendingRemote<network::mojom::URLLoaderClient> client) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!receiver_.is_bound()); - DCHECK(!client_.is_bound()); - // Set up Mojo connection and initiate the redirect. + // Set up Mojo connection and initiate the redirect. `client_` and `receiver_` + // may have been previously bound from handling a previous upgrade earlier in + // the same navigation, so reset them before re-binding them to handle a new + // redirect. + receiver_.reset(); + client_.reset(); receiver_.Bind(std::move(receiver)); receiver_.set_disconnect_handler( base::BindOnce(&HttpsUpgradesInterceptor::OnConnectionClosed,
diff --git a/chrome/browser/supervised_user/chromeos/parent_access_extension_approvals_manager.cc b/chrome/browser/supervised_user/chromeos/parent_access_extension_approvals_manager.cc index 673d1bb92..78fed535 100644 --- a/chrome/browser/supervised_user/chromeos/parent_access_extension_approvals_manager.cc +++ b/chrome/browser/supervised_user/chromeos/parent_access_extension_approvals_manager.cc
@@ -127,6 +127,11 @@ .Run(SupervisedUserExtensionsDelegate::ExtensionApprovalResult:: kFailed); break; + case ash::ParentAccessDialog::Result::Status::kDisabled: + std::move(done_callback_) + .Run(SupervisedUserExtensionsDelegate::ExtensionApprovalResult:: + kBlocked); + break; } }
diff --git a/chrome/browser/supervised_user/chromeos/parent_access_extension_approvals_manager_unittest.cc b/chrome/browser/supervised_user/chromeos/parent_access_extension_approvals_manager_unittest.cc index 7814aa7..ea0ceb7 100644 --- a/chrome/browser/supervised_user/chromeos/parent_access_extension_approvals_manager_unittest.cc +++ b/chrome/browser/supervised_user/chromeos/parent_access_extension_approvals_manager_unittest.cc
@@ -251,6 +251,30 @@ } TEST_F(ParentAccessExtensionApprovalsManagerTest, + GetParentAccessApproval_Disabled) { + SetSupervisedUserMayRequestPermissionsPref(true); + scoped_refptr<const extensions::Extension> extension = + extensions::ExtensionBuilder(kTestExtensionName).Build(); + base::RunLoop run_loop; + approvals_manager_->ShowParentAccessDialog( + *extension, profile_, extensions::util::GetDefaultExtensionIcon(), + base::BindOnce( + [](base::OnceClosure quit_closure, + extensions::SupervisedUserExtensionsDelegate:: + ExtensionApprovalResult result) { + EXPECT_EQ(result, extensions::SupervisedUserExtensionsDelegate:: + ExtensionApprovalResult::kBlocked); + std::move(quit_closure).Run(); + }, + run_loop.QuitClosure())); + + auto dialog_result = std::make_unique<ash::ParentAccessDialog::Result>(); + dialog_result->status = ash::ParentAccessDialog::Result::Status::kDisabled; + dialog_provider_->TriggerCallbackWithResult(std::move(dialog_result)); + run_loop.Run(); +} + +TEST_F(ParentAccessExtensionApprovalsManagerTest, GetParentAccessApproval_Error) { SetSupervisedUserMayRequestPermissionsPref(true); scoped_refptr<const extensions::Extension> extension =
diff --git a/chrome/browser/sync/test/integration/single_client_web_apps_sync_generated_icon_fix_sync_test.cc b/chrome/browser/sync/test/integration/single_client_web_apps_sync_generated_icon_fix_sync_test.cc new file mode 100644 index 0000000..9430a23 --- /dev/null +++ b/chrome/browser/sync/test/integration/single_client_web_apps_sync_generated_icon_fix_sync_test.cc
@@ -0,0 +1,174 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/strings/strcat.h" +#include "base/strings/string_util.h" +#include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/test_future.h" +#include "base/time/time.h" +#include "chrome/browser/sync/test/integration/sync_service_impl_harness.h" +#include "chrome/browser/sync/test/integration/web_apps_sync_test_base.h" +#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/manifest_update_manager.h" +#include "chrome/browser/web_applications/os_integration/os_integration_manager.h" +#include "chrome/browser/web_applications/test/web_app_test_observers.h" +#include "chrome/browser/web_applications/web_app_command_scheduler.h" +#include "chrome/browser/web_applications/web_app_helpers.h" +#include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/common/chrome_features.h" +#include "content/public/test/browser_test.h" + +namespace web_app { + +namespace { +using Param = std::tuple<bool /*flag_enabled*/, + bool /*wait_8_days*/, + bool /*sync_broken_icons*/>; +} + +class SingleClientWebAppsSyncGeneratedIconFixSyncTest + : public WebAppsSyncTestBase, + public testing::WithParamInterface<Param> { + public: + static std::string ParamToString(testing::TestParamInfo<Param> param) { + return base::StrCat({ + std::get<0>(param.param) ? "FlagEnabled" : "FlagDisabled", + "_", + std::get<1>(param.param) ? "Wait8Days" : "NoWait", + "_", + std::get<2>(param.param) ? "SyncBrokenIcons" : "SyncNormalIcons", + }); + } + + SingleClientWebAppsSyncGeneratedIconFixSyncTest() + : WebAppsSyncTestBase(SINGLE_CLIENT) { + if (flag_enabled()) { + scoped_feature_list_.InitAndEnableFeature( + features::kWebAppSyncGeneratedIconFix); + } else { + scoped_feature_list_.InitAndDisableFeature( + features::kWebAppSyncGeneratedIconFix); + } + } + + ~SingleClientWebAppsSyncGeneratedIconFixSyncTest() override = default; + + bool flag_enabled() const { return std::get<0>(GetParam()); } + bool wait_8_days() const { return std::get<1>(GetParam()); } + bool sync_broken_icons() const { return std::get<2>(GetParam()); } + + WebAppProvider& provider(int index) { + return *WebAppProvider::GetForTest(GetProfile(index)); + } + + void SetUpOnMainThread() override { + SyncTest::SetUpOnMainThread(); + ASSERT_TRUE(SetupSync()); + + embedded_test_server()->RegisterRequestHandler(base::BindLambdaForTesting( + [this](const net::test_server::HttpRequest& request) + -> std::unique_ptr<net::test_server::HttpResponse> { + if (!serve_pngs_ && base::EndsWith(request.GetURL().spec(), ".png")) { + auto http_response = + std::make_unique<net::test_server::BasicHttpResponse>(); + http_response->set_code(net::HTTP_NOT_FOUND); + return std::move(http_response); + } + return nullptr; + })); + embedded_test_server_handle_ = + embedded_test_server()->StartAndReturnHandle(); + } + + protected: + bool serve_pngs_ = true; + + private: + OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; + base::test::ScopedFeatureList scoped_feature_list_; + net::test_server::EmbeddedTestServerHandle embedded_test_server_handle_; +}; + +IN_PROC_BROWSER_TEST_P(SingleClientWebAppsSyncGeneratedIconFixSyncTest, + GeneratedIconsSilentlyUpdate) { + // Listen for sync install in client. + WebAppTestInstallObserver install_observer(GetProfile(0)); + install_observer.BeginListening(); + + if (sync_broken_icons()) { + // Cause icon downloading to fail. + serve_pngs_ = false; + } + + // Insert web app into sync profile. + // Fields copied from chrome/test/data/web_apps/basic.json. + GURL start_url = embedded_test_server()->GetURL("/web_apps/basic.html"); + AppId app_id = GenerateAppId(/*manifest_id=*/absl::nullopt, start_url); + sync_pb::EntitySpecifics specifics; + sync_pb::WebAppSpecifics& web_app_specifics = *specifics.mutable_web_app(); + web_app_specifics.set_start_url(start_url.spec()); + web_app_specifics.set_user_display_mode(sync_pb::WebAppSpecifics::STANDALONE); + web_app_specifics.set_name("Basic web app"); + GetFakeServer()->InjectEntity( + syncer::PersistentUniqueClientEntity::CreateFromSpecificsForTesting( + /*non_unique_name=*/app_id, + /*client_tag=*/app_id, specifics, + /*creation_time=*/0, /*last_modified_time=*/0)); + + // Await sync install. + EXPECT_EQ(install_observer.Wait(), app_id); + + // Icons should be generated if icon downloading was disabled. + EXPECT_EQ( + provider(0).registrar_unsafe().GetAppById(app_id)->is_generated_icon(), + sync_broken_icons()); + + // Ensure installed locally to enable manifest updating. + { + base::RunLoop run_loop; + provider(0).scheduler().InstallAppLocally(app_id, run_loop.QuitClosure()); + run_loop.Run(); + } + + // Re-enable icons if disabled. + serve_pngs_ = true; + + if (wait_8_days()) { + // Advance time beyond the fix time window. + provider(0).manifest_update_manager().set_time_override_for_testing( + base::Time::Now() + base::Days(8)); + } + + // Trigger manifest update. + base::test::TestFuture<const GURL&, ManifestUpdateResult> update_future; + ManifestUpdateManager::SetResultCallbackForTesting( + update_future.GetCallback()); + ASSERT_TRUE(AddTabAtIndexToBrowser(GetBrowser(0), 0, start_url, + ui::PAGE_TRANSITION_AUTO_TOPLEVEL)); + absl::optional<ManifestUpdateResult> update_result = update_future.Get<1>(); + + // Check icons fixed if flag enabled and in time window. + bool expect_fix_applied = + flag_enabled() && !wait_8_days() && sync_broken_icons(); + bool expect_generated_icons = !expect_fix_applied && sync_broken_icons(); + EXPECT_EQ(update_result, expect_fix_applied + ? ManifestUpdateResult::kAppUpdated + : ManifestUpdateResult::kAppUpToDate); + EXPECT_EQ( + provider(0).registrar_unsafe().GetAppById(app_id)->is_generated_icon(), + expect_generated_icons); +} + +INSTANTIATE_TEST_SUITE_P( + All, + SingleClientWebAppsSyncGeneratedIconFixSyncTest, + testing::Combine( + /*flag_enabled=*/testing::Values(true, false), + /*wait_8_days=*/testing::Values(true, false), + /*sync_broken_icons=*/testing::Values(true, false)), + SingleClientWebAppsSyncGeneratedIconFixSyncTest::ParamToString); + +} // namespace web_app
diff --git a/chrome/browser/sync/test/integration/sync_integration_tests_sources.gni b/chrome/browser/sync/test/integration/sync_integration_tests_sources.gni index 27e9048..11fd578 100644 --- a/chrome/browser/sync/test/integration/sync_integration_tests_sources.gni +++ b/chrome/browser/sync/test/integration/sync_integration_tests_sources.gni
@@ -43,6 +43,7 @@ "../browser/sync/test/integration/single_client_user_consents_sync_test.cc", "../browser/sync/test/integration/single_client_user_events_sync_test.cc", "../browser/sync/test/integration/single_client_wallet_sync_test.cc", + "../browser/sync/test/integration/single_client_web_apps_sync_generated_icon_fix_sync_test.cc", "../browser/sync/test/integration/single_client_web_apps_sync_test.cc", "../browser/sync/test/integration/sync_auth_test.cc", "../browser/sync/test/integration/sync_errors_test.cc",
diff --git a/chrome/browser/thumbnail/cc/thumbnail_cache.cc b/chrome/browser/thumbnail/cc/thumbnail_cache.cc index 3c863ff..a814ae4 100644 --- a/chrome/browser/thumbnail/cc/thumbnail_cache.cc +++ b/chrome/browser/thumbnail/cc/thumbnail_cache.cc
@@ -234,8 +234,12 @@ thumbnail->SetBitmap(bitmap); RemoveFromReadQueue(tab_id); - MakeSpaceForNewItemIfNecessary(tab_id); - cache_.Put(tab_id, std::move(thumbnail)); + if (!base::FeatureList::IsEnabled(kThumbnailCacheRefactor) || + base::Contains(visible_ids_, tab_id)) { + MakeSpaceForNewItemIfNecessary(tab_id); + cache_.Put(tab_id, std::move(thumbnail)); + NotifyObserversOfThumbnailAddedToCache(tab_id); + } if (use_approximation_thumbnail_) { std::pair<SkBitmap, float> approximation = @@ -324,7 +328,7 @@ return true; } -void ThumbnailCache::UpdateVisibleIds(const TabIdList& priority, +void ThumbnailCache::UpdateVisibleIds(const std::vector<TabId>& priority, TabId primary_tab_id) { bool needs_update = false; if (primary_tab_id_ != primary_tab_id) { @@ -885,6 +889,7 @@ if (base::android::ApplicationStatusListener::GetState() == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { thumbnail->CreateUIResource(); + NotifyObserversOfThumbnailAddedToCache(tab_id); } } WriteThumbnailIfNecessary(tab_id, std::move(compressed_data), scale, @@ -1058,21 +1063,32 @@ time_stamp = meta_iter->second.capture_time(); } - MakeSpaceForNewItemIfNecessary(tab_id); - std::unique_ptr<Thumbnail> thumbnail = Thumbnail::Create( - tab_id, time_stamp, scale, ui_resource_provider_, this); - thumbnail->SetCompressedBitmap(std::move(compressed_data), content_size); - if (kPreferCPUMemory) { - thumbnail->CreateUIResource(); - } + if (!base::FeatureList::IsEnabled(kThumbnailCacheRefactor) || + (base::FeatureList::IsEnabled(kThumbnailCacheRefactor) && + base::Contains(visible_ids_, tab_id))) { + MakeSpaceForNewItemIfNecessary(tab_id); + std::unique_ptr<Thumbnail> thumbnail = Thumbnail::Create( + tab_id, time_stamp, scale, ui_resource_provider_, this); + thumbnail->SetCompressedBitmap(std::move(compressed_data), content_size); + if (kPreferCPUMemory) { + thumbnail->CreateUIResource(); + } - cache_.Put(tab_id, std::move(thumbnail)); - NotifyObserversOfThumbnailRead(tab_id); + cache_.Put(tab_id, std::move(thumbnail)); + NotifyObserversOfThumbnailAddedToCache(tab_id); + NotifyObserversOfThumbnailRead(tab_id); + } } ReadNextThumbnail(); } +void ThumbnailCache::NotifyObserversOfThumbnailAddedToCache(TabId tab_id) { + for (ThumbnailCacheObserver& observer : observers_) { + observer.OnThumbnailAddedToCache(tab_id); + } +} + void ThumbnailCache::NotifyObserversOfThumbnailRead(TabId tab_id) { for (ThumbnailCacheObserver& observer : observers_) { observer.OnFinishedThumbnailRead(tab_id);
diff --git a/chrome/browser/thumbnail/cc/thumbnail_cache.h b/chrome/browser/thumbnail/cc/thumbnail_cache.h index 9e35fb9..d61b982 100644 --- a/chrome/browser/thumbnail/cc/thumbnail_cache.h +++ b/chrome/browser/thumbnail/cc/thumbnail_cache.h
@@ -10,6 +10,7 @@ #include <list> #include <map> #include <set> +#include <vector> #include "base/files/file_path.h" #include "base/functional/bind.h" @@ -40,6 +41,7 @@ class ThumbnailCacheObserver { public: + virtual void OnThumbnailAddedToCache(TabId tab_id) = 0; virtual void OnFinishedThumbnailRead(TabId tab_id) = 0; }; @@ -73,7 +75,8 @@ void InvalidateThumbnailIfChanged(TabId tab_id, const GURL& url); bool CheckAndUpdateThumbnailMetaData(TabId tab_id, const GURL& url); - void UpdateVisibleIds(const TabIdList& priority, TabId primary_tab_id); + void UpdateVisibleIds(const std::vector<TabId>& priority, + TabId primary_tab_id); void DecompressThumbnailFromFile( TabId tab_id, double jpeg_aspect_ratio, @@ -176,6 +179,7 @@ sk_sp<SkPixelRef> compressed_data, float scale, const gfx::Size& content_size); + void NotifyObserversOfThumbnailAddedToCache(TabId tab_id); void NotifyObserversOfThumbnailRead(TabId tab_id); void RemoveOnMatchedTimeStamp(TabId tab_id, const base::Time& time_stamp); static std::pair<SkBitmap, float> CreateApproximation(const SkBitmap& bitmap,
diff --git a/chrome/browser/thumbnail/cc/thumbnail_cache_unittest.cc b/chrome/browser/thumbnail/cc/thumbnail_cache_unittest.cc index be73747..c50f42c4 100644 --- a/chrome/browser/thumbnail/cc/thumbnail_cache_unittest.cc +++ b/chrome/browser/thumbnail/cc/thumbnail_cache_unittest.cc
@@ -86,6 +86,8 @@ ASSERT_TRUE(bitmap.tryAllocN32Pixels(kDimension * kKiB, kDimension)); bitmap.setImmutable(); + thumbnail_cache().UpdateVisibleIds(std::vector<TabId>({kTabId1, kTabId2}), + -1); EXPECT_TRUE(thumbnail_cache().CheckAndUpdateThumbnailMetaData( kTabId1, GURL("https://www.foo.com/"))); thumbnail_cache().Put(kTabId1, bitmap, @@ -131,6 +133,7 @@ constexpr int kDimension = 4; ASSERT_TRUE(bitmap.tryAllocN32Pixels(kDimension * kKiB, kDimension)); bitmap.setImmutable(); + thumbnail_cache().UpdateVisibleIds(std::vector<TabId>({kTabId}), -1); EXPECT_TRUE(thumbnail_cache().CheckAndUpdateThumbnailMetaData( kTabId, GURL("https://www.foo.com/"))); thumbnail_cache().Put(kTabId, bitmap,
diff --git a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc index 6c5f92b..b67b4c1 100644 --- a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc +++ b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
@@ -3464,7 +3464,8 @@ ash::SavedDeskControllerTestApi(saved_desk_controller) .SetAdminTemplate(std::move(admin_template)); - saved_desk_controller->LaunchAdminTemplate(template_uuid); + saved_desk_controller->LaunchAdminTemplate( + template_uuid, display::Screen::GetScreen()->GetPrimaryDisplay().id()); // Verify that there are two browsers (one from the suite and one from the // test), and verify that our launched browser is stacked on top.
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc index 2e49ebd..3e3af9d 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc
@@ -223,11 +223,6 @@ return pinned_files; } -void HoldingSpaceKeyedService::AddNearbyShare( - const base::FilePath& nearby_share_path) { - AddItemOfType(HoldingSpaceItem::Type::kNearbyShare, nearby_share_path); -} - const std::string& HoldingSpaceKeyedService::AddPhoneHubCameraRollItem( const base::FilePath& item_path, const HoldingSpaceProgress& progress) {
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h index 3f194af..9cea52c 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h +++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h
@@ -91,10 +91,6 @@ std::vector<GURL> GetPinnedFiles() const; // TODO(http://b/274477308): Remove one-off API. - // Adds a nearby share item backed by the provided absolute file path. - void AddNearbyShare(const base::FilePath& nearby_share_path); - - // TODO(http://b/274477308): Remove one-off API. // Adds a photo or video downloaded from a connected Android phone via // PhoneHub. Returns the id of the added holding space item or an empty string // if the item was not added due to de-duplication checks.
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc index 5460e2a..f16d119 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
@@ -2600,6 +2600,7 @@ case HoldingSpaceItem::Type::kCameraAppVideoGif: case HoldingSpaceItem::Type::kCameraAppVideoMp4: case HoldingSpaceItem::Type::kDiagnosticsLog: + case HoldingSpaceItem::Type::kNearbyShare: holding_space_service->AddItemOfType(type, file_path); break; case HoldingSpaceItem::Type::kDriveSuggestion: @@ -2607,9 +2608,6 @@ holding_space_service->SetSuggestions( /*suggestions=*/{{type, file_path}}); break; - case HoldingSpaceItem::Type::kNearbyShare: - holding_space_service->AddNearbyShare(file_path); - break; case HoldingSpaceItem::Type::kPinnedFile: holding_space_service->AddPinnedFiles( {file_manager::util::GetFileManagerFileSystemContext(profile) @@ -2833,7 +2831,8 @@ downloads_mount->CreateFile(item_1_virtual_path, "red"); ASSERT_FALSE(item_1_full_path.empty()); - holding_space_service->AddNearbyShare(item_1_full_path); + holding_space_service->AddItemOfType(HoldingSpaceItem::Type::kNearbyShare, + item_1_full_path); const base::FilePath item_2_virtual_path = base::FilePath("Alt/File 2.png"); // Create a fake nearby shared file on the local file system - later parts of @@ -2842,7 +2841,8 @@ const base::FilePath item_2_full_path = downloads_mount->CreateFile(item_2_virtual_path, "blue"); ASSERT_FALSE(item_2_full_path.empty()); - holding_space_service->AddNearbyShare(item_2_full_path); + holding_space_service->AddItemOfType(HoldingSpaceItem::Type::kNearbyShare, + item_2_full_path); EXPECT_EQ(initial_model, HoldingSpaceController::Get()->model()); EXPECT_EQ(HoldingSpaceController::Get()->model(),
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc index d6455e3..de1d3c3 100644 --- a/chrome/browser/ui/ash/test_wallpaper_controller.cc +++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -20,7 +20,9 @@ #include "ui/gfx/image/image.h" #include "url/gurl.h" -TestWallpaperController::TestWallpaperController() : id_cache_(0) {} +TestWallpaperController::TestWallpaperController() : id_cache_(0) { + ClearCounts(); +} TestWallpaperController::~TestWallpaperController() = default; @@ -33,6 +35,9 @@ void TestWallpaperController::ClearCounts() { set_online_wallpaper_count_ = 0; set_google_photos_wallpaper_count_ = 0; + show_override_wallpaper_count_[/*always_on_top=*/false] = 0; + show_override_wallpaper_count_[/*always_on_top=*/true] = 0; + remove_override_wallpaper_count_ = 0; remove_user_wallpaper_count_ = 0; wallpaper_info_ = absl::nullopt; update_current_wallpaper_layout_count_ = 0; @@ -217,13 +222,14 @@ NOTIMPLEMENTED(); } -void TestWallpaperController::ShowAlwaysOnTopWallpaper( - const base::FilePath& image_path) { - ++show_always_on_top_wallpaper_count_; +void TestWallpaperController::ShowOverrideWallpaper( + const base::FilePath& image_path, + bool always_on_top) { + ++show_override_wallpaper_count_[always_on_top]; } -void TestWallpaperController::RemoveAlwaysOnTopWallpaper() { - ++remove_always_on_top_wallpaper_count_; +void TestWallpaperController::RemoveOverrideWallpaper() { + ++remove_override_wallpaper_count_; } void TestWallpaperController::RemoveUserWallpaper(
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h index 917c8b9..627950d 100644 --- a/chrome/browser/ui/ash/test_wallpaper_controller.h +++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_ASH_TEST_WALLPAPER_CONTROLLER_H_ #define CHROME_BROWSER_UI_ASH_TEST_WALLPAPER_CONTROLLER_H_ +#include <map> + #include "ash/public/cpp/wallpaper/google_photos_wallpaper_params.h" #include "ash/public/cpp/wallpaper/online_wallpaper_params.h" #include "ash/public/cpp/wallpaper/wallpaper_controller.h" @@ -57,11 +59,15 @@ int get_update_daily_refresh_wallpaper_count() const { return update_daily_refresh_wallpaper_count_; } - int show_always_on_top_wallpaper_count() const { - return show_always_on_top_wallpaper_count_; + int show_override_wallpaper_count() const { + return show_override_wallpaper_count(/*always_on_top=*/false) + + show_override_wallpaper_count(/*always_on_top=*/true); } - int remove_always_on_top_wallpaper_count() const { - return remove_always_on_top_wallpaper_count_; + int show_override_wallpaper_count(bool always_on_top) const { + return show_override_wallpaper_count_.at(always_on_top); + } + int remove_override_wallpaper_count() const { + return remove_override_wallpaper_count_; } const std::string& collection_id() const { return wallpaper_info_.has_value() ? wallpaper_info_->collection_id @@ -146,8 +152,9 @@ user_manager::UserType user_type) override; void ShowSigninWallpaper() override; void ShowOneShotWallpaper(const gfx::ImageSkia& image) override; - void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) override; - void RemoveAlwaysOnTopWallpaper() override; + void ShowOverrideWallpaper(const base::FilePath& image_path, + bool always_on_top) override; + void RemoveOverrideWallpaper() override; void RemoveUserWallpaper(const AccountId& account_id, base::OnceClosure on_removed) override; void RemovePolicyWallpaper(const AccountId& account_id) override; @@ -181,8 +188,8 @@ int set_custom_wallpaper_count_ = 0; int set_online_wallpaper_count_ = 0; int set_google_photos_wallpaper_count_ = 0; - int show_always_on_top_wallpaper_count_ = 0; - int remove_always_on_top_wallpaper_count_ = 0; + std::map</*always_on_top=*/bool, int> show_override_wallpaper_count_; + int remove_override_wallpaper_count_ = 0; int third_party_wallpaper_count_ = 0; int update_daily_refresh_wallpaper_count_ = 0; absl::optional<ash::WallpaperInfo> wallpaper_info_;
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc index 79afd11..3301975 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
@@ -337,13 +337,14 @@ wallpaper_controller_->ShowSigninWallpaper(); } -void WallpaperControllerClientImpl::ShowAlwaysOnTopWallpaper( - const base::FilePath& image_path) { - wallpaper_controller_->ShowAlwaysOnTopWallpaper(image_path); +void WallpaperControllerClientImpl::ShowOverrideWallpaper( + const base::FilePath& image_path, + bool always_on_top) { + wallpaper_controller_->ShowOverrideWallpaper(image_path, always_on_top); } -void WallpaperControllerClientImpl::RemoveAlwaysOnTopWallpaper() { - wallpaper_controller_->RemoveAlwaysOnTopWallpaper(); +void WallpaperControllerClientImpl::RemoveOverrideWallpaper() { + wallpaper_controller_->RemoveOverrideWallpaper(); } void WallpaperControllerClientImpl::RemoveUserWallpaper(
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h index 48b1a106..90c3f86d 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
@@ -125,8 +125,9 @@ ash::WallpaperLayout layout); void ShowUserWallpaper(const AccountId& account_id); void ShowSigninWallpaper(); - void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path); - void RemoveAlwaysOnTopWallpaper(); + void ShowOverrideWallpaper(const base::FilePath& image_path, + bool always_on_top); + void RemoveOverrideWallpaper(); void RemoveUserWallpaper(const AccountId& account_id, base::OnceClosure on_removed); void RemovePolicyWallpaper(const AccountId& account_id);
diff --git a/chrome/browser/ui/test/test_browser_ui.cc b/chrome/browser/ui/test/test_browser_ui.cc index bb0ec84..0a25ab7 100644 --- a/chrome/browser/ui/test/test_browser_ui.cc +++ b/chrome/browser/ui/test/test_browser_ui.cc
@@ -54,11 +54,9 @@ // of lacros-chrome is complete. #if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_ARM64) // TODO(1429079): Make these pass with x64 win magic numbers. - // 255 * 4 is the max pixel_delta_threshold allowed by - // FuzzySkiaGoldMatchingAlgorithm. SetPixelMatchAlgorithm( std::make_unique<ui::test::FuzzySkiaGoldMatchingAlgorithm>( - /*max_different_pixels=*/40, /*pixel_delta_threshold=*/255 * 4)); + /*max_different_pixels=*/1000, /*pixel_delta_threshold=*/255 * 3)); #elif BUILDFLAG(IS_WIN) || \ (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) // Default to fuzzy diff. The magic number is chosen based on
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_partial_view.cc b/chrome/browser/ui/views/download/bubble/download_bubble_partial_view.cc index 32a5f03..d4a6203 100644 --- a/chrome/browser/ui/views/download/bubble/download_bubble_partial_view.cc +++ b/chrome/browser/ui/views/download/bubble/download_bubble_partial_view.cc
@@ -4,10 +4,192 @@ #include "chrome/browser/ui/views/download/bubble/download_bubble_partial_view.h" +#include "chrome/browser/download/bubble/download_bubble_prefs.h" +#include "chrome/browser/download/bubble/download_bubble_ui_controller.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/download/bubble/download_bubble_row_list_view.h" +#include "chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/gfx/color_palette.h" +#include "ui/gfx/geometry/insets.h" +#include "ui/views/border.h" +#include "ui/views/controls/button/checkbox.h" +#include "ui/views/controls/link_fragment.h" +#include "ui/views/controls/separator.h" +#include "ui/views/controls/styled_label.h" #include "ui/views/layout/flex_layout.h" +#include "ui/views/layout/table_layout.h" + +namespace { + +// We want the checkbox to accept gestures when users click on the label text, +// like all other Chrome checkboxes. This ViewTargeterDelegate achieves that. +class CheckboxTargeter : public views::ViewTargeterDelegate { + public: + CheckboxTargeter() = default; + ~CheckboxTargeter() override = default; + + // views::ViewTargeterDelegate: + bool DoesIntersectRect(const views::View* target, + const gfx::Rect& rect) const override { + return true; + } +}; + +class SuppressBubbleSettingRow : public views::View, + public views::ViewTargeterDelegate { + public: + METADATA_HEADER(SuppressBubbleSettingRow); + + SuppressBubbleSettingRow( + raw_ptr<Browser> browser, + bool should_show_settings_link, + raw_ptr<DownloadBubbleUIController> bubble_controller, + raw_ptr<DownloadBubbleNavigationHandler> navigation_handler) + : browser_(browser), + bubble_controller_(bubble_controller), + navigation_handler_(navigation_handler) { + // Because this view appears directly below the download rows, we want to + // use the same insets for consistency. + SetBorder(views::CreateEmptyBorder(GetLayoutInsets(DOWNLOAD_ROW))); + + SetEventTargeter(std::make_unique<views::ViewTargeter>(this)); + + const int icon_label_spacing = + ChromeLayoutProvider::Get()->GetDistanceMetric( + views::DISTANCE_RELATED_LABEL_HORIZONTAL); + auto* layout = SetLayoutManager(std::make_unique<views::TableLayout>()); + // Checkbox + layout->AddColumn(views::LayoutAlignment::kCenter, + views::LayoutAlignment::kStart, + views::TableLayout::kFixedSize, + views::TableLayout::ColumnSize::kUsePreferred, 0, 0); + // Labels + layout->AddPaddingColumn(views::TableLayout::kFixedSize, icon_label_spacing) + .AddColumn(views::LayoutAlignment::kStretch, + views::LayoutAlignment::kStart, 1.0f, + views::TableLayout::ColumnSize::kUsePreferred, 0, 0); + + layout->AddRows(1, 1.0f); + + checkbox_ = AddChildView(std::make_unique<views::Checkbox>( + std::u16string(), + base::BindRepeating(&SuppressBubbleSettingRow::CheckboxClicked, + base::Unretained(this)))); + checkbox_->SetAccessibleName( + l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW)); + checkbox_->SetChecked( + !download::IsDownloadBubblePartialViewEnabled(browser_->profile())); + targeter_ = std::make_unique<CheckboxTargeter>(); + checkbox_->SetEventTargeter( + std::make_unique<views::ViewTargeter>(targeter_.get())); + gfx::Insets insets = GetLayoutInsets(DOWNLOAD_ICON); + // The label within the checkbox will line up with `main_text` if we don't + // provide any insets. This is different than the download row view, which + // doesn't have a label within its icon column. So we use just the left and + // right inset from DOWNLOAD_ICON. + insets.set_top_bottom(0, 0); + checkbox_->SetBorder(views::CreateEmptyBorder(insets)); + + labels_wrapper_ = AddChildView(std::make_unique<views::View>()); + labels_wrapper_->SetLayoutManager(std::make_unique<views::FlexLayout>()) + ->SetOrientation(views::LayoutOrientation::kVertical); + + auto* main_text = + labels_wrapper_->AddChildView(std::make_unique<views::Label>( + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW), + views::style::CONTEXT_DIALOG_BODY_TEXT)); + main_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); + + size_t settings_offset; + std::u16string settings_link_text = l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_LINK); + settings_text_ = + labels_wrapper_->AddChildView(std::make_unique<views::StyledLabel>()); + settings_text_->SetText(l10n_util::GetStringFUTF16( + IDS_DOWNLOAD_BUBBLE_SUPPRESS_PARTIAL_VIEW_SETTINGS_REMINDER, + settings_link_text, &settings_offset)); + settings_text_->SetDefaultTextStyle(views::style::STYLE_SECONDARY); + settings_text_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + settings_text_->SetVisible(should_show_settings_link); + + views::StyledLabel::RangeStyleInfo link_style = + views::StyledLabel::RangeStyleInfo::CreateForLink( + base::BindRepeating(&SuppressBubbleSettingRow::SettingsLinkClicked, + base::Unretained(this))); + settings_text_->AddStyleRange( + gfx::Range(settings_offset, + settings_offset + settings_link_text.size()), + link_style); + } + + // views::ViewTargeterDelegate + View* TargetForRect(View* root, const gfx::Rect& rect) override { + views::View* target = + views::ViewTargeterDelegate::TargetForRect(root, rect); + // Links should operate as expected, but all other gestures on this view + // should be forwarded to the checkbox. + if (target->GetClassName() == views::LinkFragment::kViewClassName) { + return target; + } + + return checkbox_; + } + + private: + void CheckboxClicked() { + download::SetDownloadBubblePartialViewEnabled(browser_->profile(), + !checkbox_->GetChecked()); + settings_text_->SetVisible(true); + navigation_handler_->ResizeDialog(); + } + + void SettingsLinkClicked() { + bubble_controller_->RecordDownloadBubbleInteraction(); + chrome::ShowSettingsSubPage(browser_, chrome::kDownloadsSubPage); + } + + raw_ptr<Browser> browser_ = nullptr; + raw_ptr<DownloadBubbleUIController> bubble_controller_ = nullptr; + raw_ptr<DownloadBubbleNavigationHandler> navigation_handler_ = nullptr; + raw_ptr<views::Checkbox> checkbox_ = nullptr; + std::unique_ptr<CheckboxTargeter> targeter_; + raw_ptr<views::View> labels_wrapper_ = nullptr; + raw_ptr<views::StyledLabel> settings_text_ = nullptr; +}; + +BEGIN_METADATA(SuppressBubbleSettingRow, views::View) +END_METADATA + +bool ShouldShowSuppressSetting(raw_ptr<Profile> profile, int impressions) { + // Impressions have been incremented by this point, so the first + // impression is 1. + return download::IsDownloadBubblePartialViewEnabledDefaultValue(profile) && + 3 <= impressions && impressions <= 5; +} + +bool ShouldShowSettingsLink(int impressions) { + return impressions == 5; +} + +void MaybeRecordImpression(raw_ptr<Profile> profile, int impressions) { + // Pref writes are moderately expensive and we never change behavior for 7+ + // impressions, so don't increment further. + if (impressions > 6) { + return; + } + + download::SetDownloadBubblePartialViewImpressions(profile, impressions); +} + +} // namespace // static std::unique_ptr<DownloadBubblePartialView> DownloadBubblePartialView::Create( @@ -35,12 +217,38 @@ SetNotifyEnterExitOnChild(true); SetLayoutManager(std::make_unique<views::FlexLayout>()) ->SetOrientation(views::LayoutOrientation::kVertical); - const int preferred_width = ChromeLayoutProvider::Get()->GetDistanceMetric( + int preferred_width = ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_BUBBLE_PREFERRED_WIDTH); + raw_ptr<Profile> profile = browser->profile(); + const int impressions = + download::DownloadBubblePartialViewImpressions(profile) + 1; + std::unique_ptr<SuppressBubbleSettingRow> setting_row; + if (ShouldShowSuppressSetting(profile, impressions)) { + setting_row = std::make_unique<SuppressBubbleSettingRow>( + browser, ShouldShowSettingsLink(impressions), bubble_controller, + navigation_handler); + preferred_width = + std::max(preferred_width, setting_row->GetPreferredSize().width()); + } AddChildView(DownloadBubbleRowListView::CreateWithScroll( /*is_partial_view=*/true, browser, bubble_controller, navigation_handler, std::move(rows), preferred_width)); + + if (setting_row) { + const int separator_spacing = + ChromeLayoutProvider::Get()->GetDistanceMetric( + DISTANCE_CONTENT_LIST_VERTICAL_MULTI) / + 2; + auto separator = std::make_unique<views::Separator>(); + separator->SetProperty(views::kMarginsKey, + gfx::Insets::VH(separator_spacing, 0)); + + AddChildView(std::move(separator)); + AddChildView(std::move(setting_row)); + } + + MaybeRecordImpression(profile, impressions); } DownloadBubblePartialView::~DownloadBubblePartialView() = default;
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc index 53db338..126b29d5 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
@@ -65,6 +65,21 @@ ui::ImageModel::FromVectorIcon(icon, disabled_icon_color, icon_size)); } +std::u16string GetPinButtonTooltip(bool is_force_pinned, bool is_pinned) { + int tooltip_id = IDS_EXTENSIONS_PIN_TO_TOOLBAR; + if (is_force_pinned) { + tooltip_id = IDS_EXTENSIONS_PINNED_BY_ADMIN; + } else if (is_pinned) { + tooltip_id = IDS_EXTENSIONS_UNPIN_FROM_TOOLBAR; + } + return l10n_util::GetStringUTF16(tooltip_id); +} + +std::u16string GetPinButtonPressedAccText(bool is_pinned) { + return l10n_util::GetStringUTF16(is_pinned ? IDS_EXTENSION_PINNED + : IDS_EXTENSION_UNPINNED); +} + } // namespace ExtensionMenuItemView::ExtensionMenuItemView( Browser* browser, @@ -217,18 +232,21 @@ const auto* const color_provider = GetColorProvider(); const SkColor icon_color = color_provider->GetColor(kColorExtensionMenuIcon); - if (pin_button_) { - views::InkDrop::Get(pin_button_)->SetBaseColor(icon_color); - UpdatePinButton(); - } - if (base::FeatureList::IsEnabled( extensions_features::kExtensionsMenuAccessControl)) { - UpdateContextMenuButton(IsPinned()); + bool is_pinned = model_ && model_->IsActionPinned(controller_->GetId()); + UpdateContextMenuButton(is_pinned); } else { SetButtonIconWithColor( context_menu_button_, kBrowserToolsIcon, icon_color, color_provider->GetColor(kColorExtensionMenuIconDisabled)); + if (pin_button_) { + views::InkDrop::Get(pin_button_)->SetBaseColor(icon_color); + bool is_pinned = model_ && model_->IsActionPinned(controller_->GetId()); + bool is_force_pinned = + model_ && model_->IsActionForcePinned(controller_->GetId()); + UpdatePinButton(is_force_pinned, is_pinned); + } } } @@ -246,38 +264,26 @@ view_controller()->UpdateState(); } -void ExtensionMenuItemView::UpdatePinButton() { - if (!pin_button_) { +void ExtensionMenuItemView::UpdatePinButton(bool is_force_pinned, + bool is_pinned) { + if (!pin_button_ || !GetWidget()) { return; } - bool is_force_pinned = - model_ && model_->IsActionForcePinned(controller_->GetId()); - int pin_button_string_id = 0; - if (is_force_pinned) { - pin_button_string_id = IDS_EXTENSIONS_PINNED_BY_ADMIN; - } else if (IsPinned()) { - pin_button_string_id = IDS_EXTENSIONS_UNPIN_FROM_TOOLBAR; - } else { - pin_button_string_id = IDS_EXTENSIONS_PIN_TO_TOOLBAR; - } - pin_button_->SetTooltipText(l10n_util::GetStringUTF16(pin_button_string_id)); + pin_button_->SetTooltipText(GetPinButtonTooltip(is_force_pinned, is_pinned)); // Extension pinning is not available in Incognito as it leaves a trace of // user activity. pin_button_->SetEnabled(!is_force_pinned && !browser_->profile()->IsOffTheRecord()); - if (!GetWidget()) { - return; - } const auto* const color_provider = GetColorProvider(); const SkColor icon_color = color_provider->GetColor( - IsPinned() ? kColorExtensionMenuPinButtonIcon : kColorExtensionMenuIcon); + is_pinned ? kColorExtensionMenuPinButtonIcon : kColorExtensionMenuIcon); const SkColor disabled_icon_color = color_provider->GetColor( - IsPinned() ? kColorExtensionMenuPinButtonIconDisabled - : kColorExtensionMenuIconDisabled); + is_pinned ? kColorExtensionMenuPinButtonIconDisabled + : kColorExtensionMenuIconDisabled); SetButtonIconWithColor(pin_button_, - IsPinned() ? views::kUnpinIcon : views::kPinIcon, + is_pinned ? views::kUnpinIcon : views::kPinIcon, icon_color, disabled_icon_color); } @@ -323,11 +329,6 @@ context_menu_button_.get()))); } -bool ExtensionMenuItemView::IsPinned() const { - // |model_| can be null in unit tests. - return model_ && model_->IsActionPinned(controller_->GetId()); -} - void ExtensionMenuItemView::OnContextMenuPressed() { base::RecordAction(base::UserMetricsAction( "Extensions.Toolbar.MoreActionsButtonPressedFromMenu")); @@ -338,11 +339,14 @@ } void ExtensionMenuItemView::OnPinButtonPressed() { + CHECK(model_); base::RecordAction( base::UserMetricsAction("Extensions.Toolbar.PinButtonPressed")); - model_->SetActionVisibility(controller_->GetId(), !IsPinned()); - GetViewAccessibility().AnnounceText(l10n_util::GetStringUTF16( - IsPinned() ? IDS_EXTENSION_PINNED : IDS_EXTENSION_UNPINNED)); + // Toggle pin visibility. + bool is_action_pinned = model_->IsActionPinned(controller_->GetId()); + model_->SetActionVisibility(controller_->GetId(), !is_action_pinned); + GetViewAccessibility().AnnounceText( + GetPinButtonPressedAccText(is_action_pinned)); } bool ExtensionMenuItemView::IsContextMenuRunningForTesting() const {
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.h b/chrome/browser/ui/views/extensions/extensions_menu_item_view.h index 94835ad6..d7f17f8b 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.h +++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.h
@@ -59,7 +59,7 @@ void Update(SitePermissionsButtonState site_permissions_button_state); // Updates the pin button. - void UpdatePinButton(); + void UpdatePinButton(bool is_force_pinned, bool is_pinned); // Updates the context menu button given `is_action_pinned`. void UpdateContextMenuButton(bool is_action_pinned); @@ -86,10 +86,6 @@ // constructor. void SetupContextMenuButton(); - // Returns whether the action corresponding to this view is pinned to the - // toolbar. - bool IsPinned() const; - // Handles the context menu button press. This is passed as a callback to // `context_menu_button_`. void OnContextMenuPressed();
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_view.cc index 8d1e081..bd4a1d7 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_view.cc
@@ -472,8 +472,15 @@ } void ExtensionsMenuView::OnToolbarPinnedActionsChanged() { - for (auto* menu_item : extensions_menu_items_) - menu_item->UpdatePinButton(); + for (auto* menu_item : extensions_menu_items_) { + extensions::ExtensionId extension_id = + GetAsMenuItemView(menu_item)->view_controller()->GetId(); + bool is_force_pinned = + toolbar_model_ && toolbar_model_->IsActionForcePinned(extension_id); + bool is_pinned = + toolbar_model_ && toolbar_model_->IsActionPinned(extension_id); + menu_item->UpdatePinButton(is_force_pinned, is_pinned); + } } // static
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.h b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.h index 54ebf3fc..26157fa 100644 --- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.h +++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.h
@@ -57,8 +57,8 @@ std::unique_ptr<KeyboardHandler> keyboard_handler_; #endif #if BUILDFLAG(IS_MAC) - id clickEventTap_; - id notificationObserver_; + struct ObjCStorage; + std::unique_ptr<ObjCStorage> objc_storage_; #endif };
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm b/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm index 9a056b4..e533e5f 100644 --- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm +++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm
@@ -4,10 +4,10 @@ #include "chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h" +#include <Carbon/Carbon.h> // For keycode names in Carbon's Event.h. #import <Cocoa/Cocoa.h> -// Include Carbon to use the keycode names in Carbon's Event.h -#include <Carbon/Carbon.h> +#include <memory> #include "chrome/browser/ui/views/eye_dropper/eye_dropper_view.h" #include "content/public/browser/render_frame_host.h" @@ -35,14 +35,19 @@ } } -EyeDropperViewMac::~EyeDropperViewMac() {} +EyeDropperViewMac::~EyeDropperViewMac() = default; + +struct EyeDropperView::PreEventDispatchHandler::ObjCStorage { + id click_event_tap_ = nil; + id notification_observer_ = nil; +}; EyeDropperView::PreEventDispatchHandler::PreEventDispatchHandler( EyeDropperView* view, gfx::NativeView parent) - : view_(view) { + : view_(view), objc_storage_(std::make_unique<ObjCStorage>()) { // Ensure that this handler is called before color popup handler. - clickEventTap_ = [NSEvent + objc_storage_->click_event_tap_ = [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskAny handler:^NSEvent*(NSEvent* event) { NSEventType eventType = [event type]; @@ -66,7 +71,7 @@ // menubar. NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter]; - notificationObserver_ = + objc_storage_->notification_observer_ = [notificationCenter addObserverForName:NSMenuDidBeginTrackingNotification object:[NSApp mainMenu] queue:[NSOperationQueue mainQueue] @@ -76,16 +81,16 @@ } EyeDropperView::PreEventDispatchHandler::~PreEventDispatchHandler() { - if (clickEventTap_) { - [NSEvent removeMonitor:clickEventTap_]; - clickEventTap_ = nil; + if (objc_storage_->click_event_tap_) { + [NSEvent removeMonitor:objc_storage_->click_event_tap_]; + objc_storage_->click_event_tap_ = nil; } - if (notificationObserver_) { + if (objc_storage_->notification_observer_) { NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter]; - [notificationCenter removeObserver:notificationObserver_]; - notificationObserver_ = nil; + [notificationCenter removeObserver:objc_storage_->notification_observer_]; + objc_storage_->notification_observer_ = nil; } }
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc index b497ed36..0095ef48 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -3744,7 +3744,8 @@ active_app_id_ = app_id; // Manifest updates must occur as the first navigation after a webapp is // installed, otherwise the throttle is tripped. - ASSERT_FALSE(provider()->manifest_update_manager().IsUpdateConsumed(app_id)); + ASSERT_FALSE(provider()->manifest_update_manager().IsUpdateConsumed( + app_id, base::Time::Now())); ASSERT_FALSE( provider()->manifest_update_manager().IsUpdateCommandPending(app_id)); NavigateTabbedBrowserToSite(app_url_with_manifest_param,
diff --git a/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.cc b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.cc index e19cb94..5e22f12 100644 --- a/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.cc +++ b/chrome/browser/ui/webui/ash/multidevice_internals/multidevice_internals_phone_hub_handler.cc
@@ -92,8 +92,10 @@ int user_id = app_metadata_dict->FindInt("userId").value_or(0); return phonehub::Notification::AppMetadata( - visible_app_name, *package_name, icon, /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/false, user_id, + visible_app_name, *package_name, /* color_icon= */ icon, + /* monochrome_icon_mask= */ absl::nullopt, + /* icon_color= */ absl::nullopt, + /* icon_is_monochrome= */ false, user_id, phonehub::proto::AppStreamabilityStatus::STREAMABLE); }
diff --git a/chrome/browser/ui/webui/ash/parent_access/parent_access_dialog.cc b/chrome/browser/ui/webui/ash/parent_access/parent_access_dialog.cc index 41b2805e..0693ae30 100644 --- a/chrome/browser/ui/webui/ash/parent_access/parent_access_dialog.cc +++ b/chrome/browser/ui/webui/ash/parent_access/parent_access_dialog.cc
@@ -124,6 +124,12 @@ CloseWithResult(std::move(result)); } +void ParentAccessDialog::SetDisabled() { + auto result = std::make_unique<ParentAccessDialog::Result>(); + result->status = ParentAccessDialog::Result::Status::kDisabled; + CloseWithResult(std::move(result)); +} + void ParentAccessDialog::SetError() { auto result = std::make_unique<ParentAccessDialog::Result>(); result->status = ParentAccessDialog::Result::Status::kError;
diff --git a/chrome/browser/ui/webui/ash/parent_access/parent_access_dialog.h b/chrome/browser/ui/webui/ash/parent_access/parent_access_dialog.h index 06999a7..6ad616ef 100644 --- a/chrome/browser/ui/webui/ash/parent_access/parent_access_dialog.h +++ b/chrome/browser/ui/webui/ash/parent_access/parent_access_dialog.h
@@ -29,6 +29,7 @@ kApproved, // The parent was verified and they approved. kDeclined, // The request was explicitly declined by the parent. kCanceled, // The request was canceled/dismissed by the parent. + kDisabled, // Making a request has been disabled by the parent. kError, // An error occurred while handling the request. }; Status status = Status::kCanceled; @@ -60,6 +61,7 @@ const base::Time& expire_timestamp) override; void SetDeclined() override; void SetCanceled() override; + void SetDisabled() override; void SetError() override; parent_access_ui::mojom::ParentAccessParams* GetParentAccessParamsForTest()
diff --git a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui.mojom b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui.mojom index 63e5ed8..a746e75b 100644 --- a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui.mojom +++ b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui.mojom
@@ -101,6 +101,7 @@ kApproved, kDeclined, kCanceled, + kDisabled, kError, };
diff --git a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_delegate.h b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_delegate.h index c01c60b..e0c9d6c 100644 --- a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_delegate.h +++ b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_delegate.h
@@ -31,6 +31,8 @@ virtual void SetDeclined() = 0; // Indicates to the delegate that the request was canceled. virtual void SetCanceled() = 0; + // Indicates to the delegate that making a request is disabled. + virtual void SetDisabled() = 0; // Indicates to the delegate that an error occurred. virtual void SetError() = 0; };
diff --git a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.cc b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.cc index 4c718766..804fc034 100644 --- a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.cc +++ b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.cc
@@ -188,6 +188,9 @@ } delegate_->SetError(); break; + case parent_access_ui::mojom::ParentAccessResult::kDisabled: + delegate_->SetDisabled(); + break; } std::move(callback).Run();
diff --git a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl_unittest.cc b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl_unittest.cc index 94b9c46..188e7e1 100644 --- a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl_unittest.cc +++ b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl_unittest.cc
@@ -51,6 +51,7 @@ MOCK_METHOD2(SetApproved, void(const std::string&, const base::Time&)); MOCK_METHOD0(SetDeclined, void()); MOCK_METHOD0(SetCanceled, void()); + MOCK_METHOD0(SetDisabled, void()); MOCK_METHOD0(SetError, void()); };
diff --git a/chrome/browser/ui/webui/ash/set_time_ui.cc b/chrome/browser/ui/webui/ash/set_time_ui.cc index 6a0d79b..5aa326a 100644 --- a/chrome/browser/ui/webui/ash/set_time_ui.cc +++ b/chrome/browser/ui/webui/ash/set_time_ui.cc
@@ -36,6 +36,7 @@ #include "services/network/public/mojom/content_security_policy.mojom.h" #include "ui/base/webui/web_ui_util.h" #include "ui/resources/grit/webui_resources.h" +#include "ui/webui/mojo_web_ui_controller.h" namespace ash { @@ -159,7 +160,7 @@ } // namespace -SetTimeUI::SetTimeUI(content::WebUI* web_ui) : WebDialogUI(web_ui) { +SetTimeUI::SetTimeUI(content::WebUI* web_ui) : MojoWebDialogUI(web_ui) { web_ui->AddMessageHandler(std::make_unique<SetTimeMessageHandler>()); // Set up the chrome://set-time source. @@ -200,4 +201,6 @@ SetTimeUI::~SetTimeUI() = default; +WEB_UI_CONTROLLER_TYPE_IMPL(SetTimeUI) + } // namespace ash
diff --git a/chrome/browser/ui/webui/ash/set_time_ui.h b/chrome/browser/ui/webui/ash/set_time_ui.h index 4c4b430d..5af3785 100644 --- a/chrome/browser/ui/webui/ash/set_time_ui.h +++ b/chrome/browser/ui/webui/ash/set_time_ui.h
@@ -9,6 +9,7 @@ #include "content/public/browser/webui_config.h" #include "content/public/common/url_constants.h" #include "ui/web_dialogs/web_dialog_ui.h" +#include "ui/webui/mojo_web_ui_controller.h" namespace ash { @@ -23,7 +24,7 @@ }; // The WebUI for chrome://set-time. -class SetTimeUI : public ui::WebDialogUI { +class SetTimeUI : public ui::MojoWebDialogUI { public: explicit SetTimeUI(content::WebUI* web_ui); @@ -31,6 +32,9 @@ SetTimeUI& operator=(const SetTimeUI&) = delete; ~SetTimeUI() override; + + private: + WEB_UI_CONTROLLER_TYPE_DECL(); }; } // namespace ash
diff --git a/chrome/browser/ui/webui/settings/ash/accessibility_handler.cc b/chrome/browser/ui/webui/settings/ash/accessibility_handler.cc index 49c7baee..df10109 100644 --- a/chrome/browser/ui/webui/settings/ash/accessibility_handler.cc +++ b/chrome/browser/ui/webui/settings/ash/accessibility_handler.cc
@@ -91,6 +91,11 @@ "showChromeVoxTutorial", base::BindRepeating(&AccessibilityHandler::HandleShowChromeVoxTutorial, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "updateBluetoothBrailleDisplayAddress", + base::BindRepeating( + &AccessibilityHandler::HandleUpdateBluetoothBrailleDisplayAddress, + base::Unretained(this))); } void AccessibilityHandler::HandleShowBrowserAppearanceSettings( @@ -155,6 +160,13 @@ AccessibilityManager::Get()->ShowChromeVoxTutorial(); } +void AccessibilityHandler::HandleUpdateBluetoothBrailleDisplayAddress( + const base::Value::List& args) { + CHECK_EQ(1U, args.size()); + const std::string address = args[0].GetString(); + AccessibilityManager::Get()->UpdateBluetoothBrailleDisplayAddress(address); +} + void AccessibilityHandler::OpenExtensionOptionsPage(const char extension_id[]) { const extensions::Extension* extension = extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
diff --git a/chrome/browser/ui/webui/settings/ash/accessibility_handler.h b/chrome/browser/ui/webui/settings/ash/accessibility_handler.h index e8d8fca5..1288f7e 100644 --- a/chrome/browser/ui/webui/settings/ash/accessibility_handler.h +++ b/chrome/browser/ui/webui/settings/ash/accessibility_handler.h
@@ -42,6 +42,8 @@ void HandleShowChromeVoxTutorial(const base::Value::List& args); void HandleShowSelectToSpeakSettings(const base::Value::List& args); void HandleSetStartupSoundEnabled(const base::Value::List& args); + void HandleUpdateBluetoothBrailleDisplayAddress( + const base::Value::List& args); void OpenExtensionOptionsPage(const char extension_id[]);
diff --git a/chrome/browser/ui/webui/settings/ash/accessibility_section.cc b/chrome/browser/ui/webui/settings/ash/accessibility_section.cc index e7c107f..5ab81754 100644 --- a/chrome/browser/ui/webui/settings/ash/accessibility_section.cc +++ b/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
@@ -602,6 +602,18 @@ {"chromeVoxBrailleWordWrap", IDS_SETTINGS_CHROMEVOX_BRAILLE_WORD_WRAP}, {"chromeVoxMenuBrailleCommands", IDS_SETTINGS_CHROMEVOX_MENU_BRAILLE_COMMANDS}, + {"chromeVoxBluetoothBrailleDisplayConnect", + IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECT}, + {"chromeVoxBluetoothBrailleDisplayDisconnect", + IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_DISCONNECT}, + {"chromeVoxBluetoothBrailleDisplayConnecting", + IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_CONNECTING}, + {"chromeVoxBluetoothBrailleDisplayForget", + IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_FORGET}, + {"chromeVoxBluetoothBrailleDisplayPincodeLabel", + IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_PINCODE_LABEL}, + {"chromeVoxBluetoothBrailleDisplaySelectLabel", + IDS_SETTINGS_CHROMEVOX_BLUETOOTH_BRAILLE_DISPLAY_SELECT_LABEL}, {"chromeVoxVirtualBrailleDisplay", IDS_SETTINGS_CHROMEVOX_VIRTUAL_BRAILLE_DISPLAY}, {"chromeVoxVirtualBrailleDisplayDetails", @@ -627,6 +639,10 @@ IDS_SETTINGS_CHROMEVOX_MENU_ENABLE_BRAILLE_LOGGING}, {"chromeVoxEnableEventStreamLogging", IDS_SETTINGS_CHROMEVOX_MENU_ENABLE_EVENT_STREAM_LOGGING}, + {"chromeVoxBrailleTableDescription", + IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_DESCRIPTION}, + {"chromeVoxBrailleTable6Dot", IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_6_DOT}, + {"chromeVoxBrailleTable8Dot", IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_8_DOT}, {"chromeVoxTutorialLabel", IDS_SETTINGS_CHROMEVOX_TUTORIAL_LABEL}, {"clickOnStopDescription", IDS_SETTINGS_CLICK_ON_STOP_DESCRIPTION}, {"clickOnStopLabel", IDS_SETTINGS_CLICK_ON_STOP_LABEL},
diff --git a/chrome/browser/ui/webui/settings/ash/main_section.cc b/chrome/browser/ui/webui/settings/ash/main_section.cc index a4928f8..35887bca2 100644 --- a/chrome/browser/ui/webui/settings/ash/main_section.cc +++ b/chrome/browser/ui/webui/settings/ash/main_section.cc
@@ -146,6 +146,7 @@ {"menuButtonLabel", IDS_SETTINGS_MENU_BUTTON_LABEL}, {"moreActions", IDS_SETTINGS_MORE_ACTIONS}, {"ok", IDS_OK}, + {"opensInNewTab", IDS_OS_SETTINGS_OPENS_IN_NEW_TAB_A11Y_LABEL}, {"restart", IDS_SETTINGS_RESTART}, {"save", IDS_SAVE}, {"searchResultBubbleText", IDS_SEARCH_RESULT_BUBBLE_TEXT},
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index c4de4ae..2d591f20 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -22,7 +22,7 @@ #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/file_system_access/chrome_file_system_access_permission_context.h" -#include "chrome/browser/net/cert_verifier_configuration.h" +#include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/obsolete_system/obsolete_system.h" #include "chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h" #include "chrome/browser/preloading/preloading_features.h" @@ -1866,8 +1866,7 @@ html_source->AddBoolean( "showChromeRootStoreCertificates", #if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - GetChromeCertVerifierServiceParams(/*local_state=*/nullptr) - ->use_chrome_root_store + SystemNetworkContextManager::GetInstance()->IsUsingChromeRootStore() #else true #endif
diff --git a/chrome/browser/ui/webui/side_panel/companion/OWNERS b/chrome/browser/ui/webui/side_panel/companion/OWNERS index b6d1ce7..6f04bca 100644 --- a/chrome/browser/ui/webui/side_panel/companion/OWNERS +++ b/chrome/browser/ui/webui/side_panel/companion/OWNERS
@@ -1,4 +1,4 @@ -file://components/lens/OWNERS +file://chrome/browser/companion/OWNERS per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc index 6524f88..7866851c 100644 --- a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc +++ b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc
@@ -52,7 +52,7 @@ if (!IsUserPermittedToSharePageInfoWithCompanion(GetProfile()->GetPrefs())) { return; } - NotifyURLChanged(); + NotifyURLChanged(/*is_full_reload=*/false); } void CompanionPageHandler::ShowUI() { @@ -70,7 +70,7 @@ helper->SetCompanionPageHandler(weak_ptr_factory_.GetWeakPtr()); std::string initial_text_query = helper->GetTextQuery(); if (initial_text_query.empty()) { - NotifyURLChanged(); + NotifyURLChanged(/*is_full_reload=*/true); } else { OnSearchTextQuery(initial_text_query); } @@ -86,13 +86,19 @@ } GURL companion_url = url_builder_->BuildCompanionURL(page_url, query); - page_->OnURLChanged(companion_url); + page_->LoadCompanionPage(companion_url); } -void CompanionPageHandler::NotifyURLChanged() { - GURL companion_url = - url_builder_->BuildCompanionURL(web_contents()->GetVisibleURL()); - page_->OnURLChanged(companion_url); +void CompanionPageHandler::NotifyURLChanged(bool is_full_reload) { + if (is_full_reload) { + GURL companion_url = + url_builder_->BuildCompanionURL(web_contents()->GetVisibleURL()); + page_->LoadCompanionPage(companion_url); + } else { + auto companion_update_proto = url_builder_->BuildCompanionUrlParamProto( + web_contents()->GetVisibleURL()); + page_->UpdateCompanionPage(companion_update_proto); + } } void CompanionPageHandler::OnPromoAction( @@ -119,6 +125,11 @@ #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) } +void CompanionPageHandler::OnExpsOptInStatusAvailable(bool is_exps_opted_in) { + auto* pref_service = GetProfile()->GetPrefs(); + pref_service->SetBoolean(kExpsOptInStatusGrantedPref, is_exps_opted_in); +} + void CompanionPageHandler::EnableMsbb(bool enable_msbb) { auto* consent_service = UnifiedConsentServiceFactory::GetForProfile(GetProfile());
diff --git a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.h b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.h index 7771935f..9cec2a0 100644 --- a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.h +++ b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.h
@@ -7,6 +7,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/companion/core/constants.h" #include "chrome/browser/companion/core/mojom/companion.mojom.h" #include "chrome/browser/companion/core/msbb_delegate.h" #include "components/lens/buildflags.h" @@ -46,6 +47,7 @@ void OnPromoAction(side_panel::mojom::PromoType promo_type, side_panel::mojom::PromoAction promo_action) override; void OnRegionSearchClicked() override; + void OnExpsOptInStatusAvailable(bool is_exps_opted_in) override; // content::WebContentsObserver: void PrimaryPageChanged(content::Page& page) override; @@ -58,9 +60,12 @@ // MsbbDelegate overrides. void EnableMsbb(bool enable_msbb) override; - // Notifies the companion page of the visible URL when the active tab has - // changed or when the primary page has changed on the active tab. - void NotifyURLChanged(); + // Notifies the companion side panel about the URL of the main frame. Based on + // the call site, either does a full reload of the side panel or does a + // postmessage() update. Reload is done during initial load of the side panel, + // and context menu initiated navigations, while postmessage() is used for + // subsequent navigations on the main frame. + void NotifyURLChanged(bool is_full_reload); // Get the current browser associated with the WebUI. Browser* GetBrowser();
diff --git a/chrome/browser/web_applications/commands/manifest_update_check_command.cc b/chrome/browser/web_applications/commands/manifest_update_check_command.cc index e4c6f530..3ea803a8 100644 --- a/chrome/browser/web_applications/commands/manifest_update_check_command.cc +++ b/chrome/browser/web_applications/commands/manifest_update_check_command.cc
@@ -8,6 +8,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/web_applications/callback_utils.h" +#include "chrome/browser/web_applications/manifest_update_manager.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_registrar.h" @@ -21,12 +22,14 @@ ManifestUpdateCheckCommand::ManifestUpdateCheckCommand( const GURL& url, const AppId& app_id, + base::Time check_time, base::WeakPtr<content::WebContents> web_contents, CompletedCallback callback, std::unique_ptr<WebAppDataRetriever> data_retriever) : WebAppCommandTemplate<AppLock>("ManifestUpdateCheckCommand"), url_(url), app_id_(app_id), + check_time_(check_time), completed_callback_(std::move(callback)), lock_description_(app_id), web_contents_(web_contents), @@ -336,6 +339,18 @@ return IdentityUpdateDecision::kSilentlyAllow; } + // Web apps that were installed by sync but have generated icons get a window + // of time where they can "fix" themselves silently to use the site provided + // icons. + constexpr base::TimeDelta kSyncGeneratedIconFixWindowDuration = base::Days(7); + if (base::FeatureList::IsEnabled(features::kWebAppSyncGeneratedIconFix) && + web_app.is_generated_icon() && + web_app.latest_install_source() == webapps::WebappInstallSource::SYNC && + check_time_ < + (web_app.install_time() + kSyncGeneratedIconFixWindowDuration)) { + return IdentityUpdateDecision::kSilentlyAllow; + } + if (CanShowIdentityUpdateConfirmationDialog(lock_->registrar(), web_app) && base::FeatureList::IsEnabled(features::kPwaUpdateDialogForIcon)) { return IdentityUpdateDecision::kGetUserConfirmation;
diff --git a/chrome/browser/web_applications/commands/manifest_update_check_command.h b/chrome/browser/web_applications/commands/manifest_update_check_command.h index 5a0e3d0..25b185117 100644 --- a/chrome/browser/web_applications/commands/manifest_update_check_command.h +++ b/chrome/browser/web_applications/commands/manifest_update_check_command.h
@@ -9,6 +9,7 @@ #include "base/functional/callback_forward.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "base/values.h" #include "chrome/browser/web_applications/commands/web_app_command.h" #include "chrome/browser/web_applications/locks/app_lock.h" @@ -54,6 +55,7 @@ ManifestUpdateCheckCommand( const GURL& url, const AppId& app_id, + base::Time check_time, base::WeakPtr<content::WebContents> web_contents, CompletedCallback callback, std::unique_ptr<WebAppDataRetriever> data_retriever); @@ -129,6 +131,7 @@ // Manifest update check request parameters. const GURL url_; const AppId app_id_; + base::Time check_time_; CompletedCallback completed_callback_; // Resources and helpers used to fetch manifest data.
diff --git a/chrome/browser/web_applications/commands/manifest_update_check_command_unittest.cc b/chrome/browser/web_applications/commands/manifest_update_check_command_unittest.cc index 6a6c816..dd404cab 100644 --- a/chrome/browser/web_applications/commands/manifest_update_check_command_unittest.cc +++ b/chrome/browser/web_applications/commands/manifest_update_check_command_unittest.cc
@@ -362,7 +362,7 @@ RunResult output_result; provider().command_manager().ScheduleCommand( std::make_unique<ManifestUpdateCheckCommand>( - url, app_id, web_contents()->GetWeakPtr(), + url, app_id, base::Time::Now(), web_contents()->GetWeakPtr(), base::BindLambdaForTesting( [&](ManifestUpdateCheckResult check_result, absl::optional<WebAppInstallInfo> new_install_info) {
diff --git a/chrome/browser/web_applications/manifest_update_manager.cc b/chrome/browser/web_applications/manifest_update_manager.cc index c8f5119c..21fe568 100644 --- a/chrome/browser/web_applications/manifest_update_manager.cc +++ b/chrome/browser/web_applications/manifest_update_manager.cc
@@ -201,14 +201,18 @@ return; } - if (!MaybeConsumeUpdateCheck(url.DeprecatedGetOriginAsURL(), *app_id)) { + base::Time check_time = + time_override_for_testing_.value_or(base::Time::Now()); + + if (!MaybeConsumeUpdateCheck(url.DeprecatedGetOriginAsURL(), *app_id, + check_time)) { NotifyResult(url, *app_id, ManifestUpdateResult::kThrottled); return; } auto load_observer = std::make_unique<PreUpdateWebContentsObserver>( base::BindOnce(&ManifestUpdateManager::StartManifestCheckAfterPageLoad, - weak_factory_.GetWeakPtr(), *app_id, + weak_factory_.GetWeakPtr(), *app_id, check_time, web_contents->GetWeakPtr()), web_contents, hang_update_checks_for_testing_); @@ -226,6 +230,7 @@ void ManifestUpdateManager::StartManifestCheckAfterPageLoad( const AppId& app_id, + base::Time check_time, base::WeakPtr<content::WebContents> web_contents) { auto update_stage_it = update_stages_.find(app_id); DCHECK(update_stage_it != update_stages_.end()); @@ -251,7 +256,7 @@ std::move(load_finished_callback_).Run(); command_scheduler_->ScheduleManifestUpdateCheck( - url, app_id, web_contents, + url, app_id, check_time, web_contents, base::BindOnce(&ManifestUpdateManager::OnManifestCheckAwaitAppWindowClose, weak_factory_.GetWeakPtr(), web_contents, url, app_id)); } @@ -340,11 +345,11 @@ weak_factory_.GetWeakPtr())); } -bool ManifestUpdateManager::IsUpdateConsumed(const AppId& app_id) { +bool ManifestUpdateManager::IsUpdateConsumed(const AppId& app_id, + base::Time check_time) { absl::optional<base::Time> last_check_time = GetLastUpdateCheckTime(app_id); - base::Time now = time_override_for_testing_.value_or(base::Time::Now()); if (last_check_time.has_value() && - now < *last_check_time + kDelayBetweenChecks && + check_time < *last_check_time + kDelayBetweenChecks && !base::CommandLine::ForCurrentProcess()->HasSwitch( kDisableManifestUpdateThrottle)) { return true; @@ -376,12 +381,13 @@ // Throttling updates to at most once per day is consistent with Android. // See |UPDATE_INTERVAL| in WebappDataStorage.java. bool ManifestUpdateManager::MaybeConsumeUpdateCheck(const GURL& origin, - const AppId& app_id) { - if (IsUpdateConsumed(app_id)) + const AppId& app_id, + base::Time check_time) { + if (IsUpdateConsumed(app_id, check_time)) { return false; + } - base::Time now = time_override_for_testing_.value_or(base::Time::Now()); - SetLastUpdateCheckTime(origin, app_id, now); + SetLastUpdateCheckTime(origin, app_id, check_time); return true; }
diff --git a/chrome/browser/web_applications/manifest_update_manager.h b/chrome/browser/web_applications/manifest_update_manager.h index fa07984c..3cbb547 100644 --- a/chrome/browser/web_applications/manifest_update_manager.h +++ b/chrome/browser/web_applications/manifest_update_manager.h
@@ -96,7 +96,7 @@ void MaybeUpdate(const GURL& url, const absl::optional<AppId>& app_id, content::WebContents* web_contents); - bool IsUpdateConsumed(const AppId& app_id); + bool IsUpdateConsumed(const AppId& app_id, base::Time check_time); bool IsUpdateCommandPending(const AppId& app_id); // WebAppInstallManagerObserver: @@ -156,6 +156,7 @@ void StartManifestCheckAfterPageLoad( const AppId& app_id, + base::Time check_time, base::WeakPtr<content::WebContents> web_contents); void OnManifestCheckAwaitAppWindowClose( @@ -172,7 +173,9 @@ std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive, WebAppInstallInfo install_info); - bool MaybeConsumeUpdateCheck(const GURL& origin, const AppId& app_id); + bool MaybeConsumeUpdateCheck(const GURL& origin, + const AppId& app_id, + base::Time check_time); absl::optional<base::Time> GetLastUpdateCheckTime(const AppId& app_id) const; void SetLastUpdateCheckTime(const GURL& origin, const AppId& app_id,
diff --git a/chrome/browser/web_applications/web_app_command_scheduler.cc b/chrome/browser/web_applications/web_app_command_scheduler.cc index 1a4cce2..81949af 100644 --- a/chrome/browser/web_applications/web_app_command_scheduler.cc +++ b/chrome/browser/web_applications/web_app_command_scheduler.cc
@@ -247,6 +247,7 @@ void WebAppCommandScheduler::ScheduleManifestUpdateCheck( const GURL& url, const AppId& app_id, + base::Time check_time, base::WeakPtr<content::WebContents> contents, ManifestUpdateCheckCommand::CompletedCallback callback, const base::Location& location) { @@ -260,7 +261,7 @@ provider_->command_manager().ScheduleCommand( std::make_unique<ManifestUpdateCheckCommand>( - url, app_id, contents, std::move(callback), + url, app_id, check_time, contents, std::move(callback), std::make_unique<WebAppDataRetriever>()), location); }
diff --git a/chrome/browser/web_applications/web_app_command_scheduler.h b/chrome/browser/web_applications/web_app_command_scheduler.h index 840cd86..646e43d 100644 --- a/chrome/browser/web_applications/web_app_command_scheduler.h +++ b/chrome/browser/web_applications/web_app_command_scheduler.h
@@ -10,6 +10,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/raw_ref.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "chrome/browser/web_applications/commands/fetch_installability_for_chrome_management.h" #include "chrome/browser/web_applications/commands/manifest_update_check_command.h" #include "chrome/browser/web_applications/commands/manifest_update_finalize_command.h" @@ -136,6 +137,7 @@ void ScheduleManifestUpdateCheck( const GURL& url, const AppId& app_id, + base::Time check_time, base::WeakPtr<content::WebContents> contents, ManifestUpdateCheckCommand::CompletedCallback callback, const base::Location& location = FROM_HERE);
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 2245bba..3233f16a 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1681329517-4ba99e4c3e347b573e9491ea16d30d2d166d1a89.profdata +chrome-mac-arm-main-1681343974-c505acca0eb8e50d56370215187eb440b3cb01cd.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 2024a64e..aad18798 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1681311484-397fac25a38d4dc5ecb7da6d32b014e79d9a2ed0.profdata +chrome-win32-main-1681333180-dceb0c169b66545c2c80a056eb77ad3053927ae2.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 9443417..69db130 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1681311484-9edf151da433b32ad878f18460ab562b19e699ac.profdata +chrome-win64-main-1681333180-514b86a7d287c1ffd986630fffc776d452007759.profdata
diff --git a/chrome/common/extensions/api/accessibility_private.json b/chrome/common/extensions/api/accessibility_private.json index b89cf8f..24b1954 100644 --- a/chrome/common/extensions/api/accessibility_private.json +++ b/chrome/common/extensions/api/accessibility_private.json
@@ -234,7 +234,7 @@ { "id": "AccessibilityFeature", "type": "string", - "enum": [ "googleTtsLanguagePacks", "dictationContextChecking", "chromevoxTabsDeprecation"], + "enum": [ "googleTtsLanguagePacks", "dictationContextChecking", "chromevoxTabsDeprecation", "chromevoxSettingsMigration"], "description": "Subset of accessibility features." }, {
diff --git a/chrome/common/media/cdm_registration.cc b/chrome/common/media/cdm_registration.cc index 1fa0e6b..9de0d996 100644 --- a/chrome/common/media/cdm_registration.cc +++ b/chrome/common/media/cdm_registration.cc
@@ -248,6 +248,10 @@ switches::kLacrosEnablePlatformHevc)) { capability.video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); } +#elif BUILDFLAG(IS_CHROMEOS_ASH) + if (base::FeatureList::IsEnabled(media::kPlatformHEVCDecoderSupport)) { + capability.video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); + } #else capability.video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); #endif // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index b30f8ad..5324dbae 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -6628,6 +6628,7 @@ "../browser/android/bookmarks/partner_bookmarks_shim_unittest.cc", "../browser/android/chrome_backup_agent_unittest.cc", "../browser/android/compositor/layer/tab_layer_unittest.cc", + "../browser/android/compositor/tab_content_manager_unittest.cc", "../browser/android/customtabs/detached_resource_request_unittest.cc", "../browser/android/customtabs/tab_interaction_recorder_android_unittest.cc", "../browser/android/explore_sites/block_site_task_unittest.cc", @@ -6750,6 +6751,7 @@ "//chrome/browser/reading_list/android:unit_tests", "//chrome/browser/share", "//chrome/browser/thumbnail:unit_tests", + "//chrome/browser/thumbnail/cc:features", "//chrome/browser/touch_to_fill/payments/android:public", "//chrome/services/media_gallery_util:unit_tests", "//components/back_forward_cache",
diff --git a/chrome/test/data/webui/chromeos/parent_access/parent_access_browsertest.js b/chrome/test/data/webui/chromeos/parent_access/parent_access_browsertest.js index c4fd7b59..7539599 100644 --- a/chrome/test/data/webui/chromeos/parent_access/parent_access_browsertest.js +++ b/chrome/test/data/webui/chromeos/parent_access/parent_access_browsertest.js
@@ -98,6 +98,24 @@ .ParentAccessCallbackReceivedFnCalled); }); +var ParentAccessDisabledTest = class extends testing.Test { + /** @override */ + get browsePreload() { + return 'chrome://parent-access/test_loader.html?module=' + + 'chromeos/parent_access/parent_access_disabled_test.js&host=test'; + } + + /** @param {string} testName The name of the test to run. */ + runMochaTest(testName) { + runMochaTest(parent_access_disabled_tests.suiteName, testName); + } +} + +TEST_F('ParentAccessDisabledTest', 'TestOkButton', function() { + this.runMochaTest(parent_access_disabled_tests.TestNames.TestOkButton); +}); + + var ParentAccessUITest = class extends PolymerTest { /** @override */ get browsePreload() {
diff --git a/chrome/test/data/webui/chromeos/parent_access/parent_access_disabled_test.js b/chrome/test/data/webui/chromeos/parent_access/parent_access_disabled_test.js new file mode 100644 index 0000000..e34f861 --- /dev/null +++ b/chrome/test/data/webui/chromeos/parent_access/parent_access_disabled_test.js
@@ -0,0 +1,52 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://webui-test/mojo_webui_test_support.js'; +import 'chrome://parent-access/parent_access_disabled.js'; +import 'chrome://parent-access/strings.m.js'; + +import {ParentAccessResult} from 'chrome://parent-access/parent_access_ui.mojom-webui.js'; +import {setParentAccessUIHandlerForTest} from 'chrome://parent-access/parent_access_ui_handler.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; + +import {buildExtensionApprovalsParamsWithoutPermissions} from './parent_access_test_utils.js'; +import {TestParentAccessUIHandler} from './test_parent_access_ui_handler.js'; + +window.parent_access_disabled_tests = {}; +parent_access_disabled_tests.suiteName = 'ParentAccessDisabledTest'; + +/** @enum {string} */ +parent_access_disabled_tests.TestNames = { + TestOkButton: 'Test the approve button in the after flow', +}; + +suite(parent_access_disabled_tests.suiteName, function() { + setup(function() { + PolymerTest.clearBody(); + }); + + test(parent_access_disabled_tests.TestNames.TestOkButton, async () => { + // Set up the ParentAccessParams for the extension approvals flow. + const handler = new TestParentAccessUIHandler(); + handler.setParentAccessParams( + buildExtensionApprovalsParamsWithoutPermissions( + /**isDisabled=*/ true)); + setParentAccessUIHandlerForTest(handler); + + // Render ParentAccessDisabled element + const parentAccessDisabled = + document.createElement('parent-access-disabled'); + document.body.appendChild(parentAccessDisabled); + await flushTasks(); + + // Assert the disabled result is sent when the OK button is clicked. + assertEquals(handler.getCallCount('onParentAccessDone'), 0); + const okButton = + parentAccessAfter.shadowRoot.querySelector('.action-button'); + okButton.parentAccessDisabled(); + assertEquals(handler.getCallCount('onParentAccessDone'), 1); + assertEquals( + handler.getArgs('onParentAccessDone')[0], ParentAccessResult.kDisabled); + }); +});
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/fake_shortcut_provider_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/fake_shortcut_provider_test.ts index 629d4ad..abd5325 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/fake_shortcut_provider_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/fake_shortcut_provider_test.ts
@@ -6,7 +6,7 @@ import {fakeAcceleratorConfig, fakeLayoutInfo} from 'chrome://shortcut-customization/js/fake_data.js'; import {FakeShortcutProvider} from 'chrome://shortcut-customization/js/fake_shortcut_provider.js'; -import {Accelerator, AcceleratorConfigResult, AcceleratorSource, MojoAcceleratorConfig, MojoLayoutInfo} from 'chrome://shortcut-customization/js/shortcut_types.js'; +import {Accelerator, AcceleratorConfig, AcceleratorConfigResult, AcceleratorSource, MojoAcceleratorConfig, MojoLayoutInfo} from 'chrome://shortcut-customization/js/shortcut_types.js'; import {AcceleratorResultData, AcceleratorsUpdatedObserverRemote} from 'chrome://shortcut-customization/mojom-webui/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom-webui.js'; import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; @@ -70,7 +70,8 @@ test('ObserveAcceleratorsUpdated', () => { // Set the expected value to be returned when `onAcceleratorsUpdated()` is // called. - getProvider().setFakeAcceleratorsUpdated([fakeAcceleratorConfig]); + getProvider().setFakeAcceleratorsUpdated( + [fakeAcceleratorConfig as AcceleratorConfig]); const remote = new FakeAcceleratorsUpdatedRemote(); getProvider().addObserver(remote);
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.ts index e681f9c3..d394fc4 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.ts
@@ -20,7 +20,7 @@ import {FakeShortcutSearchHandler} from 'chrome://shortcut-customization/js/search/fake_shortcut_search_handler.js'; import {setShortcutSearchHandlerForTesting} from 'chrome://shortcut-customization/js/search/shortcut_search_handler.js'; import {ShortcutCustomizationAppElement} from 'chrome://shortcut-customization/js/shortcut_customization_app.js'; -import {AcceleratorCategory, AcceleratorConfigResult, AcceleratorState, AcceleratorSubcategory, LayoutInfo, Modifier} from 'chrome://shortcut-customization/js/shortcut_types.js'; +import {AcceleratorCategory, AcceleratorConfig, AcceleratorConfigResult, AcceleratorSource, AcceleratorState, AcceleratorSubcategory, AcceleratorType, LayoutInfo, LayoutStyle, Modifier, MojoLayoutInfo, TextAcceleratorPartType} from 'chrome://shortcut-customization/js/shortcut_types.js'; import {getSubcategoryNameStringId} from 'chrome://shortcut-customization/js/shortcut_utils.js'; import {AcceleratorResultData} from 'chrome://shortcut-customization/mojom-webui/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom-webui.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; @@ -67,12 +67,6 @@ provider = new FakeShortcutProvider(); provider.setFakeAcceleratorConfig(fakeAcceleratorConfig); provider.setFakeAcceleratorLayoutInfos(fakeLayoutInfo); - // `onAcceleratorsUpdated` gets observed as soon as the layouts are - // initialized. - // TODO(jimmyxgong): Triggering the observer in tests is difficult - // with how Mojo handles union types, we will need to refactor - // the fake data to support the correct Mojo types for OnAceleratorsUpdated. - provider.setFakeAcceleratorsUpdated([fakeAcceleratorConfig]); provider.setFakeHasLauncherButton(true); setShortcutProviderForTesting(provider); @@ -148,6 +142,11 @@ await flushTasks(); } + function triggerOnAcceleratorUpdated(): Promise<void> { + provider.triggerOnAcceleratorUpdated(); + return flushTasks(); + } + test('LoadFakeWindowsAndDesksPage', async () => { page = initShortcutCustomizationAppElement(); await flushTasks(); @@ -654,4 +653,81 @@ assertTrue(getLinkEl().href.includes('chrome://theme/colors.css')); }); + + test('TextAcceleratorLookupUpdatesCorrectly', async () => { + // Set up test to only have one shortcut. + const testLayoutInfo: MojoLayoutInfo[] = [ + { + category: AcceleratorCategory.kWindowsAndDesks, + subCategory: AcceleratorSubcategory.kWindows, + description: strToMojoString16('Go to windows 1 through 8'), + style: LayoutStyle.kText, + source: AcceleratorSource.kAmbient, + action: 1, + }, + ]; + provider.setFakeAcceleratorLayoutInfos(testLayoutInfo); + + page = initShortcutCustomizationAppElement(); + waitAfterNextRender(getPage()); + await flushTasks(); + + // This config is constructed to match the generated mojo type for an + // accelerator configuration. `layoutProperties` is an union type, so + // we do not have an undefined `standardAccelerator`. + const testAcceleratorConfig: AcceleratorConfig = { + [AcceleratorSource.kAmbient]: { + [1]: [{ + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + locked: true, + layoutProperties: { + textAccelerator: { + parts: [ + { + text: strToMojoString16('ctrl'), + type: TextAcceleratorPartType.kModifier, + }, + { + text: strToMojoString16(' + '), + type: TextAcceleratorPartType.kDelimiter, + }, + { + text: strToMojoString16('1 '), + type: TextAcceleratorPartType.kKey, + }, + { + text: strToMojoString16('through '), + type: TextAcceleratorPartType.kPlainText, + }, + { + text: strToMojoString16('8'), + type: TextAcceleratorPartType.kKey, + }, + ], + }, + }, + }], + }, + }; + + // Cycle tabs accelerator from kAmbient[1]. + const expectedCycleTabsAction = 1; + + let textLookup = getManager().getTextAcceleratorInfos( + AcceleratorSource.kAmbient, expectedCycleTabsAction); + assertEquals(1, textLookup.length); + + // Now simulate an update. + provider.setFakeAcceleratorsUpdated([testAcceleratorConfig]); + provider.setFakeHasLauncherButton(true); + await triggerOnAcceleratorUpdated(); + await provider.getAcceleratorsUpdatedPromiseForTesting(); + + // After a call to `onAcceleratorsUpdated` we should still expect to have + // one text accelerator. + textLookup = getManager().getTextAcceleratorInfos( + AcceleratorSource.kAmbient, expectedCycleTabsAction); + assertEquals(1, textLookup.length); + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 8a4e6489..8477214e 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -32,7 +32,6 @@ "cups_printer_page_tests.js", "cups_printer_test_utils.js", "date_time_page_tests.js", - "display_and_magnification_page_tests.js", "esim_install_error_dialog_test.js", "esim_remove_profile_dialog_test.js", "esim_rename_dialog_test.js", @@ -207,6 +206,7 @@ "os_a11y_page/audio_and_captions_page_tests.ts", "os_a11y_page/cursor_and_touchpad_page_tests.ts", + "os_a11y_page/display_and_magnification_page_tests.ts", "os_a11y_page/keyboard_and_text_input_page_tests.ts", "os_a11y_page/manage_accessibility_page_tests.ts", "os_a11y_page/os_a11y_page_tests.ts",
diff --git a/chrome/test/data/webui/settings/chromeos/chromevox_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/chromevox_subpage_tests.js index aa57d762..8927061 100644 --- a/chrome/test/data/webui/settings/chromeos/chromevox_subpage_tests.js +++ b/chrome/test/data/webui/settings/chromeos/chromevox_subpage_tests.js
@@ -73,6 +73,13 @@ type: ControlType.TOGGLE, }, { + id: 'brailleTableTypeDropdown', + prefKey: 'settings.a11y.chromevox.braille_table_type', + defaultValue: 'brailleTable8', + secondaryValue: 'brailleTable6', + type: ControlType.DROPDOWN, + }, + { id: 'brailleWordWrapToggle', prefKey: 'settings.a11y.chromevox.braille_word_wrap', defaultValue: true,
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/per_device_keyboard_remap_keys_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/per_device_keyboard_remap_keys_test.ts index f60b5576..eb76f3a 100644 --- a/chrome/test/data/webui/settings/chromeos/device_page/per_device_keyboard_remap_keys_test.ts +++ b/chrome/test/data/webui/settings/chromeos/device_page/per_device_keyboard_remap_keys_test.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {CrButtonElement, FakeInputDeviceSettingsProvider, fakeKeyboards, Keyboard, KeyboardRemapModifierKeyRowElement, MetaKey, ModifierKey, Router, routes, setInputDeviceSettingsProviderForTesting, SettingsPerDeviceKeyboardRemapKeysElement} from 'chrome://os-settings/chromeos/os_settings.js'; +import {FakeInputDeviceSettingsProvider, fakeKeyboards, Keyboard, KeyboardRemapModifierKeyRowElement, MetaKey, ModifierKey, Router, routes, setInputDeviceSettingsProviderForTesting, SettingsPerDeviceKeyboardRemapKeysElement} from 'chrome://os-settings/chromeos/os_settings.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; @@ -171,11 +171,7 @@ * Verify that the restore defaults button will restore the remapping keys. */ test('keyboard remap subpage restore defaults', async () => { - // Click the restore defaults button. - const restoreButton = page.shadowRoot!.querySelector<CrButtonElement>( - '#restoreDefaultsButton'); - assert(restoreButton); - restoreButton.click(); + page.restoreDefaults(); await flushTasks(); // The keyboard has "Command" as metaKey, so ctrl key should be restored to @@ -215,7 +211,7 @@ assert(page.get('keyboard')); await flushTasks(); - restoreButton.click(); + page.restoreDefaults(); await flushTasks(); // The keyboard has "Launcher" as metaKey, meta key should be restored to // default metaKey mappings. @@ -257,10 +253,7 @@ test('Update keyboard settings', async () => { assertTrue(page.get('isInitialized')); // Set the modifier remappings to default stage. - const restoreButton = page.shadowRoot!.querySelector<CrButtonElement>( - '#restoreDefaultsButton'); - assert(restoreButton); - restoreButton.click(); + page.restoreDefaults(); checkPrefsSetToDefault(); // Change several key remappings in the page.
diff --git a/chrome/test/data/webui/settings/chromeos/display_and_magnification_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_a11y_page/display_and_magnification_page_tests.ts similarity index 66% rename from chrome/test/data/webui/settings/chromeos/display_and_magnification_page_tests.js rename to chrome/test/data/webui/settings/chromeos/os_a11y_page/display_and_magnification_page_tests.ts index 692ab60..df9206b65 100644 --- a/chrome/test/data/webui/settings/chromeos/display_and_magnification_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_a11y_page/display_and_magnification_page_tests.ts
@@ -4,32 +4,31 @@ import 'chrome://os-settings/chromeos/lazy_load.js'; +import {SettingsDisplayAndMagnificationElement} from 'chrome://os-settings/chromeos/lazy_load.js'; import {Router, routes} from 'chrome://os-settings/chromeos/os_settings.js'; +import {assert} from 'chrome://resources/js/assert_ts.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {waitAfterNextRender, waitBeforeNextRender} from 'chrome://webui-test/polymer_test_util.js'; +import {assertEquals, assertFalse, assertNotEquals} from 'chrome://webui-test/chai_assert.js'; +import {waitBeforeNextRender} from 'chrome://webui-test/polymer_test_util.js'; import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js'; -import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; - -suite('DisplayAndMagnificationPageTests', function() { - let page = null; +suite('settings-display-and-magnification-page', () => { + let page: SettingsDisplayAndMagnificationElement; function initPage() { page = document.createElement('settings-display-and-magnification-page'); document.body.appendChild(page); } - setup(function() { - PolymerTest.clearBody(); + setup(() => { loadTimeData.overrideValues( {isAccessibilityOSSettingsVisibilityEnabled: true}); Router.getInstance().navigateTo(routes.A11Y_DISPLAY_AND_MAGNIFICATION); }); - teardown(function() { - if (page) { - page.remove(); - } + teardown(() => { + page.remove(); Router.getInstance().resetRouteForTesting(); }); @@ -43,13 +42,14 @@ flush(); const router = Router.getInstance(); - const subpageButton = page.shadowRoot.querySelector(selector); - assertTrue(!!subpageButton); + const subpageButton = + page.shadowRoot!.querySelector<HTMLElement>(selector); + assert(subpageButton); subpageButton.click(); assertEquals(route, router.currentRoute); assertNotEquals( - subpageButton, page.shadowRoot.activeElement, + subpageButton, page.shadowRoot!.activeElement, `${selector} should not be focused`); const popStateEventPromise = eventToPromise('popstate', window); @@ -60,12 +60,12 @@ assertEquals( routes.A11Y_DISPLAY_AND_MAGNIFICATION, router.currentRoute); assertEquals( - subpageButton, page.shadowRoot.activeElement, + subpageButton, page.shadowRoot!.activeElement, `${selector} should be focused`); }); }); - test('no subpages are available in kiosk mode', function() { + test('no subpages are available in kiosk mode', () => { loadTimeData.overrideValues({ isKioskModeActive: true, showTabletModeShelfNavigationButtonsSettings: true, @@ -73,7 +73,7 @@ initPage(); flush(); - const subpageLinks = page.root.querySelectorAll('cr-link-row'); + const subpageLinks = page.shadowRoot!.querySelectorAll('cr-link-row'); subpageLinks.forEach(subpageLink => assertFalse(isVisible(subpageLink))); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index c114899..8b02bc8 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -299,10 +299,6 @@ 'device_page/per_device_pointing_stick_subsection_test.js', {enabled: ['ash::features::kInputDeviceSettingsSplit']}, ], - [ - 'DisplayAndMagnificationPage', - 'display_and_magnification_page_tests.js', - ], ['EsimInstallErrorDialog', 'esim_install_error_dialog_test.js'], ['EsimRemoveProfileDialog', 'esim_remove_profile_dialog_test.js'], ['EsimRenameDialog', 'esim_rename_dialog_test.js'], @@ -431,6 +427,10 @@ 'os_a11y_page/cursor_and_touchpad_page_tests.js', ], [ + 'OsA11yPageDisplayAndMagnificationPage', + 'os_a11y_page/display_and_magnification_page_tests.js', + ], + [ 'OsA11yPageKeyboardAndTextInputPage', 'os_a11y_page/keyboard_and_text_input_page_tests.js', ],
diff --git a/chrome/test/data/webui/settings/chromeos/test_chromevox_subpage_browser_proxy.js b/chrome/test/data/webui/settings/chromeos/test_chromevox_subpage_browser_proxy.js index dd40b88..adc484da 100644 --- a/chrome/test/data/webui/settings/chromeos/test_chromevox_subpage_browser_proxy.js +++ b/chrome/test/data/webui/settings/chromeos/test_chromevox_subpage_browser_proxy.js
@@ -11,6 +11,16 @@ super([ 'getAllTtsVoiceData', 'refreshTtsVoices', + 'addDeviceAddedListener', + 'removeDeviceAddedListener', + 'addDeviceChangedListener', + 'removeDeviceChangedListener', + 'addDeviceRemovedListener', + 'removeDeviceRemovedListener', + 'addPairingListener', + 'removePairingListener', + 'startDiscovery', + 'stopDiscovery', ]); } @@ -53,4 +63,35 @@ refreshTtsVoices() { this.methodCalled('refreshTtsVoices'); } + + addDeviceAddedListener() { + this.methodCalled('addDeviceAddedListener'); + } + removeDeviceAddedListener() { + this.methodCalled('removeDeviceAddedListener'); + } + addDeviceChangedListener() { + this.methodCalled('addDeviceChangedListener'); + } + removeDeviceChangedListener() { + this.methodCalled('removeDeviceChangedListener'); + } + addDeviceRemovedListener() { + this.methodCalled('addDeviceRemovedListener'); + } + removeDeviceRemovedListener() { + this.methodCalled('removeDeviceRemovedListener'); + } + addPairingListener() { + this.methodCalled('addPairingListener'); + } + removePairingListener() { + this.methodCalled('removePairingListener'); + } + startDiscovery() { + this.methodCalled('startDiscovery'); + } + stopDiscovery() { + this.methodCalled('stopDiscovery'); + } }
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index 853e2e7e1..aca5e381 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -709,6 +709,8 @@ "test/integration_tests.cc", "test/integration_tests_impl.cc", "test/integration_tests_impl.h", + "test/request_matcher.cc", + "test/request_matcher.h", "test/server.cc", "test/server.h", "test_scope.h",
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index a5df9da..f8f35188 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -28,6 +28,7 @@ #include "chrome/updater/service_proxy_factory.h" #include "chrome/updater/test/integration_test_commands.h" #include "chrome/updater/test/integration_tests_impl.h" +#include "chrome/updater/test/request_matcher.h" #include "chrome/updater/test/server.h" #include "chrome/updater/test_scope.h" #include "chrome/updater/update_service.h" @@ -63,24 +64,22 @@ void ExpectNoUpdateSequence(ScopedServer* test_server, const std::string& app_id) { - test_server->ExpectOnce( - {base::BindRepeating( - RequestMatcherRegex, - base::StringPrintf(R"(.*"appid":"%s".*)", app_id.c_str()))}, - base::StringPrintf(")]}'\n" - R"({"response":{)" - R"( "protocol":"3.1",)" - R"( "app":[)" - R"( {)" - R"( "appid":"%s",)" - R"( "status":"ok",)" - R"( "updatecheck":{)" - R"( "status":"noupdate")" - R"( })" - R"( })" - R"( ])" - R"(}})", - app_id.c_str())); + test_server->ExpectOnce({request::GetContentMatcher(base::StringPrintf( + R"(.*"appid":"%s".*)", app_id.c_str()))}, + base::StringPrintf(")]}'\n" + R"({"response":{)" + R"( "protocol":"3.1",)" + R"( "app":[)" + R"( {)" + R"( "appid":"%s",)" + R"( "status":"ok",)" + R"( "updatecheck":{)" + R"( "status":"noupdate")" + R"( })" + R"( })" + R"( ])" + R"(}})", + app_id.c_str())); } #endif // BUILDFLAG(IS_WIN) || !defined(COMPONENT_BUILD) @@ -532,8 +531,7 @@ // This instance is now qualified and should activate itself and check itself // for updates on the next check. test_server.ExpectOnce( - {base::BindRepeating(RequestMatcherRegex, - base::StringPrintf(".*%s.*", kUpdaterAppId))}, + {request::GetContentMatcher(base::StringPrintf(".*%s.*", kUpdaterAppId))}, ")]}'\n"); ASSERT_NO_FATAL_FAILURE(RunWake(0)); ASSERT_TRUE(WaitForUpdaterExit()); @@ -599,8 +597,7 @@ ASSERT_NO_FATAL_FAILURE(ExpectActive("test1")); ASSERT_NO_FATAL_FAILURE(ExpectNotActive("test2")); test_server.ExpectOnce( - {base::BindRepeating( - RequestMatcherRegex, + {request::GetContentMatcher( R"(.*"appid":"test1","enabled":true,"ping":{"a":-2,.*)")}, R"()]}')" "\n" @@ -1044,16 +1041,14 @@ R"(}})", app_id.c_str()); test_server.ExpectOnce( - {base::BindRepeating( - RequestMatcherRegex, + {request::GetContentMatcher( R"(.*"updatecheck":{"sameversionupdate":true},"version":"0.1"}.*)")}, response); ASSERT_NO_FATAL_FAILURE(CallServiceUpdate( app_id, "", UpdateService::PolicySameVersionUpdate::kAllowed)); test_server.ExpectOnce( - {base::BindRepeating(RequestMatcherRegex, - R"(.*"updatecheck":{},"version":"0.1"}.*)")}, + {request::GetContentMatcher(R"(.*"updatecheck":{},"version":"0.1"}.*)")}, response); ASSERT_NO_FATAL_FAILURE(CallServiceUpdate( app_id, "", UpdateService::PolicySameVersionUpdate::kNotAllowed)); @@ -1088,11 +1083,9 @@ app_id.c_str()); test_server.ExpectOnce( - {base::BindRepeating( - RequestMatcherRegex, - base::StringPrintf( - R"(.*"data":\[{"index":"%s","name":"install"}],.*)", - install_data_index.c_str()))}, + {request::GetContentMatcher(base::StringPrintf( + R"(.*"data":\[{"index":"%s","name":"install"}],.*)", + install_data_index.c_str()))}, response); ASSERT_NO_FATAL_FAILURE( @@ -1160,15 +1153,15 @@ const std::string response; - // TODO(crbug.com/1430233): Add a predicate to verify the crash report + // TODO(crbug.com/1430233): Add a matcher to verify the crash report // contents. This is blocked by crbug.com/1430878. test_server.ExpectOnce( - {GetRequestPathPredicate( + {request::GetPathMatcher( base::StringPrintf(R"(%s\?product=%s&version=%s&guid=.*)", test_server.crash_report_path().c_str(), CRASH_PRODUCT_NAME, kUpdaterVersion)), - GetRequestHeaderPredicate("User-Agent", R"(Crashpad/.*)"), - GetRequestHeaderPredicate( + request::GetHeaderMatcher("User-Agent", R"(Crashpad/.*)"), + request::GetHeaderMatcher( "Content-Type", R"(multipart/form-data; boundary=---MultipartBoundary.*---)")}, response);
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc index fa077bf..bc5d6b6 100644 --- a/chrome/updater/test/integration_tests_impl.cc +++ b/chrome/updater/test/integration_tests_impl.cc
@@ -52,6 +52,7 @@ #include "chrome/updater/prefs.h" #include "chrome/updater/registration_data.h" #include "chrome/updater/service_proxy_factory.h" +#include "chrome/updater/test/request_matcher.h" #include "chrome/updater/test/server.h" #include "chrome/updater/update_service.h" #include "chrome/updater/updater_branding.h" @@ -147,78 +148,6 @@ GetHashHex(update_file).c_str()); } -ScopedServer::RequestMatcherPredicate GetScopePredicate(UpdaterScope scope) { - return base::BindLambdaForTesting( - [scope](const net::test_server::HttpRequest& request) { - const bool is_match = [&scope, &request]() { - const absl::optional<base::Value> doc = - base::JSONReader::Read(request.content); - if (!doc || !doc->is_dict()) { - return false; - } - const base::Value::Dict* object_request = - doc->GetDict().FindDict("request"); - if (!object_request) { - return false; - } - absl::optional<bool> ismachine = - object_request->FindBool("ismachine"); - if (!ismachine.has_value()) { - return false; - } - switch (scope) { - case UpdaterScope::kSystem: - return *ismachine; - case UpdaterScope::kUser: - return !*ismachine; - } - }(); - if (!is_match) { - ADD_FAILURE() << R"(Request does not match "ismachine": )" - << request.content; - } - return is_match; - }); -} - -ScopedServer::RequestMatcherPredicate MatchAppPriority( - const std::string& app_id, - UpdateService::Priority priority) { - return base::BindLambdaForTesting( - [app_id, priority](const net::test_server::HttpRequest& request) { - const bool is_match = [&app_id, priority, &request]() { - const absl::optional<base::Value> doc = - base::JSONReader::Read(request.content); - if (!doc || !doc->is_dict()) { - return false; - } - const base::Value::List* app_list = - doc->GetDict().FindListByDottedPath("request.app"); - if (!app_list) { - return false; - } - for (const base::Value& app : *app_list) { - if (const auto* dict = app.GetIfDict()) { - if (const auto* appid = dict->FindString("appid"); - *appid == app_id) { - if (const auto* install_source = - dict->FindString("installsource")) { - return (*install_source == "ondemand") == - (priority == UpdateService::Priority::kForeground); - } - } - } - } - return priority != UpdateService::Priority::kForeground; - }(); - if (!is_match) { - ADD_FAILURE() << R"(Request does not match "appid", "priority: )" - << request.content; - } - return is_match; - }); -} - void RunUpdaterWithSwitch(const base::Version& version, UpdaterScope scope, const std::string& command, @@ -252,28 +181,26 @@ // First request: update check. test_server->ExpectOnce( - {GetRequestPathPredicate(test_server->update_path()), - base::BindRepeating( - RequestMatcherRegex, + {request::GetPathMatcher(test_server->update_path()), + request::GetContentMatcher( base::StringPrintf(R"(.*"appid":"%s".*)", app_id.c_str())), - GetScopePredicate(scope), MatchAppPriority(app_id, priority)}, + request::GetScopeMatcher(scope), + request::GetAppPriorityMatcher(app_id, priority)}, GetUpdateResponse(app_id, "", test_server->update_url().spec(), to_version, crx_path, kDoNothingCRXRun, {})); // Second request: event ping with an error because the update check response // is ignored by the client: // {errorCategory::kService, ServiceError::CHECK_FOR_UPDATE_ONLY} - test_server->ExpectOnce( - {GetRequestPathPredicate(test_server->update_path()), - base::BindRepeating( - RequestMatcherRegex, - base::StringPrintf(R"(.*"errorcat":4,"errorcode":4,)" - R"("eventresult":0,"eventtype":%d,)" - R"("nextversion":"%s","previousversion":"%s".*)", - event_type, to_version.GetString().c_str(), - from_version.GetString().c_str())), - GetScopePredicate(scope)}, - ")]}'\n"); + test_server->ExpectOnce({request::GetPathMatcher(test_server->update_path()), + request::GetContentMatcher(base::StringPrintf( + R"(.*"errorcat":4,"errorcode":4,)" + R"("eventresult":0,"eventtype":%d,)" + R"("nextversion":"%s","previousversion":"%s".*)", + event_type, to_version.GetString().c_str(), + from_version.GetString().c_str())), + request::GetScopeMatcher(scope)}, + ")]}'\n"); } void ExpectUpdateSequence(UpdaterScope scope, @@ -292,21 +219,19 @@ // First request: update check. test_server->ExpectOnce( - {GetRequestPathPredicate(test_server->update_path()), - base::BindRepeating( - RequestMatcherRegex, + {request::GetPathMatcher(test_server->update_path()), + request::GetContentMatcher( base::StringPrintf(R"(.*"appid":"%s".*)", app_id.c_str())), - base::BindRepeating( - RequestMatcherRegex, - base::StringPrintf( - R"(.*%s)", - !install_data_index.empty() - ? base::StringPrintf( - R"("data":\[{"index":"%s","name":"install"}],.*)", - install_data_index.c_str()) - .c_str() - : "")), - GetScopePredicate(scope), MatchAppPriority(app_id, priority)}, + request::GetContentMatcher(base::StringPrintf( + R"(.*%s)", + !install_data_index.empty() + ? base::StringPrintf( + R"("data":\[{"index":"%s","name":"install"}],.*)", + install_data_index.c_str()) + .c_str() + : "")), + request::GetScopeMatcher(scope), + request::GetAppPriorityMatcher(app_id, priority)}, GetUpdateResponse(app_id, install_data_index, test_server->update_url().spec(), to_version, crx_path, kDoNothingCRXRun, {})); @@ -314,64 +239,21 @@ // Second request: update download. std::string crx_bytes; base::ReadFileToString(crx_path, &crx_bytes); - test_server->ExpectOnce({base::BindRepeating(RequestMatcherRegex, "")}, - crx_bytes); + test_server->ExpectOnce({request::GetContentMatcher("")}, crx_bytes); // Third request: event ping. - test_server->ExpectOnce( - {GetRequestPathPredicate(test_server->update_path()), - base::BindRepeating( - RequestMatcherRegex, - base::StringPrintf(R"(.*"eventresult":1,"eventtype":%d,)" - R"("nextversion":"%s","previousversion":"%s".*)", - event_type, to_version.GetString().c_str(), - from_version.GetString().c_str())), - GetScopePredicate(scope)}, - ")]}'\n"); + test_server->ExpectOnce({request::GetPathMatcher(test_server->update_path()), + request::GetContentMatcher(base::StringPrintf( + R"(.*"eventresult":1,"eventtype":%d,)" + R"("nextversion":"%s","previousversion":"%s".*)", + event_type, to_version.GetString().c_str(), + from_version.GetString().c_str())), + request::GetScopeMatcher(scope)}, + ")]}'\n"); } } // namespace -ScopedServer::RequestMatcherPredicate GetRequestPathPredicate( - const std::string& expected_path_regex) { - return base::BindLambdaForTesting( - [expected_path_regex](const net::test_server::HttpRequest& request) { - if (!re2::RE2::FullMatch(request.relative_url, expected_path_regex)) { - ADD_FAILURE() << "Request path [" << request.relative_url - << "], did not match expected path regex [" - << expected_path_regex << "]."; - return false; - } - return true; - }); -} - -ScopedServer::RequestMatcherPredicate GetRequestHeaderPredicate( - const std::string& header_name, - const std::string& expected_header_regex) { - return base::BindLambdaForTesting( - [header_name, - expected_header_regex](const net::test_server::HttpRequest& request) { - re2::RE2::Options opt; - opt.set_case_sensitive(false); - net::test_server::HttpRequest::HeaderMap::const_iterator it = - request.headers.find(header_name); - if (it == request.headers.end()) { - ADD_FAILURE() << "Request header '" << header_name - << "' not found, expected regex " - << expected_header_regex; - return false; - } else if (!re2::RE2::FullMatch(it->second, - re2::RE2(expected_header_regex, opt))) { - ADD_FAILURE() << "Request header '" << it->first << "' = '" - << it->second << "', did not match expected regex " - << expected_header_regex; - return false; - } - return true; - }); -} - void ExitTestMode(UpdaterScope scope) { DeleteFileAndEmptyParentDirectories(GetOverrideFilePath(scope)); } @@ -716,26 +598,11 @@ ASSERT_TRUE(succeeded); } -bool RequestMatcherRegex(const std::string& request_body_regex, - const net::test_server::HttpRequest& request) { - re2::RE2::Options opt; - opt.set_case_sensitive(false); - if (!re2::RE2::PartialMatch(request.content, - re2::RE2(request_body_regex, opt))) { - VLOG(0) << "Request content match failed."; - ADD_FAILURE() << "Request with body: " << request.content - << " did not match expected regex " << request_body_regex; - return false; - } - return true; -} - void ExpectUninstallPing(UpdaterScope scope, ScopedServer* test_server) { - test_server->ExpectOnce( - {GetRequestPathPredicate(test_server->update_path()), - base::BindRepeating(RequestMatcherRegex, R"(.*"eventtype":4.*)"), - GetScopePredicate(scope)}, - ")]}'\n"); + test_server->ExpectOnce({request::GetPathMatcher(test_server->update_path()), + request::GetContentMatcher(R"(.*"eventtype":4.*)"), + request::GetScopeMatcher(scope)}, + ")]}'\n"); } void ExpectSelfUpdateSequence(UpdaterScope scope, ScopedServer* test_server) { @@ -746,11 +613,10 @@ // First request: update check. test_server->ExpectOnce( - {GetRequestPathPredicate(test_server->update_path()), - base::BindRepeating( - RequestMatcherRegex, + {request::GetPathMatcher(test_server->update_path()), + request::GetContentMatcher( base::StringPrintf(R"(.*"appid":"%s".*)", kUpdaterAppId)), - GetScopePredicate(scope)}, + request::GetScopeMatcher(scope)}, GetUpdateResponse( kUpdaterAppId, "", test_server->update_url().spec(), base::Version(kUpdaterVersion), crx_path, kSelfUpdateCRXRun, @@ -762,19 +628,16 @@ // Second request: update download. std::string crx_bytes; base::ReadFileToString(crx_path, &crx_bytes); - test_server->ExpectOnce({base::BindRepeating(RequestMatcherRegex, "")}, - crx_bytes); + test_server->ExpectOnce({request::GetContentMatcher("")}, crx_bytes); // Third request: event ping. - test_server->ExpectOnce( - {GetRequestPathPredicate(test_server->update_path()), - base::BindRepeating( - RequestMatcherRegex, - base::StringPrintf(R"(.*"eventresult":1,"eventtype":3,)" - R"("nextversion":"%s",.*)", - kUpdaterVersion)), - GetScopePredicate(scope)}, - ")]}'\n"); + test_server->ExpectOnce({request::GetPathMatcher(test_server->update_path()), + request::GetContentMatcher(base::StringPrintf( + R"(.*"eventresult":1,"eventtype":3,)" + R"("nextversion":"%s",.*)", + kUpdaterVersion)), + request::GetScopeMatcher(scope)}, + ")]}'\n"); } void ExpectUpdateCheckSequence(UpdaterScope scope,
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h index 624f5fc..7ed6c8d 100644 --- a/chrome/updater/test/integration_tests_impl.h +++ b/chrome/updater/test/integration_tests_impl.h
@@ -25,14 +25,6 @@ class Version; } // namespace base -namespace net { -namespace test_server { - -struct HttpRequest; - -} // namespace test_server -} // namespace net - namespace updater { enum class UpdaterScope; } // namespace updater @@ -200,17 +192,6 @@ [[nodiscard]] bool WaitForUpdaterExit(UpdaterScope scope); -// Returns a predicate which returns true if the `expected_path_regex` fully -// matches the request path. -[[nodiscard]] ScopedServer::RequestMatcherPredicate GetRequestPathPredicate( - const std::string& expected_path_regex); - -// Returns a predicate which returns true if the `expected_header_regex` fully -// matches the specified header in request. -[[nodiscard]] ScopedServer::RequestMatcherPredicate GetRequestHeaderPredicate( - const std::string& header_name, - const std::string& expected_header_regex); - #if BUILDFLAG(IS_WIN) void ExpectInterfacesRegistered(UpdaterScope scope); void ExpectMarshalInterfaceSucceeds(UpdaterScope scope); @@ -243,11 +224,6 @@ // links, or dot dot. int CountDirectoryFiles(const base::FilePath& dir); -// Returns true if the `request_body_regex` partially matches the request -// content. -[[nodiscard]] bool RequestMatcherRegex(const std::string& request_body_regex, - const net::test_server::HttpRequest&); - void ExpectSelfUpdateSequence(UpdaterScope scope, ScopedServer* test_server); void ExpectUninstallPing(UpdaterScope scope, ScopedServer* test_server);
diff --git a/chrome/updater/test/request_matcher.cc b/chrome/updater/test/request_matcher.cc new file mode 100644 index 0000000..e6d81a7 --- /dev/null +++ b/chrome/updater/test/request_matcher.cc
@@ -0,0 +1,152 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/updater/test/request_matcher.h" + +#include <string> +#include <utility> + +#include "base/json/json_reader.h" +#include "base/logging.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/test/bind.h" +#include "base/values.h" +#include "chrome/updater/update_service.h" +#include "chrome/updater/updater_scope.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/re2/src/re2/re2.h" + +namespace updater::test::request { + +Matcher GetPathMatcher(const std::string& expected_path_regex) { + return base::BindLambdaForTesting( + [expected_path_regex](const net::test_server::HttpRequest& request) { + if (!re2::RE2::FullMatch(request.relative_url, expected_path_regex)) { + ADD_FAILURE() << "Request path [" << request.relative_url + << "], did not match expected path regex [" + << expected_path_regex << "]."; + return false; + } + return true; + }); +} + +Matcher GetHeaderMatcher(const std::string& header_name, + const std::string& expected_header_regex) { + return base::BindLambdaForTesting( + [header_name, + expected_header_regex](const net::test_server::HttpRequest& request) { + re2::RE2::Options opt; + opt.set_case_sensitive(false); + net::test_server::HttpRequest::HeaderMap::const_iterator it = + request.headers.find(header_name); + if (it == request.headers.end()) { + ADD_FAILURE() << "Request header '" << header_name + << "' not found, expected regex " + << expected_header_regex; + return false; + } else if (!re2::RE2::FullMatch(it->second, + re2::RE2(expected_header_regex, opt))) { + ADD_FAILURE() << "Request header [" << it->first << " = '" + << it->second << "], did not match expected regex [" + << expected_header_regex << "]"; + return false; + } + return true; + }); +} + +Matcher GetContentMatcher(const std::string& expected_content_regex) { + return base::BindLambdaForTesting( + [expected_content_regex](const net::test_server::HttpRequest& request) { + re2::RE2::Options opt; + opt.set_case_sensitive(false); + if (!re2::RE2::PartialMatch(request.content, + re2::RE2(expected_content_regex, opt))) { + ADD_FAILURE() << "Request content match failed. body: [" + << request.content + << "] did not match expected regex: [" + << expected_content_regex << "]"; + return false; + } + return true; + }); +} + +Matcher GetScopeMatcher(UpdaterScope scope) { + return base::BindLambdaForTesting( + [scope](const net::test_server::HttpRequest& request) { + const bool is_match = [&scope, &request]() { + const absl::optional<base::Value> doc = + base::JSONReader::Read(request.content); + if (!doc || !doc->is_dict()) { + return false; + } + const base::Value::Dict* object_request = + doc->GetDict().FindDict("request"); + if (!object_request) { + return false; + } + absl::optional<bool> ismachine = + object_request->FindBool("ismachine"); + if (!ismachine.has_value()) { + return false; + } + switch (scope) { + case UpdaterScope::kSystem: + return *ismachine; + case UpdaterScope::kUser: + return !*ismachine; + } + }(); + if (!is_match) { + ADD_FAILURE() << R"(Request does not match "ismachine": )" + << request.content; + } + return is_match; + }); +} + +Matcher GetAppPriorityMatcher(const std::string& app_id, + UpdateService::Priority priority) { + return base::BindLambdaForTesting( + [app_id, priority](const net::test_server::HttpRequest& request) { + const bool is_match = [&app_id, priority, &request]() { + const absl::optional<base::Value> doc = + base::JSONReader::Read(request.content); + if (!doc || !doc->is_dict()) { + return false; + } + const base::Value::List* app_list = + doc->GetDict().FindListByDottedPath("request.app"); + if (!app_list) { + return false; + } + for (const base::Value& app : *app_list) { + if (const auto* dict = app.GetIfDict()) { + if (const auto* appid = dict->FindString("appid"); + *appid == app_id) { + if (const auto* install_source = + dict->FindString("installsource")) { + return (*install_source == "ondemand") == + (priority == UpdateService::Priority::kForeground); + } + } + } + } + return priority != UpdateService::Priority::kForeground; + }(); + if (!is_match) { + ADD_FAILURE() << R"(Request does not match "appid", "priority: )" + << request.content; + } + return is_match; + }); +} + +} // namespace updater::test::request
diff --git a/chrome/updater/test/request_matcher.h b/chrome/updater/test/request_matcher.h new file mode 100644 index 0000000..d14c3e6 --- /dev/null +++ b/chrome/updater/test/request_matcher.h
@@ -0,0 +1,59 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_UPDATER_TEST_REQUEST_MATCHER_H_ +#define CHROME_UPDATER_TEST_REQUEST_MATCHER_H_ + +#include <list> +#include <string> + +#include "base/functional/callback_forward.h" +#include "base/memory/scoped_refptr.h" +#include "chrome/updater/update_service.h" +#include "chrome/updater/updater_scope.h" +#include "net/test/embedded_test_server/embedded_test_server.h" + +namespace net::test_server { + +struct HttpRequest; + +} // namespace net::test_server + +namespace updater::test::request { + +// Defines a generic matcher to match expectations for a request. +using Matcher = + base::RepeatingCallback<bool(const net::test_server::HttpRequest&)>; + +// Defines a group of matchers which all must pass in order to match a request. +// This allows for combining several matchers when matching a single request. +using MatcherGroup = std::list<Matcher>; + +// Returns a matcher which returns true if the `expected_path_regex` fully +// matches the request path. +[[nodiscard]] Matcher GetPathMatcher(const std::string& expected_path_regex); + +// Returns a matcher which returns true if the `expected_header_regex` fully +// matches the specified header in request. +[[nodiscard]] Matcher GetHeaderMatcher( + const std::string& header_name, + const std::string& expected_header_regex); + +// Returns a matcher which returns true if the `expected_content_regex` +// partially matches the request content. +[[nodiscard]] Matcher GetContentMatcher( + const std::string& expected_content_regex); + +// Returns a matcher which returns true if request scope is same as the given +// value. +[[nodiscard]] Matcher GetScopeMatcher(UpdaterScope scope); + +// Returns a matcher which returns true if the app priority in request matches +// the given value. +[[nodiscard]] Matcher GetAppPriorityMatcher(const std::string& app_id, + UpdateService::Priority priority); + +} // namespace updater::test::request + +#endif // CHROME_UPDATER_TEST_REQUEST_MATCHER_H_
diff --git a/chrome/updater/test/server.cc b/chrome/updater/test/server.cc index 21b94a4..19bdb1c 100644 --- a/chrome/updater/test/server.cc +++ b/chrome/updater/test/server.cc
@@ -79,19 +79,19 @@ } ScopedServer::~ScopedServer() { - for (const auto& request_matcher : request_matchers_) { + for (const auto& request_matcher_group : request_matcher_groups_) { // Forces `request_matcher` to log to help debugging, unless the - // predicate matches the empty request. + // matcher matches the empty request. ADD_FAILURE() << "Unmet expectation: "; - base::ranges::for_each(request_matcher, [](RequestMatcherPredicate pred) { - pred.Run(net::test_server::HttpRequest()); + base::ranges::for_each(request_matcher_group, [](request::Matcher matcher) { + matcher.Run(net::test_server::HttpRequest()); }); } } -void ScopedServer::ExpectOnce(RequestMatcher request_matcher, +void ScopedServer::ExpectOnce(request::MatcherGroup request_matcher_group, const std::string& response_body) { - request_matchers_.push_back(std::move(request_matcher)); + request_matcher_groups_.push_back(std::move(request_matcher_group)); response_bodies_.push_back(response_body); } @@ -100,15 +100,15 @@ VLOG(0) << "Handle request at path:" << request.relative_url; VLOG(3) << SerializeRequest(request); auto response = std::make_unique<net::test_server::BasicHttpResponse>(); - if (request_matchers_.empty()) { + if (request_matcher_groups_.empty()) { VLOG(0) << "Unexpected request."; ADD_FAILURE() << "Unexpected " << SerializeRequest(request); response->set_code(net::HTTP_INTERNAL_SERVER_ERROR); return response; } - if (!base::ranges::all_of(request_matchers_.front(), - [&request](RequestMatcherPredicate pred) { - return pred.Run(request); + if (!base::ranges::all_of(request_matcher_groups_.front(), + [&request](request::Matcher matcher) { + return matcher.Run(request); })) { VLOG(0) << "Request did not match."; ADD_FAILURE() << "Unmatched " << SerializeRequest(request); @@ -117,7 +117,7 @@ } response->set_code(net::HTTP_OK); response->set_content(response_bodies_.front()); - request_matchers_.pop_front(); + request_matcher_groups_.pop_front(); response_bodies_.pop_front(); return response; }
diff --git a/chrome/updater/test/server.h b/chrome/updater/test/server.h index 833e702..c21b2b1b 100644 --- a/chrome/updater/test/server.h +++ b/chrome/updater/test/server.h
@@ -11,6 +11,7 @@ #include "base/functional/callback_forward.h" #include "base/memory/scoped_refptr.h" +#include "chrome/updater/test/request_matcher.h" #include "net/test/embedded_test_server/embedded_test_server.h" class GURL; @@ -31,15 +32,6 @@ class ScopedServer { public: - // Defines a generic predicate to match expectations for a request. - using RequestMatcherPredicate = - base::RepeatingCallback<bool(const net::test_server::HttpRequest&)>; - - // Defines a sequence of predicates which all must pass in order to match - // a request. This allows for combining several predicates when matching a - // single request. - using RequestMatcher = std::list<RequestMatcherPredicate>; - // Creates and starts a scoped server. Sets up the updater to communicate // with it. Multiple scoped servers are not allowed. explicit ScopedServer( @@ -53,14 +45,14 @@ ScopedServer& operator=(const ScopedServer&) = delete; // Registers an expected request with the server. Requests must match the - // expectation defined by applying all individual request matching predicates - // composing the `request_matcher` in the order the expectations were set. + // expectation defined by applying all individual request matchers composing + // the `request_matcher_group` in the order the expectations were set. // The server replies with an HTTP 200 and `response_body` to an expected // request. It replies with HTTP 500 and fails the test if a request does - // not match the next expected `request_matcher`, or if there are no more - // expected requests. If the server does not receive every expected request, - // it will fail the test during destruction. - void ExpectOnce(RequestMatcher request_matcher, + // not match the next expected `request_matcher_group`, or if there are no + // more expected requests. If the server does not receive every expected + // request, it will fail the test during destruction. + void ExpectOnce(request::MatcherGroup request_matcher_group, const std::string& response_body); std::string update_path() const { return "/update"; } @@ -82,7 +74,7 @@ std::unique_ptr<net::test_server::EmbeddedTestServer> test_server_; net::test_server::EmbeddedTestServerHandle test_server_handle_; - std::list<RequestMatcher> request_matchers_; + std::list<request::MatcherGroup> request_matcher_groups_; std::list<std::string> response_bodies_; scoped_refptr<IntegrationTestCommands> integration_test_commands_; };
diff --git a/chromeos/ash/components/drivefs/drivefs_pin_manager.h b/chromeos/ash/components/drivefs/drivefs_pin_manager.h index c89e9d9..25b1a939 100644 --- a/chromeos/ash/components/drivefs/drivefs_pin_manager.h +++ b/chromeos/ash/components/drivefs/drivefs_pin_manager.h
@@ -447,6 +447,7 @@ FRIEND_TEST_ALL_PREFIXES(DriveFsPinManagerTest, NotifyProgress); FRIEND_TEST_ALL_PREFIXES(DriveFsPinManagerTest, OnSearchResult); FRIEND_TEST_ALL_PREFIXES(DriveFsPinManagerTest, HandleQueryItem); + FRIEND_TEST_ALL_PREFIXES(DriveFsPinManagerTest, DropQuery); }; COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_DRIVEFS)
diff --git a/chromeos/ash/components/drivefs/drivefs_pin_manager_unittest.cc b/chromeos/ash/components/drivefs/drivefs_pin_manager_unittest.cc index 8ca184c1..016fa6b 100644 --- a/chromeos/ash/components/drivefs/drivefs_pin_manager_unittest.cc +++ b/chromeos/ash/components/drivefs/drivefs_pin_manager_unittest.cc
@@ -50,6 +50,7 @@ using mojom::ItemEventPtr; using mojom::QueryItem; using mojom::QueryItemPtr; +using mojom::QueryParameters; using mojom::SearchQuery; using mojom::SyncingStatus; using mojom::SyncingStatusPtr; @@ -59,6 +60,7 @@ using testing::AnyNumber; using testing::DoAll; using testing::Field; +using testing::Invoke; using testing::IsEmpty; using testing::Return; using testing::SizeIs; @@ -131,7 +133,7 @@ mojom::DriveFs* GetForwardingInterface() override { NOTREACHED_NORETURN(); } - MOCK_METHOD(void, OnStartSearchQuery, (const mojom::QueryParameters&)); + MOCK_METHOD(void, OnStartSearchQuery, (const QueryParameters&)); void StartSearchQuery(mojo::PendingReceiver<SearchQuery> query, const mojom::QueryParametersPtr query_params) override { @@ -929,7 +931,6 @@ EXPECT_THAT(manager.files_to_pin_, UnorderedElementsAre(Id(item.stable_id))); EXPECT_THAT(manager.files_to_track_, SizeIs(1)); - event.path = Path("/root/Path 3"); // Spurious events with no stable_id should be ignored (b/268419828). event.stable_id = 0; @@ -2282,6 +2283,33 @@ manager.Stop(); } +// Tests PinManager::OnNextPage() when a query is dropped before the response +// is received. +TEST_F(DriveFsPinManagerTest, DropQuery) { + PinManager manager(temp_dir_.GetPath(), &drivefs_); + + DCHECK_CALLED_ON_VALID_SEQUENCE(manager.sequence_checker_); + manager.progress_.stage = Stage::kListingFiles; + manager.progress_.max_active_queries = 2; + manager.progress_.active_queries = 2; + + EXPECT_CALL(drivefs_, OnGetNextPage(_)) + .WillOnce( + Invoke([&manager](absl::optional<vector<QueryItemPtr>>* const items) { + manager.Stop(); + *items = {}; + return FileError::FILE_ERROR_OK; + })); + + PinManager::Query query; + EXPECT_CALL(drivefs_, OnStartSearchQuery(_)).Times(1); + drivefs_.StartSearchQuery(query.BindNewPipeAndPassReceiver(), + QueryParameters::New()); + + manager.GetNextPage(Id(101), Path("/root/My Folder"), std::move(query)); + task_environment_.RunUntilIdle(); +} + // Tests PinManager::OnSearchResult() when a query finishes and there are still // other active queries. TEST_F(DriveFsPinManagerTest, OnSearchResult) {
diff --git a/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc b/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc index 2b67611a..f857da29 100644 --- a/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc +++ b/chromeos/ash/components/phonehub/app_stream_launcher_data_model_unittest.cc
@@ -147,17 +147,25 @@ TEST_F(AppStreamLauncherDataModelTest, AddAppToList) { std::vector<Notification::AppMetadata> apps_list; apps_list.emplace_back(Notification::AppMetadata( - u"GPay", "com.fakeapp1", gfx::Image(), absl::nullopt, true, 1, + u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1, proto::AppStreamabilityStatus::STREAMABLE)); apps_list.emplace_back(Notification::AppMetadata( - u"Gboard", "com.fakeapp2", gfx::Image(), absl::nullopt, true, 1, + u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1, proto::AppStreamabilityStatus::STREAMABLE)); SetAppList(apps_list); AddAppToList(Notification::AppMetadata( - u"added_app", "com.fakeapp3", gfx::Image(), absl::nullopt, true, 1, + u"added_app", "com.fakeapp3", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color*/ absl::nullopt, + /*icon_is_monochrome*/ true, /*user_id=*/1, proto::AppStreamabilityStatus::STREAMABLE)); AddAppToList(Notification::AppMetadata( - u"a_added_app", "com.fakeapp3", gfx::Image(), absl::nullopt, true, 1, + u"a_added_app", "com.fakeapp3", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color*/ absl::nullopt, + /*icon_is_monochrome*/ true, /*user_id=*/1, proto::AppStreamabilityStatus::STREAMABLE)); EXPECT_TRUE(IsObserverAppListChanged()); EXPECT_EQ(GetAppsList()->size(), 4u); @@ -175,10 +183,14 @@ TEST_F(AppStreamLauncherDataModelTest, RemoveAppFromList) { std::vector<Notification::AppMetadata> apps_list; apps_list.emplace_back(Notification::AppMetadata( - u"GPay", "com.fakeapp1", gfx::Image(), absl::nullopt, true, 1, + u"GPay", "com.fakeapp1", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1, proto::AppStreamabilityStatus::STREAMABLE)); apps_list.emplace_back(Notification::AppMetadata( - u"Gboard", "com.fakeapp2", gfx::Image(), absl::nullopt, true, 1, + u"Gboard", "com.fakeapp2", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color*/ absl::nullopt, /*icon_is_monochrome*/ true, /*user_id=*/1, proto::AppStreamabilityStatus::STREAMABLE)); SetAppList(apps_list); auto app_to_remove = proto::App();
diff --git a/chromeos/ash/components/phonehub/notification.cc b/chromeos/ash/components/phonehub/notification.cc index b169753..c2f56f5 100644 --- a/chromeos/ash/components/phonehub/notification.cc +++ b/chromeos/ash/components/phonehub/notification.cc
@@ -20,28 +20,33 @@ const char kPackageName[] = "package_name"; const char kUserId[] = "user_id"; const char kAppStreamabilityStatus[] = "app_streamability_status"; -const char kIcon[] = "icon"; +const char kColorIcon[] = "icon"; const char kIconColorR[] = "icon_color_r"; const char kIconColorG[] = "icon_color_g"; const char kIconColorB[] = "icon_color_b"; const char kIconIsMonochrome[] = "icon_is_monochrome"; +const char kMonochromeIconMask[] = "monochrome_icon_mask"; Notification::AppMetadata::AppMetadata( const std::u16string& visible_app_name, const std::string& package_name, - const gfx::Image& icon, + const gfx::Image& color_icon, + const absl::optional<gfx::Image>& monochrome_icon_mask, const absl::optional<SkColor> icon_color, bool icon_is_monochrome, int64_t user_id, proto::AppStreamabilityStatus app_streamability_status) : visible_app_name(visible_app_name), package_name(package_name), - icon(icon), + color_icon(color_icon), + monochrome_icon_mask(monochrome_icon_mask), icon_color(icon_color), icon_is_monochrome(icon_is_monochrome), user_id(user_id), app_streamability_status(app_streamability_status) {} +Notification::AppMetadata::~AppMetadata() = default; + Notification::AppMetadata::AppMetadata(const AppMetadata& other) = default; Notification::AppMetadata& Notification::AppMetadata::operator=( @@ -49,7 +54,7 @@ bool Notification::AppMetadata::operator==(const AppMetadata& other) const { return visible_app_name == other.visible_app_name && - package_name == other.package_name && icon == other.icon && + package_name == other.package_name && color_icon == other.color_icon && user_id == other.user_id; } @@ -58,13 +63,20 @@ } base::Value::Dict Notification::AppMetadata::ToValue() const { - scoped_refptr<base::RefCountedMemory> png_data = icon.As1xPNGBytes(); + scoped_refptr<base::RefCountedMemory> png_data = color_icon.As1xPNGBytes(); + scoped_refptr<base::RefCountedMemory> monochrome_mask_png_data; base::Value::Dict val; val.Set(kVisibleAppName, visible_app_name); val.Set(kPackageName, package_name); val.Set(kUserId, static_cast<double>(user_id)); - val.Set(kIcon, base::Base64Encode(*png_data)); + val.Set(kColorIcon, base::Base64Encode(*png_data)); + + if (monochrome_icon_mask.has_value()) { + monochrome_mask_png_data = monochrome_icon_mask.value().As1xPNGBytes(); + val.Set(kMonochromeIconMask, base::Base64Encode(*monochrome_mask_png_data)); + } + val.Set(kIconIsMonochrome, icon_is_monochrome); if (icon_color.has_value()) { val.Set(kIconColorR, static_cast<int>(SkColorGetR(*icon_color))); @@ -81,7 +93,11 @@ DCHECK(value.FindString(kVisibleAppName)); DCHECK(value.FindString(kPackageName)); DCHECK(value.FindDouble(kUserId)); - DCHECK(value.FindString(kIcon)); + DCHECK(value.FindString(kColorIcon)); + + if (value.contains(kMonochromeIconMask)) { + DCHECK(value.FindString(kMonochromeIconMask)); + } if (value.contains(kIconIsMonochrome)) { DCHECK(value.FindBool(kIconIsMonochrome)); @@ -106,14 +122,25 @@ base::UTF8ToUTF16(visible_app_name_value->GetString()); } - std::string icon_str; - base::Base64Decode(*(value.FindString(kIcon)), &icon_str); - gfx::Image decode_icon = gfx::Image::CreateFrom1xPNGBytes( - base::MakeRefCounted<base::RefCountedString>(std::move(icon_str))); + std::string color_icon_str; + base::Base64Decode(*(value.FindString(kColorIcon)), &color_icon_str); + gfx::Image decode_color_icon = gfx::Image::CreateFrom1xPNGBytes( + base::MakeRefCounted<base::RefCountedString>(std::move(color_icon_str))); + + absl::optional<gfx::Image> decode_monochrome_icon_mask = absl::nullopt; + std::string monochrome_icon_mask_str; + if (value.contains(kMonochromeIconMask)) { + base::Base64Decode(*(value.FindString(kMonochromeIconMask)), + &monochrome_icon_mask_str); + decode_monochrome_icon_mask = gfx::Image::CreateFrom1xPNGBytes( + base::MakeRefCounted<base::RefCountedString>( + std::move(monochrome_icon_mask_str))); + } return Notification::AppMetadata( visible_app_name_string_value, *(value.FindString(kPackageName)), - decode_icon, icon_color, icon_is_monochrome, *(value.FindDouble(kUserId)), + decode_color_icon, decode_monochrome_icon_mask, icon_color, + icon_is_monochrome, *(value.FindDouble(kUserId)), static_cast<proto::AppStreamabilityStatus>( value.FindInt(kAppStreamabilityStatus) .value_or(static_cast<int>(
diff --git a/chromeos/ash/components/phonehub/notification.h b/chromeos/ash/components/phonehub/notification.h index 910b59a7..73f6b01 100644 --- a/chromeos/ash/components/phonehub/notification.h +++ b/chromeos/ash/components/phonehub/notification.h
@@ -31,12 +31,14 @@ struct AppMetadata { AppMetadata(const std::u16string& visible_app_name, const std::string& package_name, - const gfx::Image& icon, + const gfx::Image& color_icon, + const absl::optional<gfx::Image>& monochrome_icon_mask, const absl::optional<SkColor> icon_color, bool icon_is_monochrome, int64_t user_id, proto::AppStreamabilityStatus app_streamability_status = proto::AppStreamabilityStatus::STREAMABLE); + ~AppMetadata(); AppMetadata(const AppMetadata& other); AppMetadata& operator=(const AppMetadata& other); @@ -48,7 +50,10 @@ std::u16string visible_app_name; std::string package_name; - gfx::Image icon; + // The |color_icon| is the icon with it's original color whereas the + // |monochrome_icon| is the icon with a monochrome or system theme mask. + gfx::Image color_icon; + absl::optional<gfx::Image> monochrome_icon_mask; // Color for a monochrome icon. Leave empty to use the system theme default. absl::optional<SkColor> icon_color; // Whether the icon image is just a mask used to generate a monochrome icon.
diff --git a/chromeos/ash/components/phonehub/notification_interaction_handler_impl_unittest.cc b/chromeos/ash/components/phonehub/notification_interaction_handler_impl_unittest.cc index 01e138f3..8b1675d 100644 --- a/chromeos/ash/components/phonehub/notification_interaction_handler_impl_unittest.cc +++ b/chromeos/ash/components/phonehub/notification_interaction_handler_impl_unittest.cc
@@ -10,8 +10,7 @@ #include "chromeos/ash/components/phonehub/notification_click_handler.h" #include "testing/gtest/include/gtest/gtest.h" -namespace ash { -namespace phonehub { +namespace ash::phonehub { namespace { @@ -95,7 +94,9 @@ const char expected_package_name[] = "com.fakeapp"; const int64_t expected_user_id = 1; auto expected_app_metadata = Notification::AppMetadata( - expected_app_visible_name, expected_package_name, gfx::Image(), + expected_app_visible_name, expected_package_name, + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, expected_user_id, proto::AppStreamabilityStatus::STREAMABLE); @@ -107,5 +108,4 @@ EXPECT_EQ(expected_user_id, GetUserId()); } -} // namespace phonehub -} // namespace ash +} // namespace ash::phonehub
diff --git a/chromeos/ash/components/phonehub/notification_manager_impl_unittest.cc b/chromeos/ash/components/phonehub/notification_manager_impl_unittest.cc index f134d7d..2c7f9037 100644 --- a/chromeos/ash/components/phonehub/notification_manager_impl_unittest.cc +++ b/chromeos/ash/components/phonehub/notification_manager_impl_unittest.cc
@@ -36,7 +36,7 @@ id, phonehub::Notification::AppMetadata( kAppName, kPackageName, - /*icon=*/gfx::Image(), + /*color_icon=*/gfx::Image(), /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, kUserId, proto::AppStreamabilityStatus::STREAMABLE),
diff --git a/chromeos/ash/components/phonehub/notification_processor.cc b/chromeos/ash/components/phonehub/notification_processor.cc index 23895fe..0ae8ce14 100644 --- a/chromeos/ash/components/phonehub/notification_processor.cc +++ b/chromeos/ash/components/phonehub/notification_processor.cc
@@ -85,7 +85,8 @@ } Notification CreateInternalNotification(const proto::Notification& proto, - const gfx::Image& icon, + const gfx::Image& color_icon, + const gfx::Image& monochrome_icon, const gfx::Image& shared_image, const gfx::Image& contact_image) { base::flat_map<Notification::ActionType, int64_t> action_id_map; @@ -152,22 +153,35 @@ bool icon_is_monochrome = IsMonochromeIconEnabled(proto); absl::optional<SkColor> icon_color = - icon_is_monochrome ? getMonochromeIconColor(proto, icon) : absl::nullopt; + icon_is_monochrome ? getMonochromeIconColor(proto, monochrome_icon) + : absl::nullopt; - return Notification(proto.id(), - Notification::AppMetadata( - base::UTF8ToUTF16(proto.origin_app().visible_name()), - proto.origin_app().package_name(), icon, icon_color, - icon_is_monochrome, proto.origin_app().user_id(), - proto.origin_app().app_streamability_status()), - base::Time::FromJsTime(proto.epoch_time_millis()), - GetNotificationImportanceFromProto(proto.importance()), - category, action_id_map, behavior, title, text_content, - opt_shared_image, opt_contact_image); + return Notification( + proto.id(), + Notification::AppMetadata( + base::UTF8ToUTF16(proto.origin_app().visible_name()), + proto.origin_app().package_name(), color_icon, monochrome_icon, + icon_color, icon_is_monochrome, proto.origin_app().user_id(), + proto.origin_app().app_streamability_status()), + base::Time::FromJsTime(proto.epoch_time_millis()), + GetNotificationImportanceFromProto(proto.importance()), category, + action_id_map, behavior, title, text_content, opt_shared_image, + opt_contact_image); } } // namespace +NotificationProcessor::NotificationImages::NotificationImages() = default; + +NotificationProcessor::NotificationImages::~NotificationImages() = default; + +NotificationProcessor::NotificationImages::NotificationImages( + const NotificationImages& other) = default; + +NotificationProcessor::NotificationImages& +NotificationProcessor::NotificationImages::operator=( + const NotificationImages& other) = default; + NotificationProcessor::DecodeImageRequestMetadata::DecodeImageRequestMetadata( int64_t notification_id, NotificationImageField image_field, @@ -212,13 +226,18 @@ processed_notification_protos.emplace_back(proto); + decode_image_requests.emplace_back(proto.id(), + NotificationImageField::kColorIcon, + proto.origin_app().icon()); + if (IsMonochromeIconEnabled(proto)) { decode_image_requests.emplace_back( - proto.id(), NotificationImageField::kIcon, + proto.id(), NotificationImageField::kMonochromeIcon, proto.origin_app().monochrome_icon_mask()); } else { decode_image_requests.emplace_back( - proto.id(), NotificationImageField::kIcon, proto.origin_app().icon()); + proto.id(), NotificationImageField::kMonochromeIcon, + proto.origin_app().icon()); } if (!proto.shared_image().empty()) { @@ -319,8 +338,11 @@ } switch (request.image_field) { - case NotificationImageField::kIcon: - it->second.icon = gfx::Image(image_skia); + case NotificationImageField::kColorIcon: + it->second.color_icon = gfx::Image(image_skia); + break; + case NotificationImageField::kMonochromeIcon: + it->second.monochrome_icon_mask = gfx::Image(image_skia); break; case NotificationImageField::kSharedImage: it->second.shared_image = gfx::Image(image_skia); @@ -343,8 +365,9 @@ NotificationImages notification_images = it->second; notifications.emplace(CreateInternalNotification( - proto, notification_images.icon, notification_images.shared_image, - notification_images.contact_image)); + proto, notification_images.color_icon, + notification_images.monochrome_icon_mask, + notification_images.shared_image, notification_images.contact_image)); } AddNotificationsAndProcessNextRequest(notifications);
diff --git a/chromeos/ash/components/phonehub/notification_processor.h b/chromeos/ash/components/phonehub/notification_processor.h index a8bcaaf..8d7c3ae 100644 --- a/chromeos/ash/components/phonehub/notification_processor.h +++ b/chromeos/ash/components/phonehub/notification_processor.h
@@ -16,8 +16,7 @@ #include "services/data_decoder/public/cpp/decode_image.h" #include "ui/gfx/image/image.h" -namespace ash { -namespace phonehub { +namespace ash::phonehub { using ::google::protobuf::RepeatedPtrField; @@ -59,16 +58,23 @@ // Used to track which image type is being processed. enum class NotificationImageField { - kIcon = 0, - kSharedImage = 1, - kContactImage = 2, + kColorIcon = 0, + kMonochromeIcon = 1, + kSharedImage = 2, + kContactImage = 3, }; // Each notification proto will be associated with one of these structs. - // |icon| will always be populated, but |shared_image| and |contact_image| may - // be empty. + // |color_icon| will always be populated, but |monochrome_icon|, + // |shared_image|, and |contact_image| may be empty. struct NotificationImages { - gfx::Image icon; + NotificationImages(); + ~NotificationImages(); + NotificationImages(const NotificationImages& other); + NotificationImages& operator=(const NotificationImages& other); + + gfx::Image color_icon; + gfx::Image monochrome_icon_mask; gfx::Image shared_image; gfx::Image contact_image; }; @@ -130,7 +136,6 @@ base::WeakPtrFactory<NotificationProcessor> weak_ptr_factory_{this}; }; -} // namespace phonehub -} // namespace ash +} // namespace ash::phonehub #endif // CHROMEOS_ASH_COMPONENTS_PHONEHUB_NOTIFICATION_PROCESSOR_H_
diff --git a/chromeos/ash/components/phonehub/notification_processor_unittest.cc b/chromeos/ash/components/phonehub/notification_processor_unittest.cc index 7cfcffb..602a30f 100644 --- a/chromeos/ash/components/phonehub/notification_processor_unittest.cc +++ b/chromeos/ash/components/phonehub/notification_processor_unittest.cc
@@ -285,15 +285,17 @@ std::vector<proto::Notification> first_set_of_notifications; // The icon should be an empty image as the decoder failed to decode the - // image. + // image to be used as both the color_icon and monochrome_icon_mask. first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( kNotificationIdA, kInlineReplyIdA, kIconDataA)); notification_processor()->AddNotifications(first_set_of_notifications); image_decoder_delegate()->RunNextCallback(SkBitmap()); + image_decoder_delegate()->RunNextCallback(SkBitmap()); const Notification* notification = fake_notification_manager()->GetNotification(kNotificationIdA); - EXPECT_TRUE(notification->app_metadata().icon.IsEmpty()); + EXPECT_TRUE(notification->app_metadata().color_icon.IsEmpty()); + EXPECT_TRUE(notification->app_metadata().monochrome_icon_mask.has_value()); EXPECT_FALSE(notification->shared_image().has_value()); EXPECT_FALSE(notification->contact_image().has_value()); } @@ -322,7 +324,7 @@ const Notification* notification = fake_notification_manager()->GetNotification(kNotificationIdA); - EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().color_icon, TestImage())); EXPECT_FALSE(notification->app_metadata().icon_color.has_value()); @@ -336,7 +338,7 @@ notification = fake_notification_manager()->GetNotification(kNotificationIdA); EXPECT_TRUE(notification->app_metadata().icon_is_monochrome); - EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().color_icon, TestImage())); EXPECT_FALSE(notification->app_metadata().icon_color.has_value()); @@ -350,7 +352,7 @@ notification = fake_notification_manager()->GetNotification(kNotificationIdA); EXPECT_TRUE(notification->app_metadata().icon_is_monochrome); - EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().color_icon, TestImage())); EXPECT_TRUE(notification->app_metadata().icon_color.has_value()); EXPECT_TRUE(*notification->app_metadata().icon_color == kIconColor); @@ -366,7 +368,7 @@ notification = fake_notification_manager()->GetNotification(kNotificationIdA); EXPECT_TRUE(notification->app_metadata().icon_is_monochrome); - EXPECT_TRUE(notification->app_metadata().icon.IsEmpty()); + EXPECT_TRUE(notification->app_metadata().color_icon.IsEmpty()); EXPECT_FALSE(notification->app_metadata().icon_color.has_value()); } @@ -381,7 +383,7 @@ const Notification* notification = fake_notification_manager()->GetNotification(kNotificationIdA); - EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().color_icon, TestImage())); EXPECT_FALSE(notification->shared_image().has_value()); EXPECT_FALSE(notification->contact_image().has_value()); @@ -395,7 +397,7 @@ image_decoder_delegate()->RunAllCallbacks(); notification = fake_notification_manager()->GetNotification(kNotificationIdA); - EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().color_icon, TestImage())); EXPECT_TRUE( gfx::test::AreImagesEqual(*notification->shared_image(), TestImage())); @@ -411,7 +413,7 @@ image_decoder_delegate()->RunAllCallbacks(); notification = fake_notification_manager()->GetNotification(kNotificationIdA); - EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().color_icon, TestImage())); EXPECT_FALSE(notification->shared_image().has_value()); EXPECT_TRUE( @@ -424,7 +426,7 @@ kContactImageA)); notification_processor()->AddNotifications(first_set_of_notifications); image_decoder_delegate()->RunAllCallbacks(); - EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().color_icon, TestImage())); EXPECT_TRUE( gfx::test::AreImagesEqual(*notification->shared_image(), TestImage())); @@ -460,9 +462,10 @@ notification_processor()->AddNotifications(first_set_of_notifications); - // 6 image decode callbacks will occur for kIconDataA, kSharedImageA, - // kContactImageA, kIconDataB, kSharedImageB, and kContactImageB. - EXPECT_EQ(6u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); + // 8 image decode callbacks will occur for kIconDataA, data for icons twice + // for each notification, kSharedImageA, kContactImageA, kIconDataB, + // kSharedImageB, and kContactImageB. + EXPECT_EQ(8u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); image_decoder_delegate()->RunAllCallbacks(); EXPECT_EQ(2u, fake_notification_manager()->num_notifications()); @@ -518,25 +521,28 @@ EXPECT_EQ(3u, NumPendingRequests()); EXPECT_EQ(0u, fake_notification_manager()->num_notifications()); - // 3 image decode callbacks will occur. When the last image decode callback is - // finished running, which in this case is icon2, it will cause the next - // notification edit request to be executed. + // 5 image decode callbacks will occur (two icons, two monochrome icons, and a + // shared image). When the last image decode callback is finished running, + // which in this case is original icon2, it will cause the next notification + // edit request to be executed. + EXPECT_EQ(5u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); + EXPECT_EQ(3u, NumPendingRequests()); + image_decoder_delegate()->RunNextCallback(TestBitmap()); + + EXPECT_EQ(4u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); + EXPECT_EQ(3u, NumPendingRequests()); + image_decoder_delegate()->RunNextCallback(TestBitmap()); + EXPECT_EQ(3u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); EXPECT_EQ(3u, NumPendingRequests()); - image_decoder_delegate()->RunNextCallback(TestBitmap()); - - EXPECT_EQ(2u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); - EXPECT_EQ(3u, NumPendingRequests()); - image_decoder_delegate()->RunNextCallback(TestBitmap()); - - EXPECT_EQ(1u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); - EXPECT_EQ(3u, NumPendingRequests()); // The scheduled remove callback will occur, then subsequently the add // notification with 1 image. image_decoder_delegate()->RunNextCallback(TestBitmap()); + image_decoder_delegate()->RunNextCallback(TestBitmap()); + image_decoder_delegate()->RunNextCallback(TestBitmap()); EXPECT_EQ(1u, NumPendingRequests()); - EXPECT_EQ(1u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); + EXPECT_EQ(2u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); EXPECT_EQ(1u, fake_notification_manager()->num_notifications()); EXPECT_FALSE(fake_notification_manager()->GetNotification(kNotificationIdA));
diff --git a/chromeos/ash/components/phonehub/phone_status_processor.cc b/chromeos/ash/components/phonehub/phone_status_processor.cc index 80e17160..9daf10d2 100644 --- a/chromeos/ash/components/phonehub/phone_status_processor.cc +++ b/chromeos/ash/components/phonehub/phone_status_processor.cc
@@ -498,9 +498,12 @@ // TODO(nayebi): AppMetadata is no longer limited to Notification class, // let's move it outside of the Notification class.s2 apps_list.emplace_back(Notification::AppMetadata( - base::UTF8ToUTF16(app.visible_name()), app.package_name(), image, - /* icon_color = */ absl::nullopt, /* icon_is_monochrome = */ false, - app.user_id(), app.app_streamability_status())); + base::UTF8ToUTF16(app.visible_name()), app.package_name(), + /* color_icon= */ image, + /* monochrome_icon_mask= */ absl::nullopt, + /* icon_color = */ absl::nullopt, + /* icon_is_monochrome = */ false, app.user_id(), + app.app_streamability_status())); std::string key = app.package_name() + base::NumberToString(app.user_id()); decoding_data_list->emplace_back( IconDecoder::DecodingData(str_hash(key), app.icon())); @@ -526,7 +529,7 @@ std::string key = app_metadata.package_name + base::NumberToString(app_metadata.user_id); if (decoding_data.id == str_hash(key)) { - app_metadata.icon = decoding_data.result; + app_metadata.color_icon = decoding_data.result; continue; } }
diff --git a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc index af418d1..17f0dd6 100644 --- a/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc +++ b/chromeos/ash/components/phonehub/recent_apps_interaction_handler_impl_unittest.cc
@@ -93,7 +93,8 @@ const char package_name1[] = "com.fakeapp"; const int64_t expected_user_id1 = 1; auto app_metadata1 = Notification::AppMetadata( - app_visible_name1, package_name1, gfx::Image(), + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/kIconColor, /*icon_is_monochrome=*/true, expected_user_id1, proto::AppStreamabilityStatus::STREAMABLE); @@ -101,7 +102,8 @@ const char package_name2[] = "com.fakeapp2"; const int64_t expected_user_id2 = 2; auto app_metadata2 = Notification::AppMetadata( - app_visible_name2, package_name2, gfx::Image(), + app_visible_name2, package_name2, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/false, expected_user_id2, proto::AppStreamabilityStatus::STREAMABLE); @@ -119,7 +121,8 @@ const int64_t expected_user_id1 = 1; base::Value::Dict app_metadata_value = Notification::AppMetadata( - app_visible_name1, package_name1, gfx::Image(), + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/kIconColor, /*icon_is_monochrome=*/false, expected_user_id1, proto::AppStreamabilityStatus::STREAMABLE) .ToValue(); @@ -209,14 +212,16 @@ const char package_name1[] = "com.fakeapp1"; const int64_t expected_user_id1 = 1; auto app_metadata1 = Notification::AppMetadata( - app_visible_name1, package_name1, gfx::Image(), + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, expected_user_id1, proto::AppStreamabilityStatus::STREAMABLE); const char16_t app_visible_name2[] = u"Fake App2"; const char package_name2[] = "com.fakeapp2"; const int64_t expected_user_id2 = 2; auto app_metadata2 = Notification::AppMetadata( - app_visible_name2, package_name2, gfx::Image(), + app_visible_name2, package_name2, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, expected_user_id2, proto::AppStreamabilityStatus::STREAMABLE); handler().NotifyRecentAppAddedOrUpdated(app_metadata1, now); @@ -229,13 +234,15 @@ const char package_name1[] = "com.fakeapp1"; const int64_t expected_user_id = 1; auto app_metadata1 = Notification::AppMetadata( - app_visible_name1, package_name1, gfx::Image(), + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, expected_user_id, proto::AppStreamabilityStatus::STREAMABLE); const char16_t app_visible_name2[] = u"Fake App2"; const char package_name2[] = "com.fakeapp2"; auto app_metadata2 = Notification::AppMetadata( - app_visible_name2, package_name2, gfx::Image(), + app_visible_name2, package_name2, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, expected_user_id, proto::AppStreamabilityStatus::STREAMABLE); handler().NotifyRecentAppAddedOrUpdated(app_metadata1, now); @@ -274,7 +281,27 @@ const char expected_package_name[] = "com.fakeapp"; const int64_t expected_user_id = 1; auto expected_app_metadata = Notification::AppMetadata( - expected_app_visible_name, expected_package_name, gfx::Image(), + expected_app_visible_name, expected_package_name, + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, + expected_user_id, proto::AppStreamabilityStatus::STREAMABLE); + + handler().NotifyRecentAppClicked( + expected_app_metadata, + eche_app::mojom::AppStreamLaunchEntryPoint::RECENT_APPS); + + EXPECT_EQ(expected_package_name, GetPackageName()); +} + +TEST_F(RecentAppsInteractionHandlerTest, RecentAppsClickedHasOriginalIcon) { + const char16_t expected_app_visible_name[] = u"Fake App"; + const char expected_package_name[] = "com.fakeapp"; + const int64_t expected_user_id = 1; + auto expected_app_metadata = Notification::AppMetadata( + expected_app_visible_name, expected_package_name, + /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, expected_user_id, proto::AppStreamabilityStatus::STREAMABLE); @@ -289,20 +316,22 @@ const char16_t app_visible_name1[] = u"Fake App"; const char package_name1[] = "com.fakeapp"; const int64_t expected_user_id1 = 1; - auto app_metadata1 = - Notification::AppMetadata(app_visible_name1, package_name1, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id1, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata1 = Notification::AppMetadata( + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id1, + proto::AppStreamabilityStatus::STREAMABLE); const char16_t app_visible_name2[] = u"Fake App2"; const char package_name2[] = "com.fakeapp2"; const int64_t expected_user_id2 = 2; - auto app_metadata2 = - Notification::AppMetadata(app_visible_name2, package_name2, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id2, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata2 = Notification::AppMetadata( + app_visible_name2, package_name2, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id2, + proto::AppStreamabilityStatus::STREAMABLE); const base::Time now = base::Time::Now(); handler().NotifyRecentAppAddedOrUpdated(app_metadata1, now); @@ -324,16 +353,18 @@ TEST_F(RecentAppsInteractionHandlerTest, SetStreamableApps) { std::vector<Notification::AppMetadata> streamable_apps; - streamable_apps.emplace_back( - Notification::AppMetadata(u"App1", "com.fakeapp1", gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); - streamable_apps.emplace_back( - Notification::AppMetadata(u"App2", "com.fakeapp2", gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps.emplace_back(Notification::AppMetadata( + u"App1", "com.fakeapp1", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps.emplace_back(Notification::AppMetadata( + u"App2", "com.fakeapp2", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE)); handler().SetStreamableApps(streamable_apps); @@ -351,16 +382,18 @@ TEST_F(RecentAppsInteractionHandlerTest, SetStreamableApps_ClearsPreviousState) { std::vector<Notification::AppMetadata> streamable_apps; - streamable_apps.emplace_back( - Notification::AppMetadata(u"App1", "com.fakeapp1", gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); - streamable_apps.emplace_back( - Notification::AppMetadata(u"App2", "com.fakeapp2", gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps.emplace_back(Notification::AppMetadata( + u"App1", "com.fakeapp1", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps.emplace_back(Notification::AppMetadata( + u"App2", "com.fakeapp2", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE)); handler().SetStreamableApps(streamable_apps); @@ -375,11 +408,12 @@ .first.package_name); std::vector<Notification::AppMetadata> streamable_apps2; - streamable_apps2.emplace_back( - Notification::AppMetadata(u"App3", "com.fakeapp3", gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps2.emplace_back(Notification::AppMetadata( + u"App3", "com.fakeapp3", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE)); handler().SetStreamableApps(streamable_apps2); @@ -400,16 +434,18 @@ TEST_F(RecentAppsInteractionHandlerTest, RemoveStreamableApp) { std::vector<Notification::AppMetadata> streamable_apps; - streamable_apps.emplace_back( - Notification::AppMetadata(u"App1", "com.fakeapp1", gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); - streamable_apps.emplace_back( - Notification::AppMetadata(u"App2", "com.fakeapp2", gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, 1, - proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps.emplace_back(Notification::AppMetadata( + u"App1", "com.fakeapp1", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE)); + streamable_apps.emplace_back(Notification::AppMetadata( + u"App2", "com.fakeapp2", /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, 1, + proto::AppStreamabilityStatus::STREAMABLE)); handler().SetStreamableApps(streamable_apps); @@ -430,29 +466,32 @@ const char16_t app_visible_name1[] = u"Fake App"; const char package_name1[] = "com.fakeapp"; const int64_t expected_user_id1 = 1; - auto app_metadata1 = - Notification::AppMetadata(app_visible_name1, package_name1, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id1, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata1 = Notification::AppMetadata( + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id1, + proto::AppStreamabilityStatus::STREAMABLE); const char16_t app_visible_name2[] = u"Fake App2"; const char package_name2[] = "com.fakeapp2"; const int64_t expected_user_id2 = 1; - auto app_metadata2 = - Notification::AppMetadata(app_visible_name2, package_name2, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id2, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata2 = Notification::AppMetadata( + app_visible_name2, package_name2, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/gfx::Image(), + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id2, + proto::AppStreamabilityStatus::STREAMABLE); const char16_t app_visible_name3[] = u"Fake App3"; const char package_name3[] = "com.fakeapp3"; const int64_t expected_user_id3 = 1; - auto app_metadata3 = - Notification::AppMetadata(app_visible_name3, package_name3, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id3, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata3 = Notification::AppMetadata( + app_visible_name3, package_name3, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id3, + proto::AppStreamabilityStatus::STREAMABLE); const base::Time now = base::Time::Now(); const base::Time next_minute = base::Time::Now() + base::Minutes(1); @@ -477,20 +516,22 @@ const char16_t app_visible_name4[] = u"Fake App4"; const char package_name4[] = "com.fakeapp4"; const int64_t expected_user_id4 = 1; - auto app_metadata4 = - Notification::AppMetadata(app_visible_name4, package_name4, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id4, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata4 = Notification::AppMetadata( + app_visible_name4, package_name4, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id4, + proto::AppStreamabilityStatus::STREAMABLE); const char16_t app_visible_name5[] = u"Fake App5"; const char package_name5[] = "com.fakeapp5"; const int64_t expected_user_id5 = 1; - auto app_metadata5 = - Notification::AppMetadata(app_visible_name5, package_name5, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id5, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata5 = Notification::AppMetadata( + app_visible_name5, package_name5, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id5, + proto::AppStreamabilityStatus::STREAMABLE); const base::Time next_two_hour = base::Time::Now() + base::Hours(2); const base::Time next_three_hour = base::Time::Now() + base::Hours(3); @@ -568,11 +609,12 @@ const char16_t app_visible_name1[] = u"Fake App"; const char package_name1[] = "com.fakeapp"; const int64_t expected_user_id1 = 1; - auto app_metadata1 = - Notification::AppMetadata(app_visible_name1, package_name1, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id1, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata1 = Notification::AppMetadata( + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id1, + proto::AppStreamabilityStatus::STREAMABLE); handler().NotifyRecentAppAddedOrUpdated(app_metadata1, now); SetEcheFeatureState(FeatureState::kDisabledByUser); @@ -636,11 +678,12 @@ const char16_t app_visible_name1[] = u"Fake App"; const char package_name1[] = "com.fakeapp"; const int64_t expected_user_id1 = 1; - auto app_metadata1 = - Notification::AppMetadata(app_visible_name1, package_name1, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id1, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata1 = Notification::AppMetadata( + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id1, + proto::AppStreamabilityStatus::STREAMABLE); SetConnectionStatus(ConnectionStatus::kConnectionStatusConnected); SetAppsAccessStatus(true); handler().NotifyRecentAppAddedOrUpdated(app_metadata1, now); @@ -656,11 +699,12 @@ const char16_t app_visible_name1[] = u"Fake App"; const char package_name1[] = "com.fakeapp"; const int64_t expected_user_id1 = 1; - auto app_metadata1 = - Notification::AppMetadata(app_visible_name1, package_name1, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id1, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata1 = Notification::AppMetadata( + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id1, + proto::AppStreamabilityStatus::STREAMABLE); SetConnectionStatus(ConnectionStatus::kConnectionStatusConnected); SetAppsAccessStatus(true); @@ -711,11 +755,12 @@ const char16_t app_visible_name1[] = u"Fake App"; const char package_name1[] = "com.fakeapp"; const int64_t expected_user_id1 = 1; - auto app_metadata1 = - Notification::AppMetadata(app_visible_name1, package_name1, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id1, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata1 = Notification::AppMetadata( + app_visible_name1, package_name1, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id1, + proto::AppStreamabilityStatus::STREAMABLE); handler().NotifyRecentAppAddedOrUpdated(app_metadata1, now); EXPECT_EQ(RecentAppsInteractionHandler::RecentAppsUiState::ITEMS_VISIBLE, @@ -779,11 +824,12 @@ const char16_t app_visible_name[] = u"Fake App"; const char package_name[] = "com.fakeapp"; const int64_t expected_user_id = 1; - auto app_metadata = - Notification::AppMetadata(app_visible_name, package_name, gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, expected_user_id, - proto::AppStreamabilityStatus::STREAMABLE); + auto app_metadata = Notification::AppMetadata( + app_visible_name, package_name, /*color_icon=*/gfx::Image(), + /*monochrome_icon_mask=*/absl::nullopt, + /*icon_color=*/absl::nullopt, + /*icon_is_monochrome=*/true, expected_user_id, + proto::AppStreamabilityStatus::STREAMABLE); handler().NotifyRecentAppAddedOrUpdated(app_metadata, now); SetHostStatus(HostStatus::kHostSetButNotYetVerified);
diff --git a/components/cdm/renderer/key_system_support_update.cc b/components/cdm/renderer/key_system_support_update.cc index f37b9da..52dd9fc 100644 --- a/components/cdm/renderer/key_system_support_update.cc +++ b/components/cdm/renderer/key_system_support_update.cc
@@ -86,6 +86,11 @@ return media::EME_CODEC_NONE; } #endif // BUILDFLAG(IS_CHROMEOS_LACROS) +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (!base::FeatureList::IsEnabled(media::kPlatformHEVCDecoderSupport)) { + return media::EME_CODEC_NONE; + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) // If no profiles are specified, then all are supported. if (profiles.empty()) {
diff --git a/components/exo/wayland/shell_unittest.cc b/components/exo/wayland/shell_unittest.cc index 29fced60..582991e9 100644 --- a/components/exo/wayland/shell_unittest.cc +++ b/components/exo/wayland/shell_unittest.cc
@@ -234,8 +234,7 @@ using RemoteShellTest = test::WaylandServerTest; // Calling SetPined w/o commit should not crash (crbug.com/979128). -// Flacky crbug.com/1432518 -TEST_F(RemoteShellTest, DISABLED_DestroyRootSurfaceBeforeCommit) { +TEST_F(RemoteShellTest, DestroyRootSurfaceBeforeCommit) { test::ResourceKey surface_key; PostToClientAndWait([&](test::TestClient* client) {
diff --git a/components/exo/wayland/test/test_wayland_client_thread.cc b/components/exo/wayland/test/test_wayland_client_thread.cc index b7b5280..3bea921 100644 --- a/components/exo/wayland/test/test_wayland_client_thread.cc +++ b/components/exo/wayland/test/test_wayland_client_thread.cc
@@ -71,6 +71,7 @@ wl_display_read_events(client_->display()); wl_display_dispatch_pending(client_->display()); + wl_display_flush(client_->display()); } void TestWaylandClientThread::OnFileCanWriteWithoutBlocking(int fd) {}
diff --git a/components/global_media_controls/media_item_manager_impl.cc b/components/global_media_controls/media_item_manager_impl.cc index 39de074..230a5648 100644 --- a/components/global_media_controls/media_item_manager_impl.cc +++ b/components/global_media_controls/media_item_manager_impl.cc
@@ -4,9 +4,7 @@ #include "components/global_media_controls/media_item_manager_impl.h" -#include <list> #include <memory> -#include <string> #include "base/observer_list.h" #include "components/global_media_controls/public/media_dialog_delegate.h" @@ -75,18 +73,8 @@ if (!dialog_delegate_) return; - auto item_ids = GetActiveControllableItemIds(); - std::list<std::string> sorted_item_ids; + auto item_ids = GetActiveItemIds(); for (const std::string& id : item_ids) { - auto* item_producer = GetItemProducer(id); - if (item_producer && item_producer->IsItemActivelyPlaying(id)) { - sorted_item_ids.push_front(id); - } else { - sorted_item_ids.push_back(id); - } - } - - for (const std::string& id : sorted_item_ids) { base::WeakPtr<media_message_center::MediaNotificationItem> item = GetItem(id); MediaItemUI* item_ui = dialog_delegate_->ShowMediaItem(id, item); @@ -132,7 +120,7 @@ } bool MediaItemManagerImpl::HasActiveItems() { - return !GetActiveControllableItemIds().empty(); + return !GetActiveItemIds().empty(); } bool MediaItemManagerImpl::HasFrozenItems() { @@ -147,6 +135,30 @@ return !!dialog_delegate_; } +std::list<std::string> MediaItemManagerImpl::GetActiveItemIds() { + // Get all the active item IDs and remove duplicates. + std::set<std::string> item_ids; + for (auto* item_producer : item_producers_) { + const std::set<std::string>& ids = + item_producer->GetActiveControllableItemIds(); + item_ids.insert(ids.begin(), ids.end()); + } + + // Sort the item IDs. + std::list<std::string> sorted_item_ids; + for (const std::string& id : item_ids) { + auto* item_producer = GetItemProducer(id); + DCHECK(item_producer); + + if (item_producer->IsItemActivelyPlaying(id)) { + sorted_item_ids.push_front(id); + } else { + sorted_item_ids.push_back(id); + } + } + return sorted_item_ids; +} + void MediaItemManagerImpl::ShowAndObserveItem(const std::string& id) { OnItemsChanged(); if (!dialog_delegate_) @@ -159,17 +171,6 @@ producer->OnItemShown(id, item_ui); } -std::set<std::string> MediaItemManagerImpl::GetActiveControllableItemIds() - const { - std::set<std::string> ids; - for (auto* item_producer : item_producers_) { - const std::set<std::string>& item_ids = - item_producer->GetActiveControllableItemIds(); - ids.insert(item_ids.begin(), item_ids.end()); - } - return ids; -} - base::WeakPtr<media_message_center::MediaNotificationItem> MediaItemManagerImpl::GetItem(const std::string& id) { for (auto* producer : item_producers_) {
diff --git a/components/global_media_controls/media_item_manager_impl.h b/components/global_media_controls/media_item_manager_impl.h index 2db486c4..312c206 100644 --- a/components/global_media_controls/media_item_manager_impl.h +++ b/components/global_media_controls/media_item_manager_impl.h
@@ -5,9 +5,6 @@ #ifndef COMPONENTS_GLOBAL_MEDIA_CONTROLS_MEDIA_ITEM_MANAGER_IMPL_H_ #define COMPONENTS_GLOBAL_MEDIA_CONTROLS_MEDIA_ITEM_MANAGER_IMPL_H_ -#include <set> -#include <string> - #include "base/component_export.h" #include "base/containers/flat_set.h" #include "base/memory/raw_ptr.h" @@ -50,15 +47,13 @@ bool HasActiveItems() override; bool HasFrozenItems() override; bool HasOpenDialog() override; + std::list<std::string> GetActiveItemIds() override; base::WeakPtr<MediaItemManager> GetWeakPtr() override; private: // Called to display an item in an existing dialog. void ShowAndObserveItem(const std::string& id); - // Returns active controllable items gathered from all the item producers. - std::set<std::string> GetActiveControllableItemIds() const; - // Looks up an item from any source. Returns null if not found. base::WeakPtr<media_message_center::MediaNotificationItem> GetItem( const std::string& id);
diff --git a/components/global_media_controls/public/media_item_manager.h b/components/global_media_controls/public/media_item_manager.h index 20ddf3e..9ce7a0a4 100644 --- a/components/global_media_controls/public/media_item_manager.h +++ b/components/global_media_controls/public/media_item_manager.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_GLOBAL_MEDIA_CONTROLS_PUBLIC_MEDIA_ITEM_MANAGER_H_ #define COMPONENTS_GLOBAL_MEDIA_CONTROLS_PUBLIC_MEDIA_ITEM_MANAGER_H_ +#include <list> #include <memory> #include <string> @@ -69,6 +70,10 @@ // True if there is an open MediaDialogDelegate associated with this service. virtual bool HasOpenDialog() = 0; + // Returns active media item IDs gathered from all the item producers and + // items being actively played will be in the front. + virtual std::list<std::string> GetActiveItemIds() = 0; + virtual base::WeakPtr<MediaItemManager> GetWeakPtr() = 0; };
diff --git a/components/global_media_controls/public/media_session_item_producer.cc b/components/global_media_controls/public/media_session_item_producer.cc index 208bd402..f110fb0 100644 --- a/components/global_media_controls/public/media_session_item_producer.cc +++ b/components/global_media_controls/public/media_session_item_producer.cc
@@ -153,7 +153,11 @@ } bool MediaSessionItemProducer::Session::IsPlaying() const { - return is_playing_; + // Since both MediaSessionItemProducer and MediaSessionNotificationItem + // registered for MediaControllerObserver::MediaSessionInfoChanged(), we need + // to check both places to get the most recent playback state in case one has + // been updated while the other has not yet when this is called. + return is_playing_ || item_->IsPlaying(); } void MediaSessionItemProducer::Session::SetAudioSinkId(const std::string& id) {
diff --git a/components/global_media_controls/public/media_session_notification_item.cc b/components/global_media_controls/public/media_session_notification_item.cc index 17b801fd..ce79c7e 100644 --- a/components/global_media_controls/public/media_session_notification_item.cc +++ b/components/global_media_controls/public/media_session_notification_item.cc
@@ -322,6 +322,12 @@ return session_info_->remote_playback_metadata.Clone(); } +bool MediaSessionNotificationItem::IsPlaying() const { + return session_info_ && + session_info_->playback_state == + media_session::mojom::MediaPlaybackState::kPlaying; +} + void MediaSessionNotificationItem::FlushForTesting() { media_controller_remote_.FlushForTesting(); // IN-TEST }
diff --git a/components/global_media_controls/public/media_session_notification_item.h b/components/global_media_controls/public/media_session_notification_item.h index f3ef2cc04..5f7cdbe 100644 --- a/components/global_media_controls/public/media_session_notification_item.h +++ b/components/global_media_controls/public/media_session_notification_item.h
@@ -141,6 +141,9 @@ media_session::mojom::RemotePlaybackMetadataPtr GetRemotePlaybackMetadata() const; + // Returns whether the item is actively playing. + bool IsPlaying() const; + void FlushForTesting(); private:
diff --git a/components/global_media_controls/public/test/mock_media_item_manager.h b/components/global_media_controls/public/test/mock_media_item_manager.h index 548dce8f..0f03dd8c 100644 --- a/components/global_media_controls/public/test/mock_media_item_manager.h +++ b/components/global_media_controls/public/test/mock_media_item_manager.h
@@ -37,6 +37,7 @@ MOCK_METHOD(bool, HasActiveItems, ()); MOCK_METHOD(bool, HasFrozenItems, ()); MOCK_METHOD(bool, HasOpenDialog, ()); + MOCK_METHOD(std::list<std::string>, GetActiveItemIds, ()); private: base::WeakPtrFactory<MediaItemManager> weak_ptr_factory_{this};
diff --git a/components/live_caption/views/caption_bubble_controller_views.cc b/components/live_caption/views/caption_bubble_controller_views.cc index ee91c8a..3060d93d 100644 --- a/components/live_caption/views/caption_bubble_controller_views.cc +++ b/components/live_caption/views/caption_bubble_controller_views.cc
@@ -88,14 +88,18 @@ if (!caption_bubble_) return; - CaptionBubbleModel* caption_bubble_model = - caption_bubble_models_[caption_bubble_context].get(); + auto caption_bubble_model_it = + caption_bubble_models_.find(caption_bubble_context); + if (caption_bubble_model_it == caption_bubble_models_.end()) { + return; + } if (active_model_ != nullptr && - active_model_->unique_id() == caption_bubble_model->unique_id()) { + active_model_->unique_id() == + caption_bubble_model_it->second->unique_id()) { active_model_ = nullptr; caption_bubble_->SetModel(nullptr); } - caption_bubble_models_.erase(caption_bubble_context); + caption_bubble_models_.erase(caption_bubble_model_it); } void CaptionBubbleControllerViews::UpdateCaptionStyle( @@ -105,7 +109,9 @@ void CaptionBubbleControllerViews::SetActiveModel( CaptionBubbleContext* caption_bubble_context) { - if (!caption_bubble_models_.count(caption_bubble_context)) { + auto caption_bubble_model_it = + caption_bubble_models_.find(caption_bubble_context); + if (caption_bubble_model_it == caption_bubble_models_.end()) { auto caption_bubble_model = std::make_unique<CaptionBubbleModel>( caption_bubble_context, base::BindRepeating( @@ -119,8 +125,10 @@ caption_bubble_model->Close(); } - caption_bubble_models_.emplace(caption_bubble_context, - std::move(caption_bubble_model)); + caption_bubble_model_it = + caption_bubble_models_ + .emplace(caption_bubble_context, std::move(caption_bubble_model)) + .first; } if (!caption_bubble_session_observers_.count( @@ -137,11 +145,10 @@ } } - CaptionBubbleModel* caption_bubble_model = - caption_bubble_models_[caption_bubble_context].get(); if (active_model_ == nullptr || - active_model_->unique_id() != caption_bubble_model->unique_id()) { - active_model_ = caption_bubble_model; + active_model_->unique_id() != + caption_bubble_model_it->second->unique_id()) { + active_model_ = caption_bubble_model_it->second.get(); caption_bubble_->SetModel(active_model_); } }
diff --git a/components/password_manager/ios/shared_password_controller.h b/components/password_manager/ios/shared_password_controller.h index 831aeaa..001d68ca 100644 --- a/components/password_manager/ios/shared_password_controller.h +++ b/components/password_manager/ios/shared_password_controller.h
@@ -15,6 +15,7 @@ #import "components/password_manager/ios/password_generation_provider.h" #import "components/password_manager/ios/password_manager_driver_bridge.h" #import "components/password_manager/ios/password_suggestion_helper.h" +#import "ios/web/public/js_messaging/web_frames_manager_observer_bridge.h" #import "ios/web/public/web_state_observer_bridge.h" namespace password_manager { @@ -64,7 +65,8 @@ // Per-tab shared password controller. Handles parsing forms, loading // suggestions, filling forms, and generating passwords. @interface SharedPasswordController - : NSObject <CRWWebStateObserver, + : NSObject <CRWWebFramesManagerObserver, + CRWWebStateObserver, FormActivityObserver, FormSuggestionProvider, PasswordFormHelperDelegate,
diff --git a/components/password_manager/ios/shared_password_controller.mm b/components/password_manager/ios/shared_password_controller.mm index e86a6da..f9cf218 100644 --- a/components/password_manager/ios/shared_password_controller.mm +++ b/components/password_manager/ios/shared_password_controller.mm
@@ -48,6 +48,7 @@ #include "ios/web/common/url_scheme_util.h" #include "ios/web/public/js_messaging/web_frame.h" #import "ios/web/public/js_messaging/web_frames_manager.h" +#import "ios/web/public/js_messaging/web_frames_manager_observer_bridge.h" #include "ios/web/public/navigation/navigation_context.h" #import "ios/web/public/web_state.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -127,6 +128,10 @@ // Bridge to observe WebState from Objective-C. std::unique_ptr<web::WebStateObserverBridge> _webStateObserverBridge; + // Bridge to observe the web frames manager from Objective-C. + std::unique_ptr<web::WebFramesManagerObserverBridge> + _webFramesManagerObserverBridge; + // Bridge to observe form activity in |_webState|. std::unique_ptr<FormActivityObserverBridge> _formActivityObserverBridge; @@ -169,6 +174,12 @@ _webStateObserverBridge = std::make_unique<web::WebStateObserverBridge>(self); _webState->AddObserver(_webStateObserverBridge.get()); + _webFramesManagerObserverBridge = + std::make_unique<web::WebFramesManagerObserverBridge>(self); + web::WebFramesManager* framesManager = + password_manager::PasswordManagerJavaScriptFeature::GetInstance() + ->GetWebFramesManager(_webState); + framesManager->AddObserver(_webFramesManagerObserverBridge.get()); _formActivityObserverBridge = std::make_unique<FormActivityObserverBridge>(_webState, self); _formHelper = formHelper; @@ -270,56 +281,55 @@ } } -- (void)webState:(web::WebState*)webState - frameDidBecomeAvailable:(web::WebFrame*)web_frame { - DCHECK_EQ(_webState, webState); - DCHECK(web_frame); +- (void)webFramesManager:(web::WebFramesManager*)webFramesManager + frameBecameAvailable:(web::WebFrame*)webFrame { + DCHECK(webFrame); UniqueIDDataTabHelper* uniqueIDDataTabHelper = UniqueIDDataTabHelper::FromWebState(_webState); uint32_t nextAvailableRendererID = uniqueIDDataTabHelper->GetNextAvailableRendererID(); [self.formHelper setUpForUniqueIDsWithInitialState:nextAvailableRendererID - inFrame:web_frame]; + inFrame:webFrame]; - if (IsCrossOriginIframe(_webState, web_frame->IsMainFrame(), - web_frame->GetSecurityOrigin()) && + if (IsCrossOriginIframe(_webState, webFrame->IsMainFrame(), + webFrame->GetSecurityOrigin()) && !canProcessCrossOriginIframes()) { return; } - if (webState->ContentIsHTML()) { + if (_webState->ContentIsHTML()) { [self findPasswordFormsAndSendToPasswordStoreForFormChange:false - inFrame:web_frame]; + inFrame:webFrame]; } } // Track detaching iframes. -- (void)webState:(web::WebState*)webState - frameWillBecomeUnavailable:(web::WebFrame*)web_frame { - DCHECK_EQ(_webState, webState); +- (void)webFramesManager:(web::WebFramesManager*)webFramesManager + frameBecameUnavailable:(const std::string&)frameId { // No need to try to detect submissions when the webState is being destroyed. - if (webState->IsBeingDestroyed()) { + if (_webState->IsBeingDestroyed()) { return; } - if (web_frame->IsMainFrame()) { + web::WebFrame* webFrame = webFramesManager->GetFrameWithId(frameId); + if (!webFrame || webFrame->IsMainFrame()) { return; } - if (IsCrossOriginIframe(_webState, web_frame->IsMainFrame(), - web_frame->GetSecurityOrigin()) && + if (IsCrossOriginIframe(_webState, webFrame->IsMainFrame(), + webFrame->GetSecurityOrigin()) && !canProcessCrossOriginIframes()) { return; } // Casting is safe, as this code is run on iOS Chrome & WebView only. auto* driver = static_cast<IOSPasswordManagerDriver*>( - [_driverHelper PasswordManagerDriver:web_frame]); + [_driverHelper PasswordManagerDriver:webFrame]); if (driver) driver->ProcessFrameDeletion(); auto fieldDataManager = UniqueIDDataTabHelper::FromWebState(_webState)->GetFieldDataManager(); - _passwordManager->OnIframeDetach(web_frame->GetFrameId(), driver, + _passwordManager->OnIframeDetach(webFrame->GetFrameId(), driver, *fieldDataManager); } @@ -328,6 +338,11 @@ if (_webState) { _webState->RemoveObserver(_webStateObserverBridge.get()); _webStateObserverBridge.reset(); + web::WebFramesManager* framesManager = + password_manager::PasswordManagerJavaScriptFeature::GetInstance() + ->GetWebFramesManager(_webState); + framesManager->RemoveObserver(_webFramesManagerObserverBridge.get()); + _webFramesManagerObserverBridge.reset(); _formActivityObserverBridge.reset(); _webState = nullptr; }
diff --git a/components/password_manager/ios/shared_password_controller_unittest.mm b/components/password_manager/ios/shared_password_controller_unittest.mm index ae199f6..484a985 100644 --- a/components/password_manager/ios/shared_password_controller_unittest.mm +++ b/components/password_manager/ios/shared_password_controller_unittest.mm
@@ -157,6 +157,14 @@ OCMExpect([form_helper_ setDelegate:[OCMArg any]]); OCMExpect([suggestion_helper_ setDelegate:[OCMArg any]]); + auto web_frames_manager = std::make_unique<web::FakeWebFramesManager>(); + web_frames_manager_ = web_frames_manager.get(); + web::ContentWorld content_world = + PasswordManagerJavaScriptFeature::GetInstance() + ->GetSupportedContentWorld(); + web_state_.SetWebFramesManager(content_world, + std::move(web_frames_manager)); + controller_ = [[SharedPasswordController alloc] initWithWebState:&web_state_ manager:&password_manager_ @@ -168,14 +176,6 @@ [form_helper_ verify]; UniqueIDDataTabHelper::CreateForWebState(&web_state_); - auto web_frames_manager = std::make_unique<web::FakeWebFramesManager>(); - web_frames_manager_ = web_frames_manager.get(); - web::ContentWorld content_world = - PasswordManagerJavaScriptFeature::GetInstance() - ->GetSupportedContentWorld(); - web_state_.SetWebFramesManager(content_world, - std::move(web_frames_manager)); - web_state_.SetCurrentURL(GURL(kTestURL)); } @@ -194,6 +194,22 @@ } protected: + void AddWebFrame(std::unique_ptr<web::WebFrame> frame, + id completion_handler) { + [[[form_helper_ expect] ignoringNonObjectArgs] + setUpForUniqueIDsWithInitialState:1 + inFrame:frame.get()]; + + OCMExpect([form_helper_ findPasswordFormsInFrame:frame.get() + completionHandler:completion_handler]); + + web_frames_manager_->AddWebFrame(std::move(frame)); + } + + void AddWebFrame(std::unique_ptr<web::WebFrame> frame) { + AddWebFrame(std::move(frame), [OCMArg any]); + } + autofill::test::AutofillUnitTestEnvironment autofill_test_environment_; web::FakeWebState web_state_; web::FakeWebFramesManager* web_frames_manager_; @@ -219,7 +235,7 @@ auto web_frame = web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/true, GURL(kTestURL)); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); EXPECT_CALL(password_manager_, PropagateFieldDataManagerInfo); EXPECT_CALL(password_manager_, DidNavigateMainFrame(true)); @@ -236,10 +252,6 @@ web::FakeWebFrame::Create("dummy-frame-id", /*is_main_frame=*/true, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); - [[[form_helper_ expect] ignoringNonObjectArgs] - setUpForUniqueIDsWithInitialState:1 - inFrame:frame]; id mock_completion_handler = [OCMArg checkWithBlock:^(void (^completionHandler)( @@ -252,11 +264,9 @@ completionHandler({form_data}, 1); return YES; }]; - OCMExpect([form_helper_ findPasswordFormsInFrame:frame - completionHandler:mock_completion_handler]); + AddWebFrame(std::move(web_frame), mock_completion_handler); web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS); - web_state_.OnWebFrameDidBecomeAvailable(frame); [suggestion_helper_ verify]; [form_helper_ verify]; @@ -271,6 +281,11 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/true, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); + + [[[form_helper_ expect] ignoringNonObjectArgs] + setUpForUniqueIDsWithInitialState:1 + inFrame:web_frame.get()]; + web_frames_manager_->AddWebFrame(std::move(web_frame)); [[form_helper_ reject] findPasswordFormsInFrame:frame @@ -294,7 +309,6 @@ inFrame:web_frame.get()]; OCMExpect([form_helper_ findPasswordFormsInFrame:web_frame.get() completionHandler:[OCMArg any]]); - web_state_.OnWebFrameDidBecomeAvailable(web_frame.get()); } // Tests that suggestions are reported as unavailable for nonpassword forms. @@ -313,7 +327,7 @@ auto web_frame = web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); id mock_completion_handler = [OCMArg checkWithBlock:^BOOL(void (^completionHandler)(BOOL)) { @@ -353,7 +367,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); [[[suggestion_helper_ expect] andReturn:@[]] retrieveSuggestionsWithFormID:form_query.uniqueFormID @@ -435,7 +449,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); [[[suggestion_helper_ expect] andReturn:@[ suggestion ]] retrieveSuggestionsWithFormID:form_query.uniqueFormID @@ -478,7 +492,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); [[[suggestion_helper_ expect] andReturn:@[]] retrieveSuggestionsWithFormID:form_query.uniqueFormID @@ -564,7 +578,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::FakeWebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); id extract_completion_handler_arg = [OCMArg checkWithBlock:^(void (^completion_handler)(BOOL, autofill::FormData)) { @@ -614,7 +628,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/true, GURL(kTestURL)); web::FakeWebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); FormSuggestion* suggestion = [FormSuggestion suggestionWithValue:@"test-value" @@ -688,7 +702,7 @@ auto web_frame = web::FakeWebFrame::Create("frame-id", /*is_main_frame=*/true, GURL(kTestURL)); web::FakeWebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); [controller_ webState:&web_state_ didRegisterFormActivity:params @@ -768,16 +782,15 @@ auto web_frame = web::FakeWebFrame::Create("frame-id", /*is_main_frame=*/true, GURL(kTestURL)); web::FakeWebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + OCMExpect([driver_helper_ PasswordManagerDriver:frame]); + + AddWebFrame(std::move(web_frame)); OCMExpect([form_helper_ findPasswordFormsInFrame:frame completionHandler:mock_completion_handler]); autofill::FormActivityParams params; params.type = "form_changed"; - - OCMExpect([driver_helper_ PasswordManagerDriver:frame]); - [controller_ webState:&web_state_ didRegisterFormActivity:params inFrame:frame]; @@ -802,6 +815,14 @@ form_helper_ = OCMStrictClassMock([PasswordFormHelper class]); OCMExpect([form_helper_ setDelegate:[OCMArg any]]); + auto web_frames_manager = std::make_unique<web::FakeWebFramesManager>(); + web_frames_manager_ = web_frames_manager.get(); + web::ContentWorld content_world = + PasswordManagerJavaScriptFeature::GetInstance() + ->GetSupportedContentWorld(); + web_state_.SetWebFramesManager(content_world, + std::move(web_frames_manager)); + PasswordControllerDriverHelper* driver_helper = [[PasswordControllerDriverHelper alloc] initWithWebState:&web_state_]; controller_ = @@ -816,14 +837,6 @@ UniqueIDDataTabHelper::CreateForWebState(&web_state_); - auto web_frames_manager = std::make_unique<web::FakeWebFramesManager>(); - web_frames_manager_ = web_frames_manager.get(); - web::ContentWorld content_world = - PasswordManagerJavaScriptFeature::GetInstance() - ->GetSupportedContentWorld(); - web_state_.SetWebFramesManager(content_world, - std::move(web_frames_manager)); - web_state_.SetCurrentURL(GURL(kTestURL)); } @@ -834,6 +847,14 @@ .WillRepeatedly(Return(&password_manager_client_)); } + void AddWebFrame(std::unique_ptr<web::WebFrame> frame) { + [[[form_helper_ expect] ignoringNonObjectArgs] + setUpForUniqueIDsWithInitialState:1 + inFrame:frame.get()]; + + web_frames_manager_->AddWebFrame(std::move(frame)); + } + protected: web::FakeWebState web_state_; web::FakeWebFramesManager* web_frames_manager_; @@ -856,7 +877,11 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/true, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + + [[form_helper_ expect] findPasswordFormsInFrame:frame + completionHandler:[OCMArg any]]; + + AddWebFrame(std::move(web_frame)); EXPECT_CALL(password_manager_, OnPasswordFormsParsed); EXPECT_CALL(password_manager_, OnPasswordFormsRendered); @@ -918,7 +943,11 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/true, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + + [[form_helper_ expect] findPasswordFormsInFrame:frame + completionHandler:[OCMArg any]]; + + AddWebFrame(std::move(web_frame)); EXPECT_CALL(password_manager_, OnPasswordFormsParsed); EXPECT_CALL(password_manager_, OnPasswordFormsRendered); @@ -1012,7 +1041,9 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + [[form_helper_ expect] findPasswordFormsInFrame:frame + completionHandler:[OCMArg any]]; + AddWebFrame(std::move(web_frame)); ASSERT_TRUE(IsCrossOriginIframe(&web_state_, frame->IsMainFrame(), frame->GetSecurityOrigin())); @@ -1064,7 +1095,10 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/true, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + + [[form_helper_ expect] findPasswordFormsInFrame:frame + completionHandler:[OCMArg any]]; + AddWebFrame(std::move(web_frame)); EXPECT_CALL(password_manager_, OnPasswordFormsParsed); EXPECT_CALL(password_manager_, OnPasswordFormsRendered); @@ -1128,10 +1162,6 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); - - ASSERT_TRUE(IsCrossOriginIframe(&web_state_, frame->IsMainFrame(), - frame->GetSecurityOrigin())); [[[form_helper_ expect] ignoringNonObjectArgs] setUpForUniqueIDsWithInitialState:1 @@ -1144,7 +1174,11 @@ [[form_helper_ reject] findPasswordFormsInFrame:frame completionHandler:[OCMArg any]]; } - [controller_ webState:&web_state_ frameDidBecomeAvailable:frame]; + + web_frames_manager_->AddWebFrame(std::move(web_frame)); + + ASSERT_TRUE(IsCrossOriginIframe(&web_state_, frame->IsMainFrame(), + frame->GetSecurityOrigin())); [form_helper_ verify]; } @@ -1159,7 +1193,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); ASSERT_TRUE(IsCrossOriginIframe(&web_state_, frame->IsMainFrame(), frame->GetSecurityOrigin())); @@ -1170,7 +1204,7 @@ } else { EXPECT_CALL(password_manager_, OnIframeDetach).Times(0); } - [controller_ webState:&web_state_ frameWillBecomeUnavailable:frame]; + web_frames_manager_->RemoveWebFrame(frame->GetFrameId()); } // Tests checkIfSuggestionsAvailableForForm supports cross-origin iframes when @@ -1184,7 +1218,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); ASSERT_TRUE(IsCrossOriginIframe(&web_state_, frame->IsMainFrame(), frame->GetSecurityOrigin())); @@ -1232,7 +1266,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); ASSERT_TRUE(IsCrossOriginIframe(&web_state_, frame->IsMainFrame(), frame->GetSecurityOrigin())); @@ -1286,7 +1320,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); ASSERT_TRUE(IsCrossOriginIframe(&web_state_, frame->IsMainFrame(), frame->GetSecurityOrigin())); @@ -1314,28 +1348,32 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); ASSERT_TRUE(IsCrossOriginIframe(&web_state_, frame->IsMainFrame(), frame->GetSecurityOrigin())); - id mock_completion_handler = - [OCMArg checkWithBlock:^(void (^completionHandler)( - const std::vector<autofill::FormData>& forms, uint32_t maxID)) { - return YES; - }]; - if (IsCrossOriginSupportEnabled()) { OCMExpect([form_helper_ findPasswordFormsInFrame:frame - completionHandler:mock_completion_handler]); + completionHandler:[OCMArg any]]); } else { [[form_helper_ reject] findPasswordFormsInFrame:frame - completionHandler:mock_completion_handler]; + completionHandler:[OCMArg any]]; } + [[[form_helper_ expect] ignoringNonObjectArgs] + setUpForUniqueIDsWithInitialState:1 + inFrame:frame]; + + web_frames_manager_->AddWebFrame(std::move(web_frame)); + autofill::FormActivityParams params; params.type = "form_changed"; + if (IsCrossOriginSupportEnabled()) { + OCMExpect([form_helper_ findPasswordFormsInFrame:frame + completionHandler:[OCMArg any]]); + } + [controller_ webState:&web_state_ didRegisterFormActivity:params inFrame:frame]; @@ -1354,7 +1392,7 @@ web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), /*is_main_frame=*/false, GURL(kTestURL)); web::WebFrame* frame = web_frame.get(); - web_frames_manager_->AddWebFrame(std::move(web_frame)); + AddWebFrame(std::move(web_frame)); ASSERT_TRUE(IsCrossOriginIframe(&web_state_, frame->IsMainFrame(), frame->GetSecurityOrigin()));
diff --git a/components/performance_manager/embedder/graph_features.h b/components/performance_manager/embedder/graph_features.h index 52ccbbce..761edc56 100644 --- a/components/performance_manager/embedder/graph_features.h +++ b/components/performance_manager/embedder/graph_features.h
@@ -42,18 +42,15 @@ // (3) Add the feature to the implementation of ConfigureGraph(). bool execution_context_priority_decorator : 1; bool execution_context_registry : 1; - bool frame_node_impl_describer : 1; bool frame_visibility_decorator : 1; bool freezing_vote_decorator : 1; bool metrics_collector : 1; + bool node_impl_describers : 1; bool page_load_tracker_decorator : 1; - bool page_node_impl_describer : 1; bool process_hosted_content_types_aggregator : 1; - bool process_node_impl_describer : 1; bool site_data_recorder : 1; bool tab_properties_decorator : 1; bool v8_context_tracker : 1; - bool worker_node_impl_describer : 1; }; }; @@ -72,8 +69,8 @@ return *this; } - constexpr GraphFeatures& EnableFrameNodeImplDescriber() { - flags_.frame_node_impl_describer = true; + constexpr GraphFeatures& EnableNodeImplDescribers() { + flags_.node_impl_describers = true; return *this; } @@ -97,21 +94,11 @@ return *this; } - constexpr GraphFeatures& EnablePageNodeImplDescriber() { - flags_.page_node_impl_describer = true; - return *this; - } - constexpr GraphFeatures& EnableProcessHostedContentTypesAggregator() { flags_.process_hosted_content_types_aggregator = true; return *this; } - constexpr GraphFeatures& EnableProcessNodeImplDescriber() { - flags_.process_node_impl_describer = true; - return *this; - } - // This is a nop on the Android platform, as the feature isn't available // there. constexpr GraphFeatures& EnableSiteDataRecorder() { @@ -130,11 +117,6 @@ return *this; } - constexpr GraphFeatures& EnableWorkerNodeImplDescriber() { - flags_.worker_node_impl_describer = true; - return *this; - } - // Helper to enable the minimal set of features required for a content_shell // browser to work. constexpr GraphFeatures& EnableMinimal() { @@ -147,18 +129,15 @@ // from production code. constexpr GraphFeatures& EnableDefault() { EnableExecutionContextRegistry(); - EnableFrameNodeImplDescriber(); EnableFrameVisibilityDecorator(); EnableFreezingVoteDecorator(); EnableMetricsCollector(); + EnableNodeImplDescribers(); EnablePageLoadTrackerDecorator(); - EnablePageNodeImplDescriber(); EnableProcessHostedContentTypesAggregator(); - EnableProcessNodeImplDescriber(); EnableSiteDataRecorder(); EnableTabPropertiesDecorator(); EnableV8ContextTracker(); - EnableWorkerNodeImplDescriber(); return *this; }
diff --git a/components/performance_manager/graph/frame_node_impl_describer.h b/components/performance_manager/graph/frame_node_impl_describer.h index 78d2a421..14483fe 100644 --- a/components/performance_manager/graph/frame_node_impl_describer.h +++ b/components/performance_manager/graph/frame_node_impl_describer.h
@@ -5,11 +5,14 @@ #ifndef COMPONENTS_PERFORMANCE_MANAGER_GRAPH_FRAME_NODE_IMPL_DESCRIBER_H_ #define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_FRAME_NODE_IMPL_DESCRIBER_H_ +#include "base/values.h" #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/graph/node_data_describer.h" namespace performance_manager { +class FrameNode; + class FrameNodeImplDescriber : public GraphOwned, public NodeDataDescriberDefaultImpl { public: @@ -28,4 +31,4 @@ } // namespace performance_manager -#endif // COMPONENTS_PERFORMANCE_MANAGER_GRAPH_FRAME_NODE_IMPL_DESCRIBER_H_ \ No newline at end of file +#endif // COMPONENTS_PERFORMANCE_MANAGER_GRAPH_FRAME_NODE_IMPL_DESCRIBER_H_
diff --git a/components/performance_manager/graph/graph_impl.cc b/components/performance_manager/graph/graph_impl.cc index a0f555d9..1ba1e06 100644 --- a/components/performance_manager/graph/graph_impl.cc +++ b/components/performance_manager/graph/graph_impl.cc
@@ -57,6 +57,29 @@ DCHECK(!base::Contains(*observers, observer)); } +base::Value::Dict DescribeNodeWithDescriber(const NodeDataDescriber& describer, + const Node* node) { + const NodeBase* node_base = NodeBase::FromNode(node); + switch (node_base->type()) { + case NodeTypeEnum::kFrame: + return describer.DescribeNodeData(FrameNodeImpl::FromNodeBase(node_base)); + case NodeTypeEnum::kPage: + return describer.DescribeNodeData(PageNodeImpl::FromNodeBase(node_base)); + case NodeTypeEnum::kProcess: + return describer.DescribeNodeData( + ProcessNodeImpl::FromNodeBase(node_base)); + case NodeTypeEnum::kSystem: + return describer.DescribeNodeData( + SystemNodeImpl::FromNodeBase(node_base)); + case NodeTypeEnum::kWorker: + return describer.DescribeNodeData( + WorkerNodeImpl::FromNodeBase(node_base)); + case NodeTypeEnum::kInvalidType: + NOTREACHED_NORETURN(); + } + NOTREACHED_NORETURN(); +} + class NodeDataDescriberRegistryImpl : public NodeDataDescriberRegistry { public: ~NodeDataDescriberRegistryImpl() override; @@ -73,33 +96,11 @@ } private: - template <typename NodeType, typename NodeImplType> - base::Value::Dict DescribeNodeImpl( - base::Value::Dict (NodeDataDescriber::*DescribeFn)(const NodeType*) const, - const NodeImplType* node) const VALID_CONTEXT_REQUIRED(sequence_checker_); - base::flat_map<const NodeDataDescriber*, std::string> describers_ GUARDED_BY_CONTEXT(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_); }; -template <typename NodeType, typename NodeImplType> -base::Value::Dict NodeDataDescriberRegistryImpl::DescribeNodeImpl( - base::Value::Dict (NodeDataDescriber::*Describe)(const NodeType*) const, - const NodeImplType* node) const { - base::Value::Dict result; - - for (const auto& name_and_describer : describers_) { - base::Value::Dict description = (name_and_describer.first->*Describe)(node); - if (!description.empty()) { - DCHECK_EQ(nullptr, result.FindDict(name_and_describer.second)); - result.Set(name_and_describer.second, std::move(description)); - } - } - - return result; -} - NodeDataDescriberRegistryImpl::~NodeDataDescriberRegistryImpl() { // All describers should have unregistered before the graph is destroyed. DCHECK(describers_.empty()); @@ -129,27 +130,15 @@ base::Value::Dict NodeDataDescriberRegistryImpl::DescribeNodeData( const Node* node) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const NodeBase* node_base = NodeBase::FromNode(node); - switch (node_base->type()) { - case NodeTypeEnum::kInvalidType: - NOTREACHED(); - return base::Value::Dict(); - case NodeTypeEnum::kFrame: - return DescribeNodeImpl(&NodeDataDescriber::DescribeFrameNodeData, - FrameNodeImpl::FromNodeBase(node_base)); - case NodeTypeEnum::kPage: - return DescribeNodeImpl(&NodeDataDescriber::DescribePageNodeData, - PageNodeImpl::FromNodeBase(node_base)); - case NodeTypeEnum::kProcess: - return DescribeNodeImpl(&NodeDataDescriber::DescribeProcessNodeData, - ProcessNodeImpl::FromNodeBase(node_base)); - case NodeTypeEnum::kSystem: - return DescribeNodeImpl(&NodeDataDescriber::DescribeSystemNodeData, - SystemNodeImpl::FromNodeBase(node_base)); - case NodeTypeEnum::kWorker: - return DescribeNodeImpl(&NodeDataDescriber::DescribeWorkerNodeData, - WorkerNodeImpl::FromNodeBase(node_base)); + base::Value::Dict result; + for (const auto& [describer, describer_name] : describers_) { + base::Value::Dict description = DescribeNodeWithDescriber(*describer, node); + if (!description.empty()) { + DCHECK_EQ(nullptr, result.FindDict(describer_name)); + result.Set(describer_name, std::move(description)); + } } + return result; } } // namespace
diff --git a/components/performance_manager/graph/page_node_impl_describer.cc b/components/performance_manager/graph/page_node_impl_describer.cc index 833ed6df..7263105 100644 --- a/components/performance_manager/graph/page_node_impl_describer.cc +++ b/components/performance_manager/graph/page_node_impl_describer.cc
@@ -5,6 +5,7 @@ #include "components/performance_manager/graph/page_node_impl_describer.h" #include "base/strings/string_number_conversions.h" +#include "base/values.h" #include "components/performance_manager/graph/page_node_impl.h" #include "components/performance_manager/public/freezing/freezing.h" #include "components/performance_manager/public/graph/node_data_describer_registry.h"
diff --git a/components/performance_manager/graph/page_node_impl_describer.h b/components/performance_manager/graph/page_node_impl_describer.h index 5bc1d08..39c42b0 100644 --- a/components/performance_manager/graph/page_node_impl_describer.h +++ b/components/performance_manager/graph/page_node_impl_describer.h
@@ -5,11 +5,14 @@ #ifndef COMPONENTS_PERFORMANCE_MANAGER_GRAPH_PAGE_NODE_IMPL_DESCRIBER_H_ #define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_PAGE_NODE_IMPL_DESCRIBER_H_ +#include "base/values.h" #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/graph/node_data_describer.h" namespace performance_manager { +class PageNode; + // Describes the state of of a PageNodeImpl for human consumption. class PageNodeImplDescriber : public GraphOwned, public NodeDataDescriberDefaultImpl {
diff --git a/components/performance_manager/graph/process_node_impl_describer.cc b/components/performance_manager/graph/process_node_impl_describer.cc index e90a4322..abdd89b4 100644 --- a/components/performance_manager/graph/process_node_impl_describer.cc +++ b/components/performance_manager/graph/process_node_impl_describer.cc
@@ -14,6 +14,7 @@ #include "base/values.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#include "components/performance_manager/graph/process_node_impl.h" #include "components/performance_manager/public/graph/node_data_describer_registry.h" #include "components/performance_manager/public/graph/process_node.h" #include "content/public/browser/child_process_host.h"
diff --git a/components/performance_manager/graph/process_node_impl_describer.h b/components/performance_manager/graph/process_node_impl_describer.h index e0f1d3f..3c994c8 100644 --- a/components/performance_manager/graph/process_node_impl_describer.h +++ b/components/performance_manager/graph/process_node_impl_describer.h
@@ -6,12 +6,13 @@ #define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_PROCESS_NODE_IMPL_DESCRIBER_H_ #include "base/values.h" -#include "components/performance_manager/graph/process_node_impl.h" #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/graph/node_data_describer.h" namespace performance_manager { +class ProcessNode; + // Describes the state of of a ProcessNodeImpl for human consumption. class ProcessNodeImplDescriber : public GraphOwned, public NodeDataDescriberDefaultImpl {
diff --git a/components/performance_manager/graph/worker_node_impl_describer.cc b/components/performance_manager/graph/worker_node_impl_describer.cc index 9ebc9b1..782e9a1 100644 --- a/components/performance_manager/graph/worker_node_impl_describer.cc +++ b/components/performance_manager/graph/worker_node_impl_describer.cc
@@ -5,6 +5,8 @@ #include "components/performance_manager/graph/worker_node_impl_describer.h" #include "base/strings/string_number_conversions.h" +#include "base/values.h" +#include "components/performance_manager/graph/worker_node_impl.h" #include "components/performance_manager/public/graph/node_data_describer_registry.h" #include "components/performance_manager/public/graph/node_data_describer_util.h"
diff --git a/components/performance_manager/graph/worker_node_impl_describer.h b/components/performance_manager/graph/worker_node_impl_describer.h index 2626148..5cc2d12 100644 --- a/components/performance_manager/graph/worker_node_impl_describer.h +++ b/components/performance_manager/graph/worker_node_impl_describer.h
@@ -6,12 +6,13 @@ #define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_WORKER_NODE_IMPL_DESCRIBER_H_ #include "base/values.h" -#include "components/performance_manager/graph/worker_node_impl.h" #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/graph/node_data_describer.h" namespace performance_manager { +class WorkerNode; + class WorkerNodeImplDescriber : public GraphOwnedDefaultImpl, public NodeDataDescriberDefaultImpl { public:
diff --git a/components/performance_manager/graph_features.cc b/components/performance_manager/graph_features.cc index b8eca8c..691ea02 100644 --- a/components/performance_manager/graph_features.cc +++ b/components/performance_manager/graph_features.cc
@@ -39,24 +39,22 @@ void GraphFeatures::ConfigureGraph(Graph* graph) const { if (flags_.execution_context_registry) Install<execution_context::ExecutionContextRegistryImpl>(graph); - if (flags_.frame_node_impl_describer) - Install<FrameNodeImplDescriber>(graph); if (flags_.frame_visibility_decorator) Install<FrameVisibilityDecorator>(graph); if (flags_.metrics_collector) Install<MetricsCollector>(graph); + if (flags_.node_impl_describers) { + Install<FrameNodeImplDescriber>(graph); + Install<PageNodeImplDescriber>(graph); + Install<ProcessNodeImplDescriber>(graph); + Install<WorkerNodeImplDescriber>(graph); + } if (flags_.freezing_vote_decorator) Install<FreezingVoteDecorator>(graph); if (flags_.page_load_tracker_decorator) Install<PageLoadTrackerDecorator>(graph); - if (flags_.page_node_impl_describer) - Install<PageNodeImplDescriber>(graph); if (flags_.process_hosted_content_types_aggregator) Install<ProcessHostedContentTypesAggregator>(graph); - if (flags_.process_node_impl_describer) - Install<ProcessNodeImplDescriber>(graph); - if (flags_.worker_node_impl_describer) - Install<WorkerNodeImplDescriber>(graph); #if !BUILDFLAG(IS_ANDROID) if (flags_.site_data_recorder)
diff --git a/components/performance_manager/public/graph/node_data_describer.h b/components/performance_manager/public/graph/node_data_describer.h index 3d52703..d7ff837 100644 --- a/components/performance_manager/public/graph/node_data_describer.h +++ b/components/performance_manager/public/graph/node_data_describer.h
@@ -49,6 +49,23 @@ const SystemNode* node) const = 0; virtual base::Value::Dict DescribeWorkerNodeData( const WorkerNode* node) const = 0; + + // Polymorphic accessors. + base::Value::Dict DescribeNodeData(const FrameNode* node) const { + return DescribeFrameNodeData(node); + } + base::Value::Dict DescribeNodeData(const PageNode* node) const { + return DescribePageNodeData(node); + } + base::Value::Dict DescribeNodeData(const ProcessNode* node) const { + return DescribeProcessNodeData(node); + } + base::Value::Dict DescribeNodeData(const SystemNode* node) const { + return DescribeSystemNodeData(node); + } + base::Value::Dict DescribeNodeData(const WorkerNode* node) const { + return DescribeWorkerNodeData(node); + } }; // A convenience do-nothing implementation of the interface above. Returns
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/ChromeRootStoreEnabled.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/ChromeRootStoreEnabled.yaml index fe18bc1..8ff42e3 100644 --- a/components/policy/resources/templates/policy_definitions/Miscellaneous/ChromeRootStoreEnabled.yaml +++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/ChromeRootStoreEnabled.yaml
@@ -17,7 +17,7 @@ when support for using the platform supplied certificate verifier and roots was removed. example_value: false features: - dynamic_refresh: false + dynamic_refresh: true per_profile: false items: - caption: Use the Chrome Root Store.
diff --git a/components/safe_browsing/core/browser/verdict_cache_manager.cc b/components/safe_browsing/core/browser/verdict_cache_manager.cc index 9a98b62..fd30354 100644 --- a/components/safe_browsing/core/browser/verdict_cache_manager.cc +++ b/components/safe_browsing/core/browser/verdict_cache_manager.cc
@@ -212,11 +212,11 @@ } template <class T> -size_t RemoveExpiredEntries(base::Value* verdict_dictionary, +size_t RemoveExpiredEntries(base::Value::Dict& verdict_dictionary, const char* proto_name) { DCHECK(proto_name == kVerdictProto || proto_name == kRealTimeThreatInfoProto); std::vector<std::string> expired_keys; - for (auto item : verdict_dictionary->GetDict()) { + for (auto item : verdict_dictionary) { int verdict_received_time; T verdict; if (!ParseVerdictEntry<T>(&item.second, &verdict_received_time, &verdict, @@ -228,7 +228,7 @@ } for (const std::string& key : expired_keys) { - verdict_dictionary->RemoveKey(key); + verdict_dictionary.Remove(key); } return expired_keys.size(); @@ -577,9 +577,10 @@ for (auto item : source.setting_value.GetDict()) { if (item.first == base::StringPiece(kPasswordOnFocusCacheKey)) { stored_verdict_count_password_on_focus_.value() += - item.second.DictSize(); + item.second.GetDict().size(); } else { - stored_verdict_count_password_entry_.value() += item.second.DictSize(); + stored_verdict_count_password_entry_.value() += + item.second.GetDict().size(); } } } @@ -926,14 +927,14 @@ if (trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE && key == std::string(kPasswordOnFocusCacheKey)) { size_t removed_cnt = RemoveExpiredEntries<LoginReputationClientResponse>( - &value, kVerdictProto); + value.GetDict(), kVerdictProto); verdicts_removed += removed_cnt; if (stored_verdict_count_password_on_focus_.has_value()) { stored_verdict_count_password_on_focus_.value() -= removed_cnt; } } else { size_t removed_cnt = RemoveExpiredEntries<LoginReputationClientResponse>( - &value, kVerdictProto); + value.GetDict(), kVerdictProto); verdicts_removed += removed_cnt; if (stored_verdict_count_password_entry_.has_value()) { stored_verdict_count_password_entry_.value() -= removed_cnt; @@ -957,7 +958,7 @@ std::vector<std::string> empty_keys; for (auto [key, value] : cache_dictionary) { size_t removed_cnt = RemoveExpiredEntries<RTLookupResponse::ThreatInfo>( - &value, kRealTimeThreatInfoProto); + value.GetDict(), kRealTimeThreatInfoProto); verdicts_removed += removed_cnt; if (stored_verdict_count_real_time_url_check_.has_value()) { stored_verdict_count_real_time_url_check_.value() -= removed_cnt;
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc index 26d1e63c..66264e2 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc +++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc
@@ -246,6 +246,9 @@ absl::optional<TrainingRequestId> request_id = training_cache_->GetRequestId(segment.value().segment_id()); if (request_id.has_value()) { + RecordTrainingDataCollectionEvent( + segment.value().segment_id(), + stats::TrainingDataCollectionEvent::kHistogramTriggerHit); OnObservationTrigger(param, request_id.value(), segment.value()); } } @@ -412,16 +415,29 @@ // If no segment info list has been found. if (it == preferred_segment_info.end()) { + RecordTrainingDataCollectionEvent( + segment_id, stats::TrainingDataCollectionEvent::kNoSegmentInfo); return; } const proto::SegmentInfo& segment_info = it->second; - if (!CanReportTrainingData(segment_info, /*include_outputs*/ false)) + if (!CanReportTrainingData(segment_info, /*include_outputs*/ false)) { + RecordTrainingDataCollectionEvent( + segment_id, + stats::TrainingDataCollectionEvent::kDisallowedForRecording); return; + } TrainingTimings training_request = ComputeDecisionTiming(segment_info); + auto is_periodic = (type != proto::TrainingOutputs::TriggerConfig::ONDEMAND); + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + is_periodic + ? stats::TrainingDataCollectionEvent::kContinousCollectionStart + : stats::TrainingDataCollectionEvent::kImmediateCollectionStart); + // Start training data collection and generate training data inputs. base::Time unused; feature_list_query_processor_->ProcessFeatureList( @@ -462,17 +478,41 @@ std::move(training_data), /*save_to_db=*/store_to_disk); + if (has_error) { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kGetInputTensorsFailed); + } else { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kCollectAndStoreInputsSuccess); + } + // Set up delayed output recordings based on time delay triggers defined // in model metadata. // TODO(haileywang): This is slightly inaccurate since the the delay timer is // only started after the input training tensors are cached. if (training_request.observation_delayed_task) { + if (training_request.observation_delayed_task.value().is_zero()) { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kImmediateObservationPosted); + } else { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kDelayedTaskPosted); + } + base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( FROM_HERE, base::BindOnce(&TrainingDataCollectorImpl::OnObservationTrigger, weak_ptr_factory_.GetWeakPtr(), absl::nullopt, request_id, segment_info), *training_request.observation_delayed_task); + } else { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kWaitingForNonDelayedTrigger); } } @@ -480,8 +520,16 @@ const absl::optional<ImmediaCollectionParam>& param, TrainingRequestId request_id, const proto::SegmentInfo& segment_info) { - if (!CanReportTrainingData(segment_info, /*include_outputs*/ true)) + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kObservationTimeReached); + + if (!CanReportTrainingData(segment_info, /*include_outputs*/ true)) { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kObservationDisallowed); return; + } // Retrieve input tensor from cache. training_cache_->GetInputsAndDelete( @@ -494,8 +542,12 @@ const absl::optional<ImmediaCollectionParam>& param, const proto::SegmentInfo& segment_info, absl::optional<proto::TrainingData> input) { - if (!input.has_value()) + if (!input.has_value()) { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kTrainingDataMissing); return; + } // Observation trigger always gets prediction time from cached partial // tensor. @@ -586,12 +638,6 @@ } } - RecordTrainingDataCollectionEvent( - info.segment_id(), - is_periodic - ? stats::TrainingDataCollectionEvent::kContinousCollectionStart - : stats::TrainingDataCollectionEvent::kImmediateCollectionStart); - return training_request; }
diff --git a/components/segmentation_platform/internal/stats.h b/components/segmentation_platform/internal/stats.h index de97980..3e06dd1 100644 --- a/components/segmentation_platform/internal/stats.h +++ b/components/segmentation_platform/internal/stats.h
@@ -256,7 +256,17 @@ kPartialDataNotAllowed = 7, kContinousCollectionStart = 8, kContinousCollectionSuccess = 9, - kMaxValue = kContinousCollectionSuccess, + kCollectAndStoreInputsSuccess = 10, + kObservationTimeReached = 11, + kDelayedTaskPosted = 12, + kImmediateObservationPosted = 13, + kWaitingForNonDelayedTrigger = 14, + kHistogramTriggerHit = 15, + kNoSegmentInfo = 16, + kDisallowedForRecording = 17, + kObservationDisallowed = 18, + kTrainingDataMissing = 19, + kMaxValue = kTrainingDataMissing, }; // Records analytics for training data collection.
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 8c56bcb..3ac97b6 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2481,6 +2481,7 @@ deps += [ "//third_party/abseil-cpp:absl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_cpp", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_cpp_hlcpp_conversion", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec:fuchsia.mediacodec_hlcpp", "//third_party/fuchsia-sdk/sdk/pkg/inspect", "//third_party/fuchsia-sdk/sdk/pkg/sys_inspect_cpp",
diff --git a/content/browser/accessibility/browser_accessibility_fuchsia.cc b/content/browser/accessibility/browser_accessibility_fuchsia.cc index b0b3a01..c2f033c1 100644 --- a/content/browser/accessibility/browser_accessibility_fuchsia.cc +++ b/content/browser/accessibility/browser_accessibility_fuchsia.cc
@@ -4,7 +4,7 @@ #include "content/browser/accessibility/browser_accessibility_fuchsia.h" -#include <lib/ui/scenic/cpp/commands.h> +#include <fidl/fuchsia.accessibility.semantics/cpp/hlcpp_conversion.h> #include "base/fuchsia/fuchsia_logging.h" #include "content/browser/accessibility/browser_accessibility_manager_fuchsia.h" @@ -403,7 +403,8 @@ if (!GetAccessibilityBridge()) return; - GetAccessibilityBridge()->UpdateNode(ToFuchsiaNodeData()); + GetAccessibilityBridge()->UpdateNode( + fidl::NaturalToHLCPP(ToFuchsiaNodeData())); } void BrowserAccessibilityFuchsia::DeleteNode() {
diff --git a/content/browser/accessibility/browser_accessibility_manager_fuchsia_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_fuchsia_unittest.cc index 98ef33b..2205e34 100644 --- a/content/browser/accessibility/browser_accessibility_manager_fuchsia_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_manager_fuchsia_unittest.cc
@@ -64,7 +64,7 @@ ~MockAccessibilityBridge() override = default; // ui::AccessibilityBridgeFuchsia overrides. - void UpdateNode(fuchsia_accessibility_semantics::Node node) override { + void UpdateNode(fuchsia::accessibility::semantics::Node node) override { node_updates_.push_back(std::move(node)); } @@ -89,7 +89,7 @@ device_scale_factor_ = device_scale_factor; } - const std::vector<fuchsia_accessibility_semantics::Node>& node_updates() { + const std::vector<fuchsia::accessibility::semantics::Node>& node_updates() { return node_updates_; } const std::vector<uint32_t>& node_deletions() { return node_deletions_; } @@ -111,7 +111,7 @@ private: float device_scale_factor_ = 1.f; - std::vector<fuchsia_accessibility_semantics::Node> node_updates_; + std::vector<fuchsia::accessibility::semantics::Node> node_updates_; std::vector<uint32_t> node_deletions_; std::map<int /* hit test request id */, absl::optional<uint32_t> /* hit test result */> @@ -202,12 +202,11 @@ // Node 1 is the root of the root tree, so its fuchsia ID should be 0. EXPECT_EQ(node_updates[1].node_id(), node_1->GetFuchsiaNodeID()); - ASSERT_EQ(node_updates[1].child_ids()->size(), 1u); - EXPECT_EQ(node_updates[1].child_ids().value()[0], - node_2->GetFuchsiaNodeID()); + ASSERT_EQ(node_updates[1].child_ids().size(), 1u); + EXPECT_EQ(node_updates[1].child_ids()[0], node_2->GetFuchsiaNodeID()); // Node 2 is NOT the root, so its fuchsia ID should be its AXUniqueID. - EXPECT_EQ(node_updates[2].node_id().value(), node_2->GetFuchsiaNodeID()); + EXPECT_EQ(node_updates[2].node_id(), node_2->GetFuchsiaNodeID()); } } @@ -282,7 +281,7 @@ manager_->ax_tree()->Unserialize(initial_state); { - const std::vector<fuchsia_accessibility_semantics::Node>& node_updates = + const std::vector<fuchsia::accessibility::semantics::Node>& node_updates = mock_accessibility_bridge_->node_updates(); ASSERT_EQ(node_updates.size(), 2u); } @@ -300,20 +299,19 @@ ToBrowserAccessibilityFuchsia(manager_->GetFromID(2)); ASSERT_TRUE(node_2); - const std::vector<fuchsia_accessibility_semantics::Node>& node_updates = + const std::vector<fuchsia::accessibility::semantics::Node>& node_updates = mock_accessibility_bridge_->node_updates(); ASSERT_EQ(node_updates.size(), 3u); - const fuchsia_accessibility_semantics::Node& node_update = + const fuchsia::accessibility::semantics::Node& node_update = node_updates.back(); EXPECT_EQ(node_update.node_id(), static_cast<uint32_t>(node_2->GetFuchsiaNodeID())); - ASSERT_TRUE(node_update.location()); - const fuchsia_ui_gfx::BoundingBox& location = - node_update.location().value(); - EXPECT_EQ(location.min().x(), 1); - EXPECT_EQ(location.min().y(), 2); - EXPECT_EQ(location.max().x(), 4); - EXPECT_EQ(location.max().y(), 6); + ASSERT_TRUE(node_update.has_location()); + const fuchsia::ui::gfx::BoundingBox& location = node_update.location(); + EXPECT_EQ(location.min.x, 1); + EXPECT_EQ(location.min.y, 2); + EXPECT_EQ(location.max.x, 4); + EXPECT_EQ(location.max.y, 6); } } @@ -360,14 +358,13 @@ } { - const std::vector<fuchsia_accessibility_semantics::Node>& node_updates = + const std::vector<fuchsia::accessibility::semantics::Node>& node_updates = mock_accessibility_bridge_->node_updates(); ASSERT_FALSE(node_updates.empty()); - EXPECT_EQ(node_updates.back().node_id().value(), - node_1->GetFuchsiaNodeID()); - ASSERT_TRUE(node_updates.back().states()); - ASSERT_TRUE(node_updates.back().states()->has_input_focus().has_value()); - EXPECT_TRUE(node_updates.back().states()->has_input_focus().value()); + EXPECT_EQ(node_updates.back().node_id(), node_1->GetFuchsiaNodeID()); + ASSERT_TRUE(node_updates.back().has_states()); + ASSERT_TRUE(node_updates.back().states().has_has_input_focus()); + EXPECT_TRUE(node_updates.back().states().has_input_focus()); } // Set focus to node 2, and check that focus was updated from node 1 to node @@ -385,20 +382,19 @@ } { - const std::vector<fuchsia_accessibility_semantics::Node>& node_updates = + const std::vector<fuchsia::accessibility::semantics::Node>& node_updates = mock_accessibility_bridge_->node_updates(); ASSERT_GT(node_updates.size(), 2u); - const fuchsia_accessibility_semantics::Node& old_focus_node = + const fuchsia::accessibility::semantics::Node& old_focus_node = node_updates[node_updates.size() - 2]; - EXPECT_EQ(old_focus_node.node_id().value(), node_1->GetFuchsiaNodeID()); - ASSERT_TRUE(old_focus_node.states()); - ASSERT_TRUE(old_focus_node.states()->has_input_focus().has_value()); - EXPECT_FALSE(old_focus_node.states()->has_input_focus().value()); - EXPECT_EQ(node_updates.back().node_id().value(), - node_2->GetFuchsiaNodeID()); - ASSERT_TRUE(node_updates.back().states()); - ASSERT_TRUE(node_updates.back().states()->has_input_focus().has_value()); - EXPECT_TRUE(node_updates.back().states()->has_input_focus().value()); + EXPECT_EQ(old_focus_node.node_id(), node_1->GetFuchsiaNodeID()); + ASSERT_TRUE(old_focus_node.has_states()); + ASSERT_TRUE(old_focus_node.states().has_has_input_focus()); + EXPECT_FALSE(old_focus_node.states().has_input_focus()); + EXPECT_EQ(node_updates.back().node_id(), node_2->GetFuchsiaNodeID()); + ASSERT_TRUE(node_updates.back().has_states()); + ASSERT_TRUE(node_updates.back().states().has_has_input_focus()); + EXPECT_TRUE(node_updates.back().states().has_input_focus()); } }
diff --git a/content/browser/compute_pressure/compute_pressure_unittest.cc b/content/browser/compute_pressure/compute_pressure_unittest.cc index 168ca3d..e98baee1 100644 --- a/content/browser/compute_pressure/compute_pressure_unittest.cc +++ b/content/browser/compute_pressure/compute_pressure_unittest.cc
@@ -18,6 +18,7 @@ #include "content/test/test_web_contents.h" #include "services/device/public/cpp/test/scoped_pressure_manager_overrider.h" #include "services/device/public/mojom/pressure_manager.mojom.h" +#include "services/device/public/mojom/pressure_update.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/permissions_policy/permissions_policy.h" @@ -27,6 +28,7 @@ namespace content { using device::mojom::PressureFactor; +using device::mojom::PressureSource; using device::mojom::PressureState; using device::mojom::PressureStatus; using device::mojom::PressureUpdate; @@ -48,9 +50,10 @@ PressureManagerSync& operator=(const PressureManagerSync&) = delete; PressureStatus AddClient( - mojo::PendingRemote<device::mojom::PressureClient> client) { + mojo::PendingRemote<device::mojom::PressureClient> client, + PressureSource source) { base::test::TestFuture<PressureStatus> future; - manager_->AddClient(std::move(client), future.GetCallback()); + manager_->AddClient(std::move(client), source, future.GetCallback()); return future.Get(); } @@ -190,13 +193,13 @@ TEST_F(ComputePressureTest, AddClient) { FakePressureClient client; - ASSERT_EQ( - pressure_manager_sync_->AddClient(client.BindNewPipeAndPassRemote()), - PressureStatus::kOk); + ASSERT_EQ(pressure_manager_sync_->AddClient(client.BindNewPipeAndPassRemote(), + PressureSource::kCpu), + PressureStatus::kOk); const base::Time time = base::Time::Now(); - PressureUpdate update(PressureState::kNominal, {PressureFactor::kThermal}, - time); + PressureUpdate update(PressureSource::kCpu, PressureState::kNominal, + {PressureFactor::kThermal}, time); pressure_manager_overrider_->UpdateClients(update); client.WaitForUpdate(); ASSERT_EQ(client.updates().size(), 1u); @@ -205,12 +208,12 @@ TEST_F(ComputePressureTest, UpdatePressureFactors) { FakePressureClient client; - ASSERT_EQ( - pressure_manager_sync_->AddClient(client.BindNewPipeAndPassRemote()), - PressureStatus::kOk); + ASSERT_EQ(pressure_manager_sync_->AddClient(client.BindNewPipeAndPassRemote(), + PressureSource::kCpu), + PressureStatus::kOk); const base::Time time = base::Time::Now(); - PressureUpdate update1(PressureState::kNominal, + PressureUpdate update1(PressureSource::kCpu, PressureState::kNominal, {PressureFactor::kPowerSupply}, time); pressure_manager_overrider_->UpdateClients(update1); @@ -220,7 +223,7 @@ client.updates().clear(); PressureUpdate update2( - PressureState::kCritical, + PressureSource::kCpu, PressureState::kCritical, {PressureFactor::kThermal, PressureFactor::kPowerSupply}, time + kSampleInterval); pressure_manager_overrider_->UpdateClients(update2); @@ -229,7 +232,8 @@ EXPECT_EQ(client.updates()[0], update2); client.updates().clear(); - PressureUpdate update3(PressureState::kCritical, {PressureFactor::kThermal}, + PressureUpdate update3(PressureSource::kCpu, PressureState::kCritical, + {PressureFactor::kThermal}, time + kSampleInterval * 2); pressure_manager_overrider_->UpdateClients(update3); client.WaitForUpdate(); @@ -242,9 +246,9 @@ pressure_manager_overrider_->set_is_supported(false); FakePressureClient client; - EXPECT_EQ( - pressure_manager_sync_->AddClient(client.BindNewPipeAndPassRemote()), - PressureStatus::kNotSupported); + EXPECT_EQ(pressure_manager_sync_->AddClient(client.BindNewPipeAndPassRemote(), + PressureSource::kCpu), + PressureStatus::kNotSupported); } TEST_F(ComputePressureTest, InsecureOrigin) {
diff --git a/content/browser/gpu/browser_child_process_backgrounded_bridge.h b/content/browser/gpu/browser_child_process_backgrounded_bridge.h index 3bbf76be..015b167 100644 --- a/content/browser/gpu/browser_child_process_backgrounded_bridge.h +++ b/content/browser/gpu/browser_child_process_backgrounded_bridge.h
@@ -5,7 +5,7 @@ #ifndef CONTENT_BROWSER_GPU_BROWSER_CHILD_PROCESS_BACKGROUNDED_BRIDGE_H_ #define CONTENT_BROWSER_GPU_BROWSER_CHILD_PROCESS_BACKGROUNDED_BRIDGE_H_ -#include <objc/objc.h> +#include <memory> #include "base/memory/raw_ptr.h" #include "base/process/port_provider_mac.h" @@ -44,10 +44,8 @@ base::ScopedObservation<base::PortProvider, base::PortProvider::Observer> scoped_port_provider_observer_{this}; - // Registration IDs for NSApplicationDidBecomeActiveNotification and - // NSApplicationDidResignActiveNotification. - id did_become_active_observer_ = nil; - id did_resign_active_observer_ = nil; + struct ObjCStorage; + std::unique_ptr<ObjCStorage> objc_storage_; }; } // namespace content
diff --git a/content/browser/gpu/browser_child_process_backgrounded_bridge.mm b/content/browser/gpu/browser_child_process_backgrounded_bridge.mm index f4f3a52..759e9f2d 100644 --- a/content/browser/gpu/browser_child_process_backgrounded_bridge.mm +++ b/content/browser/gpu/browser_child_process_backgrounded_bridge.mm
@@ -7,6 +7,8 @@ #import <AppKit/AppKit.h> #import <Foundation/Foundation.h> +#include <memory> + #include "base/process/process.h" #include "content/browser/browser_child_process_host_impl.h" #include "content/public/browser/child_process_data.h" @@ -19,9 +21,16 @@ } // namespace +struct BrowserChildProcessBackgroundedBridge::ObjCStorage { + // Registration IDs for NSApplicationDidBecomeActiveNotification and + // NSApplicationDidResignActiveNotification. + id did_become_active_observer_ = nil; + id did_resign_active_observer_ = nil; +}; + BrowserChildProcessBackgroundedBridge::BrowserChildProcessBackgroundedBridge( BrowserChildProcessHostImpl* process) - : process_(process) { + : process_(process), objc_storage_(std::make_unique<ObjCStorage>()) { base::PortProvider* port_provider = BrowserChildProcessHost::GetPortProvider(); if (port_provider->TaskForPid(process_->GetData().GetProcess().Pid()) != @@ -36,13 +45,13 @@ BrowserChildProcessBackgroundedBridge:: ~BrowserChildProcessBackgroundedBridge() { - if (did_become_active_observer_) { + if (objc_storage_->did_become_active_observer_) { [NSNotificationCenter.defaultCenter - removeObserver:did_become_active_observer_]; + removeObserver:objc_storage_->did_become_active_observer_]; } - if (did_resign_active_observer_) { + if (objc_storage_->did_resign_active_observer_) { [NSNotificationCenter.defaultCenter - removeObserver:did_resign_active_observer_]; + removeObserver:objc_storage_->did_resign_active_observer_]; } } @@ -78,20 +87,22 @@ // process becomes foreground and background, respectively. The blocks // implicity captures `this`. It is safe to do so since the subscriptions are // removed in the destructor - did_become_active_observer_ = [NSNotificationCenter.defaultCenter - addObserverForName:NSApplicationDidBecomeActiveNotification - object:nil - queue:nil - usingBlock:^(NSNotification* notification) { - OnBrowserProcessForegrounded(); - }]; - did_resign_active_observer_ = [NSNotificationCenter.defaultCenter - addObserverForName:NSApplicationDidResignActiveNotification - object:nil - queue:nil - usingBlock:^(NSNotification* notification) { - OnBrowserProcessBackgrounded(); - }]; + objc_storage_->did_become_active_observer_ = + [NSNotificationCenter.defaultCenter + addObserverForName:NSApplicationDidBecomeActiveNotification + object:nil + queue:nil + usingBlock:^(NSNotification* notification) { + OnBrowserProcessForegrounded(); + }]; + objc_storage_->did_resign_active_observer_ = + [NSNotificationCenter.defaultCenter + addObserverForName:NSApplicationDidResignActiveNotification + object:nil + queue:nil + usingBlock:^(NSNotification* notification) { + OnBrowserProcessBackgrounded(); + }]; } void BrowserChildProcessBackgroundedBridge::OnReceivedTaskPort(
diff --git a/content/browser/media/stable_video_decoder_factory.cc b/content/browser/media/stable_video_decoder_factory.cc index 0e4ae5b6..682b38d 100644 --- a/content/browser/media/stable_video_decoder_factory.cc +++ b/content/browser/media/stable_video_decoder_factory.cc
@@ -117,6 +117,12 @@ receiver) { DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); + if (gpu_feature_info_ + ->status_values[gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] != + gpu::kGpuFeatureStatusEnabled) { + return; + } + #if BUILDFLAG(IS_CHROMEOS_ASH) const bool enable_direct_video_decoder = gpu_preferences_.enable_chromeos_direct_video_decoder;
diff --git a/content/browser/network_service_instance_impl.cc b/content/browser/network_service_instance_impl.cc index 92e2a32..341c0ad 100644 --- a/content/browser/network_service_instance_impl.cc +++ b/content/browser/network_service_instance_impl.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/base_paths.h" +#include "base/check.h" #include "base/command_line.h" #include "base/environment.h" #include "base/feature_list.h" @@ -767,7 +768,6 @@ g_cert_verifier_service_factory_for_testing = nullptr; void RunInProcessCertVerifierServiceFactory( - cert_verifier::mojom::CertVerifierServiceParamsPtr params, mojo::PendingReceiver<cert_verifier::mojom::CertVerifierServiceFactory> receiver) { #if BUILDFLAG(IS_CHROMEOS) @@ -784,7 +784,7 @@ service_factory_slot; service_factory_slot.GetOrCreateValue() = std::make_unique<cert_verifier::CertVerifierServiceFactoryImpl>( - std::move(params), std::move(receiver)); + std::move(receiver)); } // Owns the CertVerifierServiceFactory used by the browser. @@ -811,8 +811,6 @@ factory_remote_storage = GetCertVerifierServiceFactoryRemoteStorage(); if (!factory_remote_storage.is_bound() || !factory_remote_storage.is_connected()) { - cert_verifier::mojom::CertVerifierServiceParamsPtr service_params = - GetContentClient()->browser()->GetCertVerifierServiceParams(); factory_remote_storage.reset(); #if BUILDFLAG(IS_CHROMEOS) // In-process CertVerifierService in Ash and Lacros should run on the IO @@ -822,17 +820,26 @@ GetIOThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&RunInProcessCertVerifierServiceFactory, - std::move(service_params), factory_remote_storage.BindNewPipeAndPassReceiver())); #else RunInProcessCertVerifierServiceFactory( - std::move(service_params), factory_remote_storage.BindNewPipeAndPassReceiver()); #endif } return factory_remote_storage.get(); } +mojo::Remote<cert_verifier::mojom::CertVerifierServiceFactory>& +GetCertVerifierServiceFactoryRemoteForTesting() { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + // The Remote isn't used if g_cert_verifier_service_factory_for_testing is + // registered, so any test trying to do both is doing something wrong. + CHECK(!g_cert_verifier_service_factory_for_testing); + + return GetCertVerifierServiceFactoryRemoteStorage(); +} + network::mojom::CertVerifierServiceRemoteParamsPtr GetCertVerifierParams( cert_verifier::mojom::CertVerifierCreationParamsPtr cert_verifier_creation_params) {
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index b789b7b..bf19525f 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -553,11 +553,6 @@ return GeneratedCodeCacheSettings(false, 0, base::FilePath()); } -cert_verifier::mojom::CertVerifierServiceParamsPtr -ContentBrowserClient::GetCertVerifierServiceParams() { - return nullptr; -} - void ContentBrowserClient::AllowCertificateError( WebContents* web_contents, int cert_error,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 57ffe3e..3a843b83 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -974,13 +974,6 @@ virtual GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( BrowserContext* context); - // Allows the embedder to control initialization of the - // CertVerifierServiceFactory. May return nullptr to use defaults. This must - // return the same parameters for the lifetime of the process. Will be called - // when the CertVerifierService is created or re-created. - virtual cert_verifier::mojom::CertVerifierServiceParamsPtr - GetCertVerifierServiceParams(); - // Informs the embedder that a certificate error has occurred. If // |overridable| is true and if |strict_enforcement| is false, the user // can ignore the error and continue. The embedder can call the callback
diff --git a/content/public/browser/network_service_instance.h b/content/public/browser/network_service_instance.h index 705188d..27fa98b 100644 --- a/content/public/browser/network_service_instance.h +++ b/content/public/browser/network_service_instance.h
@@ -10,6 +10,7 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "content/common/content_export.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom-forward.h" #include "services/network/public/cpp/network_connection_tracker.h" #include "services/network/public/mojom/network_context.mojom-forward.h" @@ -104,6 +105,12 @@ CONTENT_EXPORT cert_verifier::mojom::CertVerifierServiceFactory* GetCertVerifierServiceFactory(); +// Returns the |mojo::Remote<CertVerifierServiceFactory>|. For testing only. +// Must only be called on the UI thread. +CONTENT_EXPORT +mojo::Remote<cert_verifier::mojom::CertVerifierServiceFactory>& +GetCertVerifierServiceFactoryRemoteForTesting(); + // Convenience function to create a NetworkContext from the given set of // |params|. Any creation of network contexts should be done through this // function.
diff --git a/content/public/test/test_cert_verifier_service_factory.cc b/content/public/test/test_cert_verifier_service_factory.cc index d6836a0..b5b542f1 100644 --- a/content/public/test/test_cert_verifier_service_factory.cc +++ b/content/public/test/test_cert_verifier_service_factory.cc
@@ -53,11 +53,6 @@ captured_params_.push_front(std::move(params)); } -void TestCertVerifierServiceFactoryImpl::GetServiceParamsForTesting( - GetServiceParamsForTestingCallback callback) { - delegate_remote_->GetServiceParamsForTesting(std::move(callback)); -} - #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) void TestCertVerifierServiceFactoryImpl::UpdateChromeRootStore( mojom::ChromeRootStorePtr new_root_store, @@ -100,10 +95,7 @@ base::SequencedTaskRunner::GetCurrentDefault() #endif ); - delegate_->Init(content::GetContentClientForTesting() - ->browser() - ->GetCertVerifierServiceParams(), - delegate_remote_.BindNewPipeAndPassReceiver()); + delegate_->Init(delegate_remote_.BindNewPipeAndPassReceiver()); } TestCertVerifierServiceFactoryImpl::DelegateOwner::DelegateOwner( @@ -113,17 +105,16 @@ TestCertVerifierServiceFactoryImpl::DelegateOwner::~DelegateOwner() = default; void TestCertVerifierServiceFactoryImpl::DelegateOwner::Init( - mojom::CertVerifierServiceParamsPtr params, mojo::PendingReceiver<cert_verifier::mojom::CertVerifierServiceFactory> receiver) { if (!owning_task_runner()->RunsTasksInCurrentSequence()) { owning_task_runner()->PostTask( - FROM_HERE, base::BindOnce(&DelegateOwner::Init, this, std::move(params), - std::move(receiver))); + FROM_HERE, + base::BindOnce(&DelegateOwner::Init, this, std::move(receiver))); return; } - delegate_ = std::make_unique<CertVerifierServiceFactoryImpl>( - std::move(params), std::move(receiver)); + delegate_ = + std::make_unique<CertVerifierServiceFactoryImpl>(std::move(receiver)); } } // namespace cert_verifier
diff --git a/content/public/test/test_cert_verifier_service_factory.h b/content/public/test/test_cert_verifier_service_factory.h index 5bb080e..87e8b8d 100644 --- a/content/public/test/test_cert_verifier_service_factory.h +++ b/content/public/test/test_cert_verifier_service_factory.h
@@ -50,8 +50,6 @@ mojo::PendingReceiver<mojom::CertVerifierService> receiver, mojo::PendingRemote<mojom::CertVerifierServiceClient> client, mojom::CertVerifierCreationParamsPtr creation_params) override; - void GetServiceParamsForTesting( - GetServiceParamsForTestingCallback callback) override; #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) void UpdateChromeRootStore(mojom::ChromeRootStorePtr new_root_store, @@ -77,7 +75,6 @@ scoped_refptr<base::SequencedTaskRunner> owning_task_runner); void Init( - mojom::CertVerifierServiceParamsPtr params, mojo::PendingReceiver<cert_verifier::mojom::CertVerifierServiceFactory> receiver);
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 2f88259..bb4395ae 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -2954,7 +2954,10 @@ } if (is_fuchsia) { - deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_cpp" ] + deps += [ + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_cpp", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_hlcpp", + ] } if (enable_printing) {
diff --git a/docs/mac/mixing_cpp_and_objc.md b/docs/mac/mixing_cpp_and_objc.md new file mode 100644 index 0000000..b0de2ce --- /dev/null +++ b/docs/mac/mixing_cpp_and_objc.md
@@ -0,0 +1,109 @@ +# Mixing C++ and Objective-C + +The Mac is in a unique position of having most of its relevant UI APIs be in a +different language than the one used for its core code. Navigating boundaries +between C++ and Objective-C can be tricky. + +## Use Objective-C++ + +Using Objective-C++ works well for Mac-only implementation files. If a file is +named with a `.mm` extension, then it will be compiled as an Objective-C++ file. +Within such a file usage of Objective-C and C++ can be intermixed. + +If Objective-C++ works in the context needed, it is the preferred way to +accomplish mixing of C++ and Objective-C. + +## Use the pimpl idiom + +The [pimpl idiom](https://en.wikipedia.org/wiki/Opaque_pointer#C++) is a +standard way to hide the implementation of a C++ class from its users, exposing +nothing but an implementation pointer in the header file. Usually it is used for +compatibility (e.g. hiding implementation details), but it's useful in Chromium +for hiding the Objective-C implementation details in the `.mm` implementation +file and removing them from the `.h` file which might need to be included in a +different `.cc` implementation file and which thus cannot have any Objective-C +in it, even in a `private:` block. + +The standard boilerplate for doing this is named +[`ObjCStorage`](https://source.chromium.org/search?q=ObjCStorage&ss=chromium). + +In the header file, a nested struct is forward-declared for use by a +`std::unique_ptr`: + +``` +class UtilityObjectMac { + // ... + private: + struct ObjCStorage; + std::unique_ptr<ObjCStorage> objc_storage_; +}; +``` + +and in the implementation `.mm` file, have that nested class host all the Obj-C +instance variables: + +``` +struct UtilityObjectMac::ObjCStorage { + id appkit_token_; + NSWindow* window_; +}; + +UtilityObjectMac::UtilityObjectMac() + : objc_storage_(std::make_unique<ObjCStorage>()) { + objc_storage_->appkit_token_ = [NSFramework registerTheThing: //... + // ... +``` + +This moves all of the Objective-C code into an Objective-C++ file at the cost of +a secondary allocation and indirection on use. + +## Double-declaration (dangerous) + +If none of these techniques will work, a double-declaration can be used. An +example can be seen in +[native_widget_types.h](https://source.chromium.org/chromium/chromium/src/+/main:ui/gfx/native_widget_types.h): + +``` +#ifdef __OBJC__ +@class NSCursor; +@class NSEvent; +@class NSFont; +@class NSImage; +@class NSView; +@class NSWindow; +@class NSTextField; +#else +class NSCursor; +class NSEvent; +class NSFont; +class NSImage; +class NSView; +class NSWindow; +class NSTextField; +#endif // __OBJC__ +``` + +With this double-declaration, these types can be used from both C++ and +Objective-C. However, the price that is paid is that this is a (mostly) benign +violation of the [ODR](https://en.wikipedia.org/wiki/One_Definition_Rule) and +thus should be avoided if possible. + +Specifically, this can get dangerous with Objective-C ARC enabled, where a +pointer to a type declared this way will be treated by C++ as a raw pointer +while it will be treated by Objective-C as a smart pointer with retain/release +semantics. + +Because of Chromium's history as a non-ARC app, the approach of using +double-declarations was found to be more acceptable of a tradeoff than it is +nowadays, so there is a lot of double-declaration. Revising code to remove +double-declaration improves the code; please do so when it makes sense. + +Do not include `<objc/objc.h>`. It has all the pitfalls of double-declaration +for the `id` type (note that even though it defines `id` as `struct +objc_object*`, the Objective-C compiler does not see them as equivalent), but +has the additional pitfall of defining away the ARC ownership annotations if not +compiling with Objective-C ARC. The inclusion of it is therefore banned, as it +causes conflicts if included in header files, and while C++ implementation files +should not be involving themselves with Objective-C types anyway, Objective-C +implementation files implicitly have it included through their inclusion of +framework headers.
diff --git a/fuchsia_web/webengine/BUILD.gn b/fuchsia_web/webengine/BUILD.gn index f48f15a..16da102e 100644 --- a/fuchsia_web/webengine/BUILD.gn +++ b/fuchsia_web/webengine/BUILD.gn
@@ -243,7 +243,6 @@ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.settings:fuchsia.settings_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.gfx:fuchsia.ui.gfx_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.scenic:fuchsia.ui.scenic_hlcpp", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.views:fuchsia.ui.views_cpp_hlcpp_conversion", "//third_party/fuchsia-sdk/sdk/pkg/component_incoming_cpp", "//third_party/fuchsia-sdk/sdk/pkg/fit-promise", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
diff --git a/fuchsia_web/webengine/browser/frame_impl.cc b/fuchsia_web/webengine/browser/frame_impl.cc index 109b2512..094b1318 100644 --- a/fuchsia_web/webengine/browser/frame_impl.cc +++ b/fuchsia_web/webengine/browser/frame_impl.cc
@@ -7,7 +7,6 @@ #include <fidl/fuchsia.logger/cpp/fidl.h> #include <fidl/fuchsia.logger/cpp/hlcpp_conversion.h> #include <fidl/fuchsia.media.sessions2/cpp/hlcpp_conversion.h> -#include <fidl/fuchsia.ui.views/cpp/hlcpp_conversion.h> #include <fuchsia/ui/gfx/cpp/fidl.h> #include <lib/fpromise/result.h> #include <lib/sys/cpp/component_context.h> @@ -798,7 +797,7 @@ // TODO(crbug.com/1291613): Replace callbacks with an interface that // FrameImpl implements. accessibility_bridge_ = std::make_unique<ui::AccessibilityBridgeFuchsiaImpl>( - root_window(), fidl::HLCPPToNatural(window_tree_host_->CreateViewRef()), + root_window(), window_tree_host_->CreateViewRef(), base::BindRepeating(&FrameImpl::SetAccessibilityEnabled, base::Unretained(this)), base::BindRepeating(&FrameImpl::OnAccessibilityError,
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm index 0ccd7552..a5d72b0 100644 --- a/ios/chrome/browser/passwords/password_controller_unittest.mm +++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -52,7 +52,9 @@ #import "ios/web/public/js_messaging/web_frames_manager.h" #import "ios/web/public/navigation/navigation_item.h" #import "ios/web/public/navigation/navigation_manager.h" +#import "ios/web/public/test/fakes/fake_browser_state.h" #import "ios/web/public/test/fakes/fake_navigation_context.h" +#import "ios/web/public/test/fakes/fake_web_client.h" #import "ios/web/public/test/fakes/fake_web_frame.h" #import "ios/web/public/test/fakes/fake_web_frames_manager.h" #import "ios/web/public/test/fakes/fake_web_state.h" @@ -1240,9 +1242,19 @@ // The test cases below need a different SetUp. class PasswordControllerTestSimple : public PlatformTest { public: - PasswordControllerTestSimple() {} + PasswordControllerTestSimple() + : task_environment_(web::WebTaskEnvironment::Options::DEFAULT), + web_client_(std::make_unique<web::FakeWebClient>()), + browser_state_(std::make_unique<web::FakeBrowserState>()) { + web_state_.SetBrowserState(browser_state_.get()); + } - ~PasswordControllerTestSimple() override { store_->ShutdownOnUIThread(); } + ~PasswordControllerTestSimple() override { + // Ensure the password manager callbacks complete before destruction. + task_environment_.RunUntilIdle(); + + store_->ShutdownOnUIThread(); + } void SetUp() override { // Tests depend on some of these prefs being registered. @@ -1254,8 +1266,22 @@ new testing::NiceMock<password_manager::MockPasswordStoreInterface>(); ON_CALL(*store_, IsAbleToSavePasswords).WillByDefault(Return(true)); + web::test::OverrideJavaScriptFeatures( + browser_state_.get(), + {autofill::FormUtilJavaScriptFeature::GetInstance(), + password_manager::PasswordManagerJavaScriptFeature::GetInstance()}); + UniqueIDDataTabHelper::CreateForWebState(&web_state_); + web::ContentWorld content_world = + password_manager::PasswordManagerJavaScriptFeature::GetInstance() + ->GetSupportedContentWorld(); + + auto web_frames_manager = std::make_unique<web::FakeWebFramesManager>(); + web_frames_manager_ = web_frames_manager.get(); + web_state_.SetWebFramesManager(content_world, + std::move(web_frames_manager)); + passwordController_ = CreatePasswordController(&pref_service_, &web_state_, store_.get(), &weak_client_); passwordController_.passwordManager->set_leak_factory( @@ -1267,20 +1293,13 @@ ON_CALL(*store_, GetLogins) .WillByDefault(WithArg<1>(InvokeEmptyConsumerWithForms(store_.get()))); - - web::ContentWorld content_world = - password_manager::PasswordManagerJavaScriptFeature::GetInstance() - ->GetSupportedContentWorld(); - - auto web_frames_manager = std::make_unique<web::FakeWebFramesManager>(); - web_frames_manager_ = web_frames_manager.get(); - web_state_.SetWebFramesManager(content_world, - std::move(web_frames_manager)); } - base::test::TaskEnvironment task_environment_; + web::WebTaskEnvironment task_environment_; + web::ScopedTestingWebClient web_client_; sync_preferences::TestingPrefServiceSyncable pref_service_; + std::unique_ptr<web::FakeBrowserState> browser_state_; PasswordController* passwordController_; scoped_refptr<password_manager::MockPasswordStoreInterface> store_; MockPasswordManagerClient* weak_client_; @@ -1295,6 +1314,7 @@ passwordController_.sharedPasswordController; auto web_frame = web::FakeWebFrame::CreateMainWebFrame(GURL::EmptyGURL()); + web_frame->set_browser_state(browser_state_.get()); web::WebFrame* main_web_frame = web_frame.get(); web_frames_manager_->AddWebFrame(std::move(web_frame));
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift index dfbad51..46cec60 100644 --- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift +++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
@@ -78,11 +78,12 @@ .accessibilityIdentifier(kPopupMenuToolsMenuTableViewId) } } - .animation(nil) .background( Color("destination_highlight_color").opacity(uiConfiguration.highlightDestinationsRow ? 1 : 0) ) - .animation(.linear(duration: kMaterialDuration3)) + .animation( + .linear(duration: kMaterialDuration3), value: uiConfiguration.highlightDestinationsRow + ) .onPreferenceChange(ScrollViewLeadingOffset.self) { newOffset in // Only alert the handler if scroll tracking has started. if let listOffset = listOffset,
diff --git a/media/audio/mac/audio_auhal_mac.cc b/media/audio/mac/audio_auhal_mac.cc index 2c62bde5..ef83b268 100644 --- a/media/audio/mac/audio_auhal_mac.cc +++ b/media/audio/mac/audio_auhal_mac.cc
@@ -39,8 +39,8 @@ kAudioChannelLabel_LeftCenter, kAudioChannelLabel_RightCenter, kAudioChannelLabel_CenterSurround, - kAudioChannelLabel_LeftSurroundDirect, - kAudioChannelLabel_RightSurroundDirect, + kAudioChannelLabel_RearSurroundLeft, + kAudioChannelLabel_RearSurroundRight }; static_assert(0 == LEFT && 1 == RIGHT && 2 == CENTER && 3 == LFE && 4 == BACK_LEFT &&
diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc index 7cfc0bf..07b9919 100644 --- a/media/base/supported_types.cc +++ b/media/base/supported_types.cc
@@ -224,6 +224,11 @@ return true; } #endif // BUILDFLAG(IS_CHROMEOS_LACROS) +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (!base::FeatureList::IsEnabled(kPlatformHEVCDecoderSupport)) { + return false; + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) return GetSupplementalProfileCache()->IsProfileSupported(type.profile); #else return true;
diff --git a/media/cdm/aes_decryptor_unittest.cc b/media/cdm/aes_decryptor_unittest.cc index 0dc2d8b2..23953b6 100644 --- a/media/cdm/aes_decryptor_unittest.cc +++ b/media/cdm/aes_decryptor_unittest.cc
@@ -281,9 +281,9 @@ CdmAdapter::CreateCdmFunc create_cdm_func = CdmModule::GetInstance()->GetCreateCdmFunc(); - std::unique_ptr<CdmAllocator> allocator(new SimpleCdmAllocator()); - std::unique_ptr<CdmAuxiliaryHelper> cdm_helper( - new MockCdmAuxiliaryHelper(std::move(allocator))); + auto allocator = std::make_unique<SimpleCdmAllocator>(); + auto cdm_helper = + std::make_unique<MockCdmAuxiliaryHelper>(std::move(allocator)); CdmAdapter::Create( helper_->CdmConfig(), create_cdm_func, std::move(cdm_helper), base::BindRepeating(&MockCdmClient::OnSessionMessage, @@ -345,22 +345,21 @@ std::unique_ptr<SimpleCdmPromise> CreatePromise( ExpectedResult expected_result) { - std::unique_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>( + auto promise = std::make_unique<CdmCallbackPromise<>>( base::BindOnce(&AesDecryptorTest::OnResolve, base::Unretained(this), expected_result), base::BindOnce(&AesDecryptorTest::OnReject, base::Unretained(this), - expected_result))); + expected_result)); return promise; } std::unique_ptr<NewSessionCdmPromise> CreateSessionPromise( ExpectedResult expected_result) { - std::unique_ptr<NewSessionCdmPromise> promise( - new CdmCallbackPromise<std::string>( - base::BindOnce(&AesDecryptorTest::OnResolveWithSession, - base::Unretained(this), expected_result), - base::BindOnce(&AesDecryptorTest::OnReject, base::Unretained(this), - expected_result))); + auto promise = std::make_unique<CdmCallbackPromise<std::string>>( + base::BindOnce(&AesDecryptorTest::OnResolveWithSession, + base::Unretained(this), expected_result), + base::BindOnce(&AesDecryptorTest::OnReject, base::Unretained(this), + expected_result)); return promise; }
diff --git a/media/cdm/cdm_adapter_unittest.cc b/media/cdm/cdm_adapter_unittest.cc index 043483a..dadc893 100644 --- a/media/cdm/cdm_adapter_unittest.cc +++ b/media/cdm/cdm_adapter_unittest.cc
@@ -140,9 +140,9 @@ // or generates an error. void InitializeWithCdmConfigAndExpect(const CdmConfig& cdm_config, ExpectedResult expected_result) { - std::unique_ptr<CdmAllocator> allocator(new SimpleCdmAllocator()); - std::unique_ptr<StrictMock<MockCdmAuxiliaryHelper>> cdm_helper( - new StrictMock<MockCdmAuxiliaryHelper>(std::move(allocator))); + auto allocator = std::make_unique<SimpleCdmAllocator>(); + auto cdm_helper = std::make_unique<StrictMock<MockCdmAuxiliaryHelper>>( + std::move(allocator)); cdm_helper_ = cdm_helper.get(); CdmAdapter::Create( cdm_config, GetCreateCdmFunc(), std::move(cdm_helper), @@ -291,11 +291,11 @@ EXPECT_CALL(*this, OnReject(_, _, IsNotEmpty())); } - std::unique_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>( + auto promise = std::make_unique<CdmCallbackPromise<>>( base::BindOnce(&CdmAdapterTestWithClearKeyCdm::OnResolve, base::Unretained(this)), base::BindOnce(&CdmAdapterTestWithClearKeyCdm::OnReject, - base::Unretained(this)))); + base::Unretained(this))); return promise; } @@ -310,12 +310,11 @@ EXPECT_CALL(*this, OnReject(_, _, IsNotEmpty())); } - std::unique_ptr<NewSessionCdmPromise> promise( - new CdmCallbackPromise<std::string>( - base::BindOnce(&CdmAdapterTestWithClearKeyCdm::OnResolveWithSession, - base::Unretained(this)), - base::BindOnce(&CdmAdapterTestWithClearKeyCdm::OnReject, - base::Unretained(this)))); + auto promise = std::make_unique<CdmCallbackPromise<std::string>>( + base::BindOnce(&CdmAdapterTestWithClearKeyCdm::OnResolveWithSession, + base::Unretained(this)), + base::BindOnce(&CdmAdapterTestWithClearKeyCdm::OnReject, + base::Unretained(this))); return promise; }
diff --git a/media/cdm/cenc_decryptor.cc b/media/cdm/cenc_decryptor.cc index ce9c4b8e..0f47832 100644 --- a/media/cdm/cenc_decryptor.cc +++ b/media/cdm/cenc_decryptor.cc
@@ -125,7 +125,7 @@ // copy all encrypted subsamples to a contiguous buffer, decrypt them, then // copy the decrypted bytes over the encrypted bytes in the output. // TODO(strobe): attempt to reduce number of memory copies - std::unique_ptr<uint8_t[]> encrypted_bytes(new uint8_t[total_encrypted_size]); + auto encrypted_bytes = std::make_unique<uint8_t[]>(total_encrypted_size); CopySubsamples(subsamples, kSrcContainsClearBytes, reinterpret_cast<const uint8_t*>(sample), encrypted_bytes.get());
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.cc b/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.cc index 2f9b3d4..36aa3112 100644 --- a/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.cc +++ b/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.cc
@@ -33,11 +33,11 @@ // |test_name| is also used as the file name. File name validity tests relies // on this to work. -#define START_TEST_CASE(test_name) \ - do { \ - std::unique_ptr<FileIOTest> test_case( \ - new FileIOTest(create_file_io_cb_, test_name)); \ - CREATE_FILE_IO // Create FileIO for each test case. +#define START_TEST_CASE(test_name) \ + do { \ + auto test_case = \ + std::make_unique<FileIOTest>(create_file_io_cb_, test_name); \ + CREATE_FILE_IO // Create FileIO for each test case. #define ADD_TEST_STEP(type, status, data, data_size) \ test_case->AddTestStep(FileIOTest::type, cdm::FileIOClient::Status::status, \
diff --git a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc index 61f1370..795dcaac 100644 --- a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc +++ b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc
@@ -308,7 +308,7 @@ template <typename HostInterface> ClearKeyCdm::ClearKeyCdm(HostInterface* host, const std::string& key_system) : host_interface_version_(HostInterface::kVersion), - cdm_host_proxy_(new CdmHostProxyImpl<HostInterface>(host)), + cdm_host_proxy_(std::make_unique<CdmHostProxyImpl<HostInterface>>(host)), cdm_(new ClearKeyPersistentSessionCdm( cdm_host_proxy_.get(), base::BindRepeating(&ClearKeyCdm::OnSessionMessage, @@ -363,12 +363,11 @@ return; } - std::unique_ptr<NewSessionCdmPromise> promise( - new CdmCallbackPromise<std::string>( - base::BindOnce(&ClearKeyCdm::OnSessionCreated, base::Unretained(this), - promise_id), - base::BindOnce(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), - promise_id))); + auto promise = std::make_unique<CdmCallbackPromise<std::string>>( + base::BindOnce(&ClearKeyCdm::OnSessionCreated, base::Unretained(this), + promise_id), + base::BindOnce(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), + promise_id)); cdm_->CreateSessionAndGenerateRequest( ToMediaSessionType(session_type), ToEmeInitDataType(init_data_type), std::vector<uint8_t>(init_data, init_data + init_data_size), @@ -399,12 +398,11 @@ DCHECK(allow_persistent_state_); std::string web_session_str(session_id, session_id_length); - std::unique_ptr<NewSessionCdmPromise> promise( - new CdmCallbackPromise<std::string>( - base::BindOnce(&ClearKeyCdm::OnSessionCreated, base::Unretained(this), - promise_id), - base::BindOnce(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), - promise_id))); + auto promise = std::make_unique<CdmCallbackPromise<std::string>>( + base::BindOnce(&ClearKeyCdm::OnSessionCreated, base::Unretained(this), + promise_id), + base::BindOnce(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), + promise_id)); cdm_->LoadSession(ToMediaSessionType(session_type), std::move(web_session_str), std::move(promise)); } @@ -418,11 +416,11 @@ std::string web_session_str(session_id, session_id_length); std::vector<uint8_t> response_vector(response, response + response_size); - std::unique_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>( + auto promise = std::make_unique<CdmCallbackPromise<>>( base::BindOnce(&ClearKeyCdm::OnUpdateSuccess, base::Unretained(this), promise_id, web_session_str), base::BindOnce(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), - promise_id))); + promise_id)); cdm_->UpdateSession(session_id, response_vector, std::move(promise)); } @@ -473,11 +471,11 @@ DVLOG(1) << __func__; std::string web_session_str(session_id, session_id_length); - std::unique_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>( + auto promise = std::make_unique<CdmCallbackPromise<>>( base::BindOnce(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), promise_id), base::BindOnce(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), - promise_id))); + promise_id)); cdm_->CloseSession(std::move(web_session_str), std::move(promise)); } @@ -487,11 +485,11 @@ DVLOG(1) << __func__; std::string web_session_str(session_id, session_id_length); - std::unique_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>( + auto promise = std::make_unique<CdmCallbackPromise<>>( base::BindOnce(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), promise_id), base::BindOnce(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), - promise_id))); + promise_id)); cdm_->RemoveSession(std::move(web_session_str), std::move(promise)); } @@ -499,11 +497,11 @@ const uint8_t* server_certificate_data, uint32_t server_certificate_data_size) { DVLOG(1) << __func__; - std::unique_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>( + auto promise = std::make_unique<CdmCallbackPromise<>>( base::BindOnce(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), promise_id), base::BindOnce(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), - promise_id))); + promise_id)); cdm_->SetServerCertificate( std::vector<uint8_t>( server_certificate_data,
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc index 93027ad..8a0b996 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -255,7 +255,7 @@ *svc_supported = false; for (UINT32 i = 0; i < encoder_count; i++) { - if (!svc_supported && IsSvcSupported(activates[i], codec)) { + if (!*svc_supported && IsSvcSupported(activates[i], codec)) { *svc_supported = true; } activates[i]->Release();
diff --git a/net/cert/cert_verifier.cc b/net/cert/cert_verifier.cc index f87fc15..cfb73ea 100644 --- a/net/cert/cert_verifier.cc +++ b/net/cert/cert_verifier.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/strings/string_util.h" +#include "base/types/optional_util.h" #include "build/build_config.h" #include "net/base/features.h" #include "net/cert/caching_cert_verifier.h" @@ -27,29 +28,25 @@ public: scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc( scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) override { - scoped_refptr<net::CertVerifyProc> verify_proc; + const CertVerifyProcFactory::ImplParams& impl_params) override { #if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - if (!verify_proc && - base::FeatureList::IsEnabled(features::kChromeRootStoreUsed)) { - verify_proc = CertVerifyProc::CreateBuiltinWithChromeRootStore( - std::move(cert_net_fetcher), std::move(crl_set), root_store_data); + if (impl_params.use_chrome_root_store) { + return CertVerifyProc::CreateBuiltinWithChromeRootStore( + std::move(cert_net_fetcher), impl_params.crl_set, + base::OptionalToPtr(impl_params.root_store_data)); } #endif - if (!verify_proc) { #if BUILDFLAG(CHROME_ROOT_STORE_ONLY) - verify_proc = CertVerifyProc::CreateBuiltinWithChromeRootStore( - std::move(cert_net_fetcher), std::move(crl_set), root_store_data); + return CertVerifyProc::CreateBuiltinWithChromeRootStore( + std::move(cert_net_fetcher), impl_params.crl_set, + base::OptionalToPtr(impl_params.root_store_data)); #elif BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) - verify_proc = CertVerifyProc::CreateBuiltinVerifyProc( - std::move(cert_net_fetcher), std::move(crl_set)); + return CertVerifyProc::CreateBuiltinVerifyProc(std::move(cert_net_fetcher), + impl_params.crl_set); #else - verify_proc = CertVerifyProc::CreateSystemVerifyProc( - std::move(cert_net_fetcher), std::move(crl_set)); + return CertVerifyProc::CreateSystemVerifyProc(std::move(cert_net_fetcher), + impl_params.crl_set); #endif - } - return verify_proc; } private: @@ -119,8 +116,7 @@ scoped_refptr<CertNetFetcher> cert_net_fetcher) { auto proc_factory = base::MakeRefCounted<DefaultCertVerifyProcFactory>(); return std::make_unique<MultiThreadedCertVerifier>( - proc_factory->CreateCertVerifyProc(std::move(cert_net_fetcher), - net::CRLSet::BuiltinCRLSet(), nullptr), + proc_factory->CreateCertVerifyProc(std::move(cert_net_fetcher), {}), proc_factory); }
diff --git a/net/cert/cert_verifier.h b/net/cert/cert_verifier.h index 19b2520..026ffc8e 100644 --- a/net/cert/cert_verifier.h +++ b/net/cert/cert_verifier.h
@@ -16,15 +16,14 @@ #include "net/base/hash_value.h" #include "net/base/net_export.h" #include "net/cert/cert_net_fetcher.h" +#include "net/cert/cert_verify_proc.h" #include "net/cert/x509_certificate.h" namespace net { class CertVerifyResult; class CertVerifierWithUpdatableProc; -class CRLSet; class NetLogWithSource; -class ChromeRootStoreData; // CertVerifier represents a service for verifying certificates. // @@ -239,11 +238,10 @@ // A CertVerifier that can update its CertVerifyProc while it is running. class NET_EXPORT CertVerifierWithUpdatableProc : public CertVerifier { public: - // Update the CertVerifyProc with new CRLSet and ChromeRootStoreData. + // Update the CertVerifyProc with a new set of parameters. virtual void UpdateVerifyProcData( scoped_refptr<CertNetFetcher> cert_net_fetcher, - scoped_refptr<CRLSet> crl_set, - const ChromeRootStoreData* root_store_data) = 0; + const net::CertVerifyProcFactory::ImplParams& impl_params) = 0; }; } // namespace net
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc index a9b1d6de..8f4ed6e1 100644 --- a/net/cert/cert_verify_proc.cc +++ b/net/cert/cert_verify_proc.cc
@@ -892,4 +892,21 @@ return false; } +CertVerifyProcFactory::ImplParams::ImplParams() { + crl_set = net::CRLSet::BuiltinCRLSet(); +#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) + use_chrome_root_store = + base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed); +#endif +} + +CertVerifyProcFactory::ImplParams::~ImplParams() = default; + +CertVerifyProcFactory::ImplParams::ImplParams(const ImplParams&) = default; +CertVerifyProcFactory::ImplParams& CertVerifyProcFactory::ImplParams::operator=( + const ImplParams& other) = default; +CertVerifyProcFactory::ImplParams::ImplParams(ImplParams&&) = default; +CertVerifyProcFactory::ImplParams& CertVerifyProcFactory::ImplParams::operator=( + ImplParams&& other) = default; + } // namespace net
diff --git a/net/cert/cert_verify_proc.h b/net/cert/cert_verify_proc.h index f1d698f8..22e6055 100644 --- a/net/cert/cert_verify_proc.h +++ b/net/cert/cert_verify_proc.h
@@ -17,6 +17,10 @@ #include "net/base/net_export.h" #include "net/net_buildflags.h" +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) +#include "net/cert/internal/trust_store_chrome.h" +#endif + namespace net { class CertNetFetcher; @@ -24,7 +28,6 @@ class CRLSet; class NetLogWithSource; class X509Certificate; -class ChromeRootStoreData; typedef std::vector<scoped_refptr<X509Certificate>> CertificateList; // Class to perform certificate path building and verification for various @@ -213,12 +216,35 @@ class NET_EXPORT CertVerifyProcFactory : public base::RefCountedThreadSafe<CertVerifyProcFactory> { public: + // The set of factory parameters that are variable over time, but are + // expected to be consistent between multiple verifiers that are created. For + // example, CertNetFetcher is not in this struct as it is expected that + // different verifiers will have different net fetchers. (There is no + // technical restriction against creating different verifiers with different + // ImplParams, structuring the parameters this way just makes some APIs more + // convenient for the common case.) + struct NET_EXPORT ImplParams { + ImplParams(); + ~ImplParams(); + ImplParams(const ImplParams&); + ImplParams& operator=(const ImplParams& other); + ImplParams(ImplParams&&); + ImplParams& operator=(ImplParams&& other); + + scoped_refptr<CRLSet> crl_set; +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) + absl::optional<net::ChromeRootStoreData> root_store_data; +#endif +#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) + bool use_chrome_root_store; +#endif + }; + // Create a new CertVerifyProc that uses the passed in CRLSet and // ChromeRootStoreData. virtual scoped_refptr<CertVerifyProc> CreateCertVerifyProc( scoped_refptr<CertNetFetcher> cert_net_fetcher, - scoped_refptr<CRLSet> crl_set, - const ChromeRootStoreData* root_store_data) = 0; + const ImplParams& impl_params) = 0; protected: virtual ~CertVerifyProcFactory() = default;
diff --git a/net/cert/multi_threaded_cert_verifier.cc b/net/cert/multi_threaded_cert_verifier.cc index 13cd5f04..dfa1916 100644 --- a/net/cert/multi_threaded_cert_verifier.cc +++ b/net/cert/multi_threaded_cert_verifier.cc
@@ -236,11 +236,10 @@ void MultiThreadedCertVerifier::UpdateVerifyProcData( scoped_refptr<CertNetFetcher> cert_net_fetcher, - scoped_refptr<CRLSet> crl_set, - const ChromeRootStoreData* root_store_data) { + const net::CertVerifyProcFactory::ImplParams& impl_params) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); verify_proc_ = verify_proc_factory_->CreateCertVerifyProc( - std::move(cert_net_fetcher), std::move(crl_set), root_store_data); + std::move(cert_net_fetcher), impl_params); NotifyCertVerifierChanged(); }
diff --git a/net/cert/multi_threaded_cert_verifier.h b/net/cert/multi_threaded_cert_verifier.h index d5a01a1c..368368c 100644 --- a/net/cert/multi_threaded_cert_verifier.h +++ b/net/cert/multi_threaded_cert_verifier.h
@@ -28,7 +28,6 @@ class CertVerifyProc; class CertNetFetcher; class CertVerifyProcFactory; -class ChromeRootStoreData; // MultiThreadedCertVerifier is a CertVerifier implementation that runs // synchronous CertVerifier implementations on worker threads. @@ -58,8 +57,7 @@ void RemoveObserver(Observer* observer) override; void UpdateVerifyProcData( scoped_refptr<CertNetFetcher> cert_net_fetcher, - scoped_refptr<CRLSet> crl_set, - const ChromeRootStoreData* root_store_data) override; + const net::CertVerifyProcFactory::ImplParams& impl_params) override; private: class InternalRequest;
diff --git a/net/cert/multi_threaded_cert_verifier_unittest.cc b/net/cert/multi_threaded_cert_verifier_unittest.cc index ce6577f..a56ee3e 100644 --- a/net/cert/multi_threaded_cert_verifier_unittest.cc +++ b/net/cert/multi_threaded_cert_verifier_unittest.cc
@@ -83,8 +83,7 @@ scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc( scoped_refptr<CertNetFetcher> cert_net_fetcher, - scoped_refptr<CRLSet> crl_set, - const ChromeRootStoreData* root_store_data) override { + const ImplParams& impl_params) override { return mock_verify_proc_; } @@ -313,7 +312,7 @@ EXPECT_CALL(*mock_new_verify_proc_, VerifyInternal(_, _, _, _, _, _, _, _)) .WillRepeatedly( DoAll(SetCertVerifyRevokedResult(), Return(ERR_CERT_REVOKED))); - verifier_->UpdateVerifyProcData(nullptr, nullptr, nullptr); + verifier_->UpdateVerifyProcData(nullptr, {}); EXPECT_EQ(observer_counter.change_count(), 1u); @@ -353,7 +352,7 @@ &verify_result, callback.callback(), &request, NetLogWithSource()); ASSERT_THAT(error, IsError(ERR_IO_PENDING)); EXPECT_TRUE(request); - verifier_->UpdateVerifyProcData(nullptr, nullptr, nullptr); + verifier_->UpdateVerifyProcData(nullptr, {}); error = callback.WaitForResult(); EXPECT_TRUE(IsCertificateError(error)); EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID));
diff --git a/net/cert/trial_comparison_cert_verifier.cc b/net/cert/trial_comparison_cert_verifier.cc index 2e7070c..94d80b2 100644 --- a/net/cert/trial_comparison_cert_verifier.cc +++ b/net/cert/trial_comparison_cert_verifier.cc
@@ -468,21 +468,29 @@ } TrialComparisonCertVerifier::TrialComparisonCertVerifier( - scoped_refptr<CertVerifyProc> primary_verify_proc, - scoped_refptr<CertVerifyProcFactory> primary_verify_proc_factory, - scoped_refptr<CertVerifyProc> trial_verify_proc, - scoped_refptr<CertVerifyProcFactory> trial_verify_proc_factory, + scoped_refptr<CertVerifyProcFactory> verify_proc_factory, + scoped_refptr<CertNetFetcher> cert_net_fetcher, + const CertVerifyProcFactory::ImplParams& impl_params, ReportCallback report_callback) - : report_callback_(std::move(report_callback)), - primary_verifier_(std::make_unique<MultiThreadedCertVerifier>( - primary_verify_proc, - primary_verify_proc_factory)), - primary_reverifier_(std::make_unique<MultiThreadedCertVerifier>( - primary_verify_proc, - primary_verify_proc_factory)), - trial_verifier_(std::make_unique<MultiThreadedCertVerifier>( - trial_verify_proc, - trial_verify_proc_factory)) { + : report_callback_(std::move(report_callback)) { + auto [primary_impl_params, trial_impl_params] = + ProcessImplParams(impl_params); + + primary_verifier_ = std::make_unique<MultiThreadedCertVerifier>( + verify_proc_factory->CreateCertVerifyProc(cert_net_fetcher, + primary_impl_params), + verify_proc_factory); + + primary_reverifier_ = std::make_unique<MultiThreadedCertVerifier>( + verify_proc_factory->CreateCertVerifyProc(cert_net_fetcher, + primary_impl_params), + verify_proc_factory); + + trial_verifier_ = std::make_unique<MultiThreadedCertVerifier>( + verify_proc_factory->CreateCertVerifyProc(cert_net_fetcher, + trial_impl_params), + verify_proc_factory); + primary_verifier_->AddObserver(this); primary_reverifier_->AddObserver(this); trial_verifier_->AddObserver(this); @@ -501,9 +509,18 @@ const NetLogWithSource& net_log) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!trial_allowed()) { - return primary_verifier_->Verify(params, verify_result, std::move(callback), + // Technically, the trial could still be active when + // actual_use_chrome_root_store_=true, just by reversing everything. (Doing + // the trial verifier first and returning that result, then doing the primary + // verifier and comparing.) Probably not worth the trouble though. + if (!trial_allowed() || actual_use_chrome_root_store_) { + if (actual_use_chrome_root_store_) { + return trial_verifier_->Verify(params, verify_result, std::move(callback), out_req, net_log); + } else { + return primary_verifier_->Verify(params, verify_result, + std::move(callback), out_req, net_log); + } } std::unique_ptr<Job> job = @@ -527,32 +544,53 @@ void TrialComparisonCertVerifier::AddObserver( CertVerifier::Observer* observer) { - // Let primary_verifier_ handle the observer lists rather than creating - // another one in TrialComparisonCertVerifier. From the perspective of the - // caller, the primary_verifier is the only one that it would care about - // changes to. + // Delegate the notifications to the wrapped verifiers. We add the observer + // to both `primary_verifier_` and `trial_verifier_` since either one might + // be the one that matters depending on the configuration at the time. This + // does mean the caller will get double notified, but shouldn't really matter + // that much. It would be possible to avoid this by making a notification + // proxy that only forwards notifications from the verifier that is currently + // the "main" one, but it's probably not worth the trouble. + // + // Also this assumes that there is never a case where the + // TrialComparisonCertVerifier itself would change something without the + // wrapped verifiers also generating a notification. primary_verifier_->AddObserver(observer); + trial_verifier_->AddObserver(observer); } void TrialComparisonCertVerifier::RemoveObserver( CertVerifier::Observer* observer) { + trial_verifier_->RemoveObserver(observer); primary_verifier_->RemoveObserver(observer); } void TrialComparisonCertVerifier::UpdateVerifyProcData( scoped_refptr<CertNetFetcher> cert_net_fetcher, - scoped_refptr<CRLSet> crl_set, - const ChromeRootStoreData* root_store_data) { - primary_verifier_->UpdateVerifyProcData(cert_net_fetcher, crl_set, - root_store_data); - primary_reverifier_->UpdateVerifyProcData(cert_net_fetcher, crl_set, - root_store_data); - trial_verifier_->UpdateVerifyProcData(cert_net_fetcher, crl_set, - root_store_data); + const CertVerifyProcFactory::ImplParams& impl_params) { + bool previous_actual_use_chrome_root_store = actual_use_chrome_root_store_; + auto [primary_impl_params, trial_impl_params] = + ProcessImplParams(impl_params); + + // If the only change in the params was to switch the + // `actual_use_chrome_root_store_` value, updating the underlying verifiers + // is unnecessary, but it's probably not worth the trouble to try to avoid + // it. + primary_verifier_->UpdateVerifyProcData(cert_net_fetcher, + primary_impl_params); + primary_reverifier_->UpdateVerifyProcData(cert_net_fetcher, + primary_impl_params); + + trial_verifier_->UpdateVerifyProcData(cert_net_fetcher, trial_impl_params); + // The TrialComparisonCertVerifier is registered as an observer of the // underlying verifiers, and so the OnCertVerifierChanged method should be // triggered to call NotifyJobsOfConfigChange, so it isn't explicitly called - // here. + // here for cases other than the `actual_use_chrome_root_store_` changing. + + if (previous_actual_use_chrome_root_store != actual_use_chrome_root_store_) { + NotifyJobsOfConfigChange(); + } } void TrialComparisonCertVerifier::RemoveJob(Job* job_ptr) { @@ -563,6 +601,18 @@ jobs_.erase(it); } +std::tuple<CertVerifyProcFactory::ImplParams, CertVerifyProcFactory::ImplParams> +TrialComparisonCertVerifier::ProcessImplParams( + const CertVerifyProcFactory::ImplParams& impl_params) { + actual_use_chrome_root_store_ = impl_params.use_chrome_root_store; + + CertVerifyProcFactory::ImplParams primary_impl_params(impl_params); + primary_impl_params.use_chrome_root_store = false; + CertVerifyProcFactory::ImplParams trial_impl_params(impl_params); + trial_impl_params.use_chrome_root_store = true; + return {std::move(primary_impl_params), std::move(trial_impl_params)}; +} + void TrialComparisonCertVerifier::NotifyJobsOfConfigChange() { for (auto& job : jobs_) { job->OnConfigChanged();
diff --git a/net/cert/trial_comparison_cert_verifier.h b/net/cert/trial_comparison_cert_verifier.h index b0306c2..1712a81 100644 --- a/net/cert/trial_comparison_cert_verifier.h +++ b/net/cert/trial_comparison_cert_verifier.h
@@ -19,11 +19,8 @@ #include "net/cert/cert_verifier.h" namespace net { -class CertVerifyProc; class CertVerifyProcFactory; class CertNetFetcher; -class ChromeRootStoreData; -class CRLSet; // TrialComparisonCertVerifier is a CertVerifier that can be used to compare // the results between two different CertVerifyProcs. The results are reported @@ -45,33 +42,35 @@ const net::CertVerifyResult& primary_result, const net::CertVerifyResult& trial_result)>; - // Create a new TrialComparisonCertVerifier. Initially, no trial - // verifications will actually be performed; that is, calls to Verify() will - // be dispatched to the underlying |primary_verify_proc|. This can be changed - // by calling set_trial_allowed(). + // Create a new TrialComparisonCertVerifier. The `verify_proc_factory` will + // be used to create the underlying primary and trial verifiers. + // + // Initially, no trial verifications will actually be performed; that is, + // calls to Verify() will be dispatched to the underlying `primary_verifier_` + // or `trial_verifier_` depending on the `impl_params`. This can be changed + // by calling `set_trial_allowed()`. // // When trial verifications are enabled, calls to Verify() will first call - // into |primary_verify_proc| to verify. The result of this verification will + // into `primary_verifier_` to verify. The result of this verification will // be immediately returned to the caller of Verify, allowing them to proceed. // However, the verifier will continue in the background, attempting to - // verify the same RequestParams using |trial_verify_proc|. If there are - // differences in the results, they will be reported via |report_callback|, + // verify the same RequestParams using `trial_verifier_`. If there are + // differences in the results, they will be reported via `report_callback`, // allowing the creator to receive information about differences. // // If the caller abandons the CertVerifier::Request prior to the primary // verification completed, no trial verification will be done. However, once // the primary verifier has returned, the trial verifications will continue, // provided that the underlying configuration has not been changed by - // calling SetConfig(). + // calling `SetConfig()` or `UpdateVerifyProcData()`. // - // Note that there may be multiple calls to both |primary_verify_proc| and - // |trial_verify_proc|, using different parameters to account for platform - // differences. + // Note that there may be multiple calls to both the primary CertVerifyProc + // and trial CertVerifyProc, using different parameters to account for + // platform differences. TrialComparisonCertVerifier( - scoped_refptr<CertVerifyProc> primary_verify_proc, - scoped_refptr<CertVerifyProcFactory> primary_verify_proc_factory, - scoped_refptr<CertVerifyProc> trial_verify_proc, - scoped_refptr<CertVerifyProcFactory> trial_verify_proc_factory, + scoped_refptr<CertVerifyProcFactory> verify_proc_factory, + scoped_refptr<CertNetFetcher> cert_net_fetcher, + const CertVerifyProcFactory::ImplParams& impl_params, ReportCallback report_callback); TrialComparisonCertVerifier(const TrialComparisonCertVerifier&) = delete; @@ -94,8 +93,7 @@ void RemoveObserver(Observer* observer) override; void UpdateVerifyProcData( scoped_refptr<CertNetFetcher> cert_net_fetcher, - scoped_refptr<CRLSet> crl_set, - const ChromeRootStoreData* root_store_data) override; + const CertVerifyProcFactory::ImplParams& impl_params) override; private: class Job; @@ -108,6 +106,13 @@ void RemoveJob(Job* job_ptr); void NotifyJobsOfConfigChange(); + // Processes the params from the caller, updates the state of the trial and + // returns the pair of {primary verifier params, trial verifier params} to + // be used in creating or updating the wrapped verifiers. + std::tuple<CertVerifyProcFactory::ImplParams, + CertVerifyProcFactory::ImplParams> + ProcessImplParams(const CertVerifyProcFactory::ImplParams& impl_params); + // CertVerifier::Observer methods: void OnCertVerifierChanged() override; @@ -116,6 +121,11 @@ // Callback that reports are sent to. ReportCallback report_callback_; + // The actual `use_chrome_root_store` value that is requested by the caller. + // This determines which verifier's result is returned to the caller as the + // actual verification result. + bool actual_use_chrome_root_store_; + CertVerifier::Config config_; std::unique_ptr<CertVerifierWithUpdatableProc> primary_verifier_;
diff --git a/net/cert/trial_comparison_cert_verifier_unittest.cc b/net/cert/trial_comparison_cert_verifier_unittest.cc index ece77e8..859ee6e 100644 --- a/net/cert/trial_comparison_cert_verifier_unittest.cc +++ b/net/cert/trial_comparison_cert_verifier_unittest.cc
@@ -205,6 +205,10 @@ return ERR_UNEXPECTED; } +scoped_refptr<CertVerifyProc> MakeNotCalledProc() { + return base::MakeRefCounted<NotCalledCertVerifyProc>(); +} + void NotCalledCallback(int error) { ADD_FAILURE() << "NotCalledCallback was called with error code " << error; } @@ -232,27 +236,42 @@ ~MockCertVerifyProc() override = default; }; -class SwapWithNewProcFactory : public CertVerifyProcFactory { +class TestProcFactory : public CertVerifyProcFactory { public: - explicit SwapWithNewProcFactory(scoped_refptr<CertVerifyProc> new_proc) - : verify_proc_(std::move(new_proc)) {} + explicit TestProcFactory( + std::deque<scoped_refptr<CertVerifyProc>> primary_verify_procs, + std::deque<scoped_refptr<CertVerifyProc>> trial_verify_procs) + : primary_verify_procs_(std::move(primary_verify_procs)), + trial_verify_procs_(std::move(trial_verify_procs)) {} scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc( scoped_refptr<CertNetFetcher> cert_net_fetcher, - scoped_refptr<CRLSet> crl_set, - const ChromeRootStoreData* root_store_data) override { - return verify_proc_; + const ImplParams& impl_params) override { + std::deque<scoped_refptr<CertVerifyProc>>* procs = + impl_params.use_chrome_root_store ? &trial_verify_procs_ + : &primary_verify_procs_; + if (procs->empty()) { + ADD_FAILURE() << "procs is empty for crs=" + << impl_params.use_chrome_root_store; + return MakeNotCalledProc(); + } + scoped_refptr<CertVerifyProc> r = procs->front(); + procs->pop_front(); + return r; } protected: - ~SwapWithNewProcFactory() override = default; + ~TestProcFactory() override = default; - scoped_refptr<CertVerifyProc> verify_proc_; + std::deque<scoped_refptr<CertVerifyProc>> primary_verify_procs_; + std::deque<scoped_refptr<CertVerifyProc>> trial_verify_procs_; }; -scoped_refptr<CertVerifyProcFactory> SwapWithNotCalledProcFactory() { - return base::MakeRefCounted<SwapWithNewProcFactory>( - base::MakeRefCounted<NotCalledCertVerifyProc>()); +scoped_refptr<CertVerifyProcFactory> ProcFactory( + std::deque<scoped_refptr<CertVerifyProc>> primary_verify_procs, + std::deque<scoped_refptr<CertVerifyProc>> trial_verify_procs) { + return base::MakeRefCounted<TestProcFactory>(std::move(primary_verify_procs), + std::move(trial_verify_procs)); } struct TrialReportInfo { @@ -332,6 +351,9 @@ GetTestCertsDirectory(), "lets-encrypt-isrg-x1-root.pem", X509Certificate::FORMAT_AUTO); ASSERT_TRUE(lets_encrypt_isrg_x1_); + + no_crs_impl_params_.use_chrome_root_store = false; + yes_crs_impl_params_.use_chrome_root_store = true; } protected: @@ -340,22 +362,26 @@ scoped_refptr<X509Certificate> leaf_cert_1_; scoped_refptr<X509Certificate> lets_encrypt_dst_x3_; scoped_refptr<X509Certificate> lets_encrypt_isrg_x1_; + net::CertVerifyProcFactory::ImplParams no_crs_impl_params_; + net::CertVerifyProcFactory::ImplParams yes_crs_impl_params_; base::HistogramTester histograms_; }; -TEST_F(TrialComparisonCertVerifierTest, ObserverIsCalledOnCRSUpdate) { +TEST_F(TrialComparisonCertVerifierTest, ObserverIsCalledOnVerifierUpdate) { std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - base::MakeRefCounted<NotCalledCertVerifyProc>(), - SwapWithNotCalledProcFactory(), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - SwapWithNotCalledProcFactory(), + ProcFactory({MakeNotCalledProc(), MakeNotCalledProc(), + MakeNotCalledProc(), MakeNotCalledProc()}, + {MakeNotCalledProc(), MakeNotCalledProc()}), + nullptr, no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); CertVerifierObserverCounter observer_(&verifier); EXPECT_EQ(observer_.change_count(), 0u); - verifier.UpdateVerifyProcData(nullptr, nullptr, nullptr); - EXPECT_EQ(observer_.change_count(), 1u); + verifier.UpdateVerifyProcData(nullptr, no_crs_impl_params_); + // Observer is called twice since the TrialComparisonCertVerifier currently + // forwards notifications from both the primary and secondary verifiers. + EXPECT_EQ(observer_.change_count(), 2u); } TEST_F(TrialComparisonCertVerifierTest, InitiallyDisallowed) { @@ -365,10 +391,10 @@ auto verify_proc = base::MakeRefCounted<FakeCertVerifyProc>(OK, dummy_result); std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc, SwapWithNotCalledProcFactory(), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - SwapWithNotCalledProcFactory(), + ProcFactory({verify_proc, MakeNotCalledProc()}, {MakeNotCalledProc()}), + nullptr, no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); + CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, /*ocsp_response=*/std::string(), /*sct_list=*/std::string()); @@ -428,9 +454,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); CertVerifier::RequestParams params(leaf, "t0.test", /*flags=*/0, /*ocsp_response=*/std::string(), @@ -512,9 +537,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf, "t0.test", /*flags=*/0, @@ -565,6 +589,186 @@ EXPECT_EQ("t0.test", report.hostname); } +TEST_F(TrialComparisonCertVerifierTest, InitiallyCRSEnabledThenDisabled) { + // Certificate that has multiple subjectAltName entries. This allows easily + // confirming which verification attempt the report was generated for without + // having to mock different CertVerifyProc results for each. + base::FilePath certs_dir = + GetTestNetDataDirectory() + .AppendASCII("verify_certificate_chain_unittest") + .AppendASCII("many-names"); + scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile( + certs_dir, "ok-all-types.pem", X509Certificate::FORMAT_AUTO); + ASSERT_TRUE(cert_chain); + ASSERT_EQ(2U, cert_chain->intermediate_buffers().size()); + + scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromBuffer( + bssl::UpRef(cert_chain->cert_buffer()), {}); + ASSERT_TRUE(leaf); + + CertVerifyResult primary_result; + primary_result.verified_cert = cert_chain; + scoped_refptr<FakeCertVerifyProc> verify_proc1 = + base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result); + + // Trial verifier returns an error status. + CertVerifyResult secondary_result; + secondary_result.cert_status = CERT_STATUS_DATE_INVALID; + secondary_result.verified_cert = cert_chain; + scoped_refptr<FakeCertVerifyProc> verify_proc2 = + base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID, + secondary_result); + + std::vector<TrialReportInfo> reports; + // Verifier created with ImplParams that have use_chrome_root_store=true. + TrialComparisonCertVerifier verifier( + ProcFactory({verify_proc1, MakeNotCalledProc(), verify_proc1, + MakeNotCalledProc()}, + {verify_proc2, verify_proc2}), + nullptr, yes_crs_impl_params_, + base::BindRepeating(&RecordTrialReport, &reports)); + verifier.set_trial_allowed(true); + + CertVerifier::RequestParams params(leaf, "t0.test", /*flags=*/0, + /*ocsp_response=*/std::string(), + /*sct_list=*/std::string()); + CertVerifyResult result; + TestCompletionCallback callback; + std::unique_ptr<CertVerifier::Request> request; + int error = verifier.Verify(params, &result, callback.callback(), &request, + NetLogWithSource()); + ASSERT_THAT(error, IsError(ERR_IO_PENDING)); + EXPECT_TRUE(request); + error = callback.WaitForResult(); + // The actual result returned should be from the secondary verifier. + EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID)); + + // Turn chrome root store off and verify again. + verifier.UpdateVerifyProcData(nullptr, no_crs_impl_params_); + CertVerifier::RequestParams params2(leaf, "t1.test", /*flags=*/0, + /*ocsp_response=*/std::string(), + /*sct_list=*/std::string()); + CertVerifyResult result2; + TestCompletionCallback callback2; + std::unique_ptr<CertVerifier::Request> request2; + error = verifier.Verify(params2, &result2, callback2.callback(), &request2, + NetLogWithSource()); + ASSERT_THAT(error, IsError(ERR_IO_PENDING)); + EXPECT_TRUE(request2); + + // The actual result returned should now be from the primary verifier. + error = callback2.WaitForResult(); + EXPECT_THAT(error, IsOk()); + + verify_proc2->WaitForVerifyCall(); + RunUntilIdle(); + + // Primary verifier should have run once, secondary verifier should run twice. + EXPECT_EQ(1, verify_proc1->num_verifications()); + EXPECT_EQ(2, verify_proc2->num_verifications()); + // Trial comparison was only run once. + histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1); + histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", + 1); + histograms_.ExpectUniqueSample( + "Net.CertVerifier_TrialComparisonResult", + TrialComparisonResult::kPrimaryValidSecondaryError, 1); + + // Expect a report from the second verification. + ASSERT_EQ(1U, reports.size()); + const TrialReportInfo& report = reports[0]; + EXPECT_EQ("t1.test", report.hostname); +} + +TEST_F(TrialComparisonCertVerifierTest, InitiallyAllowedThenCRSEnabled) { + // Certificate that has multiple subjectAltName entries. This allows easily + // confirming which verification attempt the report was generated for without + // having to mock different CertVerifyProc results for each. + base::FilePath certs_dir = + GetTestNetDataDirectory() + .AppendASCII("verify_certificate_chain_unittest") + .AppendASCII("many-names"); + scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile( + certs_dir, "ok-all-types.pem", X509Certificate::FORMAT_AUTO); + ASSERT_TRUE(cert_chain); + ASSERT_EQ(2U, cert_chain->intermediate_buffers().size()); + + scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromBuffer( + bssl::UpRef(cert_chain->cert_buffer()), {}); + ASSERT_TRUE(leaf); + + CertVerifyResult primary_result; + primary_result.verified_cert = cert_chain; + scoped_refptr<FakeCertVerifyProc> verify_proc1 = + base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result); + + // Trial verifier returns an error status. + CertVerifyResult secondary_result; + secondary_result.cert_status = CERT_STATUS_DATE_INVALID; + secondary_result.verified_cert = cert_chain; + scoped_refptr<FakeCertVerifyProc> verify_proc2 = + base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID, + secondary_result); + + std::vector<TrialReportInfo> reports; + TrialComparisonCertVerifier verifier( + ProcFactory({verify_proc1, MakeNotCalledProc(), verify_proc1, + MakeNotCalledProc()}, + {verify_proc2, verify_proc2}), + nullptr, no_crs_impl_params_, + base::BindRepeating(&RecordTrialReport, &reports)); + verifier.set_trial_allowed(true); + + CertVerifier::RequestParams params(leaf, "t0.test", /*flags=*/0, + /*ocsp_response=*/std::string(), + /*sct_list=*/std::string()); + CertVerifyResult result; + TestCompletionCallback callback; + std::unique_ptr<CertVerifier::Request> request; + int error = verifier.Verify(params, &result, callback.callback(), &request, + NetLogWithSource()); + ASSERT_THAT(error, IsError(ERR_IO_PENDING)); + EXPECT_TRUE(request); + error = callback.WaitForResult(); + EXPECT_THAT(error, IsOk()); + + // Turn chrome root store on and verify again. + verifier.UpdateVerifyProcData(nullptr, yes_crs_impl_params_); + CertVerifier::RequestParams params2(leaf, "t1.test", /*flags=*/0, + /*ocsp_response=*/std::string(), + /*sct_list=*/std::string()); + CertVerifyResult result2; + TestCompletionCallback callback2; + std::unique_ptr<CertVerifier::Request> request2; + error = verifier.Verify(params2, &result2, callback2.callback(), &request2, + NetLogWithSource()); + ASSERT_THAT(error, IsError(ERR_IO_PENDING)); + EXPECT_TRUE(request2); + + // The actual result returned should now be from the secondary verifier. + error = callback2.WaitForResult(); + EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID)); + + verify_proc2->WaitForVerifyCall(); + RunUntilIdle(); + + // Primary verifier should have run once, secondary verifier should run twice. + EXPECT_EQ(1, verify_proc1->num_verifications()); + EXPECT_EQ(2, verify_proc2->num_verifications()); + // Trial comparison was only run once. + histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1); + histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", + 1); + histograms_.ExpectUniqueSample( + "Net.CertVerifier_TrialComparisonResult", + TrialComparisonResult::kPrimaryValidSecondaryError, 1); + + // Expect a report from the first verification. + ASSERT_EQ(1U, reports.size()); + const TrialReportInfo& report = reports[0]; + EXPECT_EQ("t0.test", report.hostname); +} + TEST_F(TrialComparisonCertVerifierTest, ConfigChangedDuringPrimaryVerification) { CertVerifyResult primary_result; @@ -574,9 +778,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - SwapWithNotCalledProcFactory(), + ProcFactory({verify_proc1, MakeNotCalledProc()}, {MakeNotCalledProc()}), + nullptr, no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); @@ -630,17 +833,18 @@ // Both verifiers are initially NotCalledCertVerifyProc, but should swap to // verify_proc1 and verify_proc2 when UpdateVerifyProcData is called. TrialComparisonCertVerifier verifier( - base::MakeRefCounted<NotCalledCertVerifyProc>(), - base::MakeRefCounted<SwapWithNewProcFactory>(verify_proc1), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - base::MakeRefCounted<SwapWithNewProcFactory>(verify_proc2), + ProcFactory({MakeNotCalledProc(), MakeNotCalledProc(), verify_proc1, + MakeNotCalledProc()}, + {MakeNotCalledProc(), verify_proc2}), + nullptr, no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); + verifier.set_trial_allowed(true); // Change the verifier Chrome Root Store data before verification, so the // Verify should call the verifiers that were swapped in by the factories // instead of the initial ones. - verifier.UpdateVerifyProcData(nullptr, nullptr, nullptr); + verifier.UpdateVerifyProcData(nullptr, no_crs_impl_params_); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, /*ocsp_response=*/std::string(), @@ -696,9 +900,10 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - SwapWithNotCalledProcFactory(), + ProcFactory({verify_proc1, MakeNotCalledProc(), MakeNotCalledProc(), + MakeNotCalledProc()}, + {MakeNotCalledProc(), MakeNotCalledProc()}), + nullptr, no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); @@ -715,7 +920,7 @@ // Change the verifier Chrome Root Store data before the primary verification // finishes. - verifier.UpdateVerifyProcData(nullptr, nullptr, nullptr); + verifier.UpdateVerifyProcData(nullptr, no_crs_impl_params_); error = callback.WaitForResult(); EXPECT_THAT(error, IsOk()); @@ -749,9 +954,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -811,8 +1015,10 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), + ProcFactory({verify_proc1, MakeNotCalledProc(), MakeNotCalledProc(), + MakeNotCalledProc()}, + {verify_proc2, MakeNotCalledProc()}), + nullptr, no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); @@ -831,7 +1037,7 @@ EXPECT_THAT(error, IsOk()); // Change the verifier Chrome Root Store data during the trial verification. - verifier.UpdateVerifyProcData(nullptr, nullptr, nullptr); + verifier.UpdateVerifyProcData(nullptr, no_crs_impl_params_); RunUntilIdle(); @@ -864,9 +1070,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -914,9 +1119,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -980,9 +1184,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1045,9 +1248,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1106,9 +1308,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, verify_proc1}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1170,9 +1371,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1238,9 +1438,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, verify_proc1}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1335,9 +1534,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, verify_proc1}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf, "test.example", /*flags=*/0, @@ -1389,9 +1587,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::Config config; @@ -1462,9 +1659,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1522,9 +1718,8 @@ std::vector<TrialReportInfo> reports; auto verifier = std::make_unique<TrialComparisonCertVerifier>( - verify_proc1, SwapWithNotCalledProcFactory(), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - SwapWithNotCalledProcFactory(), + ProcFactory({verify_proc1, MakeNotCalledProc()}, {MakeNotCalledProc()}), + nullptr, no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier->set_trial_allowed(true); @@ -1571,9 +1766,8 @@ std::vector<TrialReportInfo> reports; auto verifier = std::make_unique<TrialComparisonCertVerifier>( - verify_proc1, SwapWithNotCalledProcFactory(), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - SwapWithNotCalledProcFactory(), + ProcFactory({verify_proc1, MakeNotCalledProc()}, {MakeNotCalledProc()}), + nullptr, no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier->set_trial_allowed(true); @@ -1636,8 +1830,8 @@ bool was_report_callback_called = false; std::unique_ptr<TrialComparisonCertVerifier> verifier; verifier = std::make_unique<TrialComparisonCertVerifier>( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindLambdaForTesting( [&verifier, &was_report_callback_called]( const std::string& hostname, @@ -1702,9 +1896,8 @@ std::vector<TrialReportInfo> reports; auto verifier = std::make_unique<TrialComparisonCertVerifier>( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier->set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1769,9 +1962,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1842,9 +2034,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1908,9 +2099,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -1978,9 +2168,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -2031,9 +2220,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -2085,9 +2273,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -2140,9 +2327,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -2196,9 +2382,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -2254,9 +2439,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -2305,9 +2489,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0, @@ -2358,9 +2541,8 @@ std::vector<TrialReportInfo> reports; TrialComparisonCertVerifier verifier( - verify_proc1, SwapWithNotCalledProcFactory(), verify_proc2, - SwapWithNotCalledProcFactory(), - base::BindRepeating(&RecordTrialReport, &reports)); + ProcFactory({verify_proc1, MakeNotCalledProc()}, {verify_proc2}), nullptr, + no_crs_impl_params_, base::BindRepeating(&RecordTrialReport, &reports)); verifier.set_trial_allowed(true); CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
diff --git a/net/test/embedded_test_server/http_request.cc b/net/test/embedded_test_server/http_request.cc index 4704ab10..66d7569 100644 --- a/net/test/embedded_test_server/http_request.cc +++ b/net/test/embedded_test_server/http_request.cc
@@ -171,7 +171,8 @@ LOG(WARNING) << "Malformed Content-Length header's value."; } } else if (http_request_->headers.count("Transfer-Encoding") > 0) { - if (http_request_->headers["Transfer-Encoding"] == "chunked") { + if (base::CompareCaseInsensitiveASCII( + http_request_->headers["Transfer-Encoding"], "chunked") == 0) { http_request_->has_content = true; chunked_decoder_ = std::make_unique<HttpChunkedDecoder>(); state_ = STATE_CONTENT;
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 6b0807f..48cf06c0 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -10496,8 +10496,9 @@ } void UpdateCertVerifier(scoped_refptr<CRLSet> crl_set) { - updatable_cert_verifier_->UpdateVerifyProcData(cert_net_fetcher_, - std::move(crl_set), nullptr); + net::CertVerifyProcFactory::ImplParams params; + params.crl_set = std::move(crl_set); + updatable_cert_verifier_->UpdateVerifyProcData(cert_net_fetcher_, params); } scoped_refptr<CertNetFetcherURLRequest> cert_net_fetcher_; @@ -11606,16 +11607,15 @@ // Configure a CRL that will mark |root_ca_cert| as a blocked interception // root. std::string crl_set_bytes; - scoped_refptr<CRLSet> crl_set; + net::CertVerifyProcFactory::ImplParams params; ASSERT_TRUE( base::ReadFileToString(GetTestCertsDirectory().AppendASCII( "crlset_blocked_interception_by_root.raw"), &crl_set_bytes)); - ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set)); + ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, ¶ms.crl_set)); updatable_cert_verifier_->UpdateVerifyProcData( - /*cert_net_fetcher=*/nullptr, crl_set, - /*root_store_data=*/nullptr); + /*cert_net_fetcher=*/nullptr, params); // Verify the connection fails as being a known interception root. {
diff --git a/remoting/base/protobuf_http_request.cc b/remoting/base/protobuf_http_request.cc index 2dbf331..8626200 100644 --- a/remoting/base/protobuf_http_request.cc +++ b/remoting/base/protobuf_http_request.cc
@@ -63,7 +63,8 @@ RunResponseCallback(url_loader_status); } } - DCHECK(!response_callback_); + // NOTE: Don't access member variables here, since |this| might have been + // deleted by the callback. std::move(invalidator).Run(); }
diff --git a/remoting/base/protobuf_http_request.h b/remoting/base/protobuf_http_request.h index 154414b..5dce48b0d 100644 --- a/remoting/base/protobuf_http_request.h +++ b/remoting/base/protobuf_http_request.h
@@ -10,11 +10,9 @@ #include "base/memory/raw_ptr.h" #include "remoting/base/protobuf_http_request_base.h" -namespace google { -namespace protobuf { +namespace google::protobuf { class MessageLite; -} // namespace protobuf -} // namespace google +} // namespace google::protobuf namespace remoting {
diff --git a/services/cert_verifier/cert_verifier_creation.cc b/services/cert_verifier/cert_verifier_creation.cc index ee5d2fa0..9290ca17 100644 --- a/services/cert_verifier/cert_verifier_creation.cc +++ b/services/cert_verifier/cert_verifier_creation.cc
@@ -4,6 +4,7 @@ #include "services/cert_verifier/cert_verifier_creation.h" +#include "base/types/optional_util.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "net/base/features.h" @@ -65,14 +66,9 @@ } #endif // BUILDFLAG(IS_CHROMEOS) -#if !BUILDFLAG(CHROME_ROOT_STORE_ONLY) -// CertVerifyProcFactory that returns a CertVerifyProc that supports the old -// configuration for platforms where we are transitioning from one cert -// configuration to another. If the platform only supports one configuration, -// return a CertVerifyProc that supports that configuration. -class OldDefaultCertVerifyProcFactory : public net::CertVerifyProcFactory { +class CertVerifyProcFactoryImpl : public net::CertVerifyProcFactory { public: - explicit OldDefaultCertVerifyProcFactory( + explicit CertVerifyProcFactoryImpl( mojom::CertVerifierCreationParams* creation_params) { #if BUILDFLAG(IS_CHROMEOS) user_slot_restriction_ = @@ -82,8 +78,34 @@ scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc( scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) override { + const CertVerifyProcFactory::ImplParams& impl_params) override { +#if BUILDFLAG(CHROME_ROOT_STORE_ONLY) + return CreateNewCertVerifyProc( + cert_net_fetcher, impl_params.crl_set, + base::OptionalToPtr(impl_params.root_store_data)); +#else +#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) + if (impl_params.use_chrome_root_store) { + return CreateNewCertVerifyProc( + cert_net_fetcher, impl_params.crl_set, + base::OptionalToPtr(impl_params.root_store_data)); + } +#endif + return CreateOldCertVerifyProc(cert_net_fetcher, impl_params.crl_set); +#endif + } + + protected: + ~CertVerifyProcFactoryImpl() override = default; + +#if !BUILDFLAG(CHROME_ROOT_STORE_ONLY) + // Factory function that returns a CertVerifyProc that supports the old + // configuration for platforms where we are transitioning from one cert + // configuration to another. If the platform only supports one configuration, + // return a CertVerifyProc that supports that configuration. + scoped_refptr<net::CertVerifyProc> CreateOldCertVerifyProc( + scoped_refptr<net::CertNetFetcher> cert_net_fetcher, + scoped_refptr<net::CRLSet> crl_set) { scoped_refptr<net::CertVerifyProc> verify_proc; #if BUILDFLAG(IS_CHROMEOS) verify_proc = net::CreateCertVerifyProcBuiltin( @@ -102,34 +124,15 @@ #endif return verify_proc; } - - protected: - ~OldDefaultCertVerifyProcFactory() override = default; - -#if BUILDFLAG(IS_CHROMEOS) - crypto::ScopedPK11Slot user_slot_restriction_; -#endif -}; #endif // !BUILDFLAG(CHROME_ROOT_STORE_ONLY) #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) -// CertVerifyProcFactory that returns a CertVerifyProc that uses the -// Chrome Cert Verifier with the Chrome Root Store. -class NewCertVerifyProcChromeRootStoreFactory - : public net::CertVerifyProcFactory { - public: - explicit NewCertVerifyProcChromeRootStoreFactory( - mojom::CertVerifierCreationParams* creation_params) { -#if BUILDFLAG(IS_CHROMEOS) - user_slot_restriction_ = - GetUserSlotRestrictionForChromeOSParams(creation_params); -#endif - } - - scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc( + // CertVerifyProcFactory that returns a CertVerifyProc that uses the + // Chrome Cert Verifier with the Chrome Root Store. + scoped_refptr<net::CertVerifyProc> CreateNewCertVerifyProc( scoped_refptr<net::CertNetFetcher> cert_net_fetcher, scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) override { + const net::ChromeRootStoreData* root_store_data) { std::unique_ptr<net::TrustStoreChrome> chrome_root; if (!root_store_data) { chrome_root = std::make_unique<net::TrustStoreChrome>(); @@ -166,15 +169,12 @@ std::move(crl_set), std::move(trust_store)); } - - protected: - ~NewCertVerifyProcChromeRootStoreFactory() override = default; +#endif // BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) #if BUILDFLAG(IS_CHROMEOS) crypto::ScopedPK11Slot user_slot_restriction_; #endif }; -#endif // BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) #if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED) // Returns true if creation_params are requesting the creation of a @@ -190,39 +190,23 @@ std::unique_ptr<net::CertVerifierWithUpdatableProc> CreateTrialCertVerifier( mojom::CertVerifierCreationParams* creation_params, scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) { + const net::CertVerifyProcFactory::ImplParams& impl_params) { DCHECK(IsTrialVerificationOn(creation_params)); - // If we're doing trial verification, we always do it between the old - // default and the proposed new default, giving the user the value computed - // by the old default. - auto primary_proc_factory = - base::MakeRefCounted<OldDefaultCertVerifyProcFactory>(creation_params); - scoped_refptr<net::CertVerifyProc> primary_proc = - primary_proc_factory->CreateCertVerifyProc(cert_net_fetcher, crl_set, - root_store_data); + scoped_refptr<net::CertVerifyProcFactory> proc_factory = + base::MakeRefCounted<CertVerifyProcFactoryImpl>(creation_params); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - auto trial_proc_factory = - base::MakeRefCounted<NewCertVerifyProcChromeRootStoreFactory>( - creation_params); -#else +#if !BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) #error "CHROME_ROOT_STORE_OPTIONAL must be true" #endif - scoped_refptr<net::CertVerifyProc> trial_proc = - trial_proc_factory->CreateCertVerifyProc(cert_net_fetcher, crl_set, - root_store_data); - return std::make_unique<TrialComparisonCertVerifierMojo>( creation_params->trial_comparison_cert_verifier_params->initial_allowed, std::move(creation_params->trial_comparison_cert_verifier_params ->config_client_receiver), std::move(creation_params->trial_comparison_cert_verifier_params ->report_client), - std::move(primary_proc), std::move(primary_proc_factory), - std::move(trial_proc), std::move(trial_proc_factory)); + std::move(proc_factory), cert_net_fetcher, impl_params); } #endif // BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED) @@ -240,49 +224,23 @@ } std::unique_ptr<net::CertVerifierWithUpdatableProc> CreateCertVerifier( - mojom::CertVerifierServiceParams* impl_params, mojom::CertVerifierCreationParams* creation_params, scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) { + const net::CertVerifyProcFactory::ImplParams& impl_params) { DCHECK(cert_net_fetcher || !IsUsingCertNetFetcher()); - std::unique_ptr<net::CertVerifierWithUpdatableProc> cert_verifier; - -#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) - if (!cert_verifier -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - && impl_params->use_chrome_root_store -#endif - ) { - scoped_refptr<NewCertVerifyProcChromeRootStoreFactory> proc_factory = - base::MakeRefCounted<NewCertVerifyProcChromeRootStoreFactory>( - creation_params); - cert_verifier = std::make_unique<net::MultiThreadedCertVerifier>( - proc_factory->CreateCertVerifyProc(cert_net_fetcher, crl_set, - root_store_data), - proc_factory); - } -#endif #if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED) - if (!cert_verifier && IsTrialVerificationOn(creation_params)) { - cert_verifier = CreateTrialCertVerifier(creation_params, cert_net_fetcher, - crl_set, root_store_data); + if (IsTrialVerificationOn(creation_params)) { + return CreateTrialCertVerifier(creation_params, cert_net_fetcher, + impl_params); } #endif -#if !BUILDFLAG(CHROME_ROOT_STORE_ONLY) - if (!cert_verifier) { - scoped_refptr<OldDefaultCertVerifyProcFactory> proc_factory = - base::MakeRefCounted<OldDefaultCertVerifyProcFactory>(creation_params); - cert_verifier = std::make_unique<net::MultiThreadedCertVerifier>( - proc_factory->CreateCertVerifyProc(cert_net_fetcher, crl_set, - root_store_data), - proc_factory); - } -#endif - - return cert_verifier; + scoped_refptr<net::CertVerifyProcFactory> proc_factory = + base::MakeRefCounted<CertVerifyProcFactoryImpl>(creation_params); + return std::make_unique<net::MultiThreadedCertVerifier>( + proc_factory->CreateCertVerifyProc(cert_net_fetcher, impl_params), + proc_factory); } } // namespace cert_verifier
diff --git a/services/cert_verifier/cert_verifier_creation.h b/services/cert_verifier/cert_verifier_creation.h index a737096..1f2fe062a 100644 --- a/services/cert_verifier/cert_verifier_creation.h +++ b/services/cert_verifier/cert_verifier_creation.h
@@ -11,13 +11,9 @@ #include "base/memory/scoped_refptr.h" #include "net/cert/cert_net_fetcher.h" #include "net/cert/cert_verifier.h" +#include "net/cert/cert_verify_proc.h" #include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" -namespace net { -class ChromeRootStoreData; -class CRLSet; -} // namespace net - // Set of utility functions to help with creation of CertVerifiers for // CertVerifyServiceFactory. namespace cert_verifier { @@ -31,11 +27,9 @@ // Creates a concrete net::CertVerifier based on the platform and the particular // build configuration. |creation_params| and |root_store_data| are optional. std::unique_ptr<net::CertVerifierWithUpdatableProc> CreateCertVerifier( - mojom::CertVerifierServiceParams* impl_params, mojom::CertVerifierCreationParams* creation_params, scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data); + const net::CertVerifyProcFactory::ImplParams& impl_params); } // namespace cert_verifier
diff --git a/services/cert_verifier/cert_verifier_service.cc b/services/cert_verifier/cert_verifier_service.cc index f5af740..cc2b35c 100644 --- a/services/cert_verifier/cert_verifier_service.cc +++ b/services/cert_verifier/cert_verifier_service.cc
@@ -133,10 +133,8 @@ } void CertVerifierServiceImpl::UpdateVerifierData( - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) { - verifier_->UpdateVerifyProcData(cert_net_fetcher_, std::move(crl_set), - root_store_data); + const net::CertVerifyProcFactory::ImplParams& impl_params) { + verifier_->UpdateVerifyProcData(cert_net_fetcher_, impl_params); } void CertVerifierServiceImpl::Verify(
diff --git a/services/cert_verifier/cert_verifier_service.h b/services/cert_verifier/cert_verifier_service.h index 1eb9b44a..a0a9e20 100644 --- a/services/cert_verifier/cert_verifier_service.h +++ b/services/cert_verifier/cert_verifier_service.h
@@ -63,8 +63,8 @@ service_factory_impl); // Update the wrapped verifier with CRLSet and ChromeRootStoreData. - void UpdateVerifierData(scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data); + void UpdateVerifierData( + const net::CertVerifyProcFactory::ImplParams& impl_params); private: ~CertVerifierServiceImpl() override;
diff --git a/services/cert_verifier/cert_verifier_service_factory.cc b/services/cert_verifier/cert_verifier_service_factory.cc index 34c3878..54c2d286 100644 --- a/services/cert_verifier/cert_verifier_service_factory.cc +++ b/services/cert_verifier/cert_verifier_service_factory.cc
@@ -43,12 +43,10 @@ namespace { internal::CertVerifierServiceImpl* GetNewCertVerifierImpl( - mojom::CertVerifierServiceParams* impl_params, mojo::PendingReceiver<mojom::CertVerifierService> receiver, mojo::PendingRemote<mojom::CertVerifierServiceClient> client, mojom::CertVerifierCreationParamsPtr creation_params, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data, + const net::CertVerifyProcFactory::ImplParams& impl_params, scoped_refptr<CertNetFetcherURLLoader>* out_cert_net_fetcher) { scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher; @@ -60,8 +58,7 @@ } std::unique_ptr<net::CertVerifierWithUpdatableProc> cert_verifier = - CreateCertVerifier(impl_params, creation_params.get(), cert_net_fetcher, - crl_set, root_store_data); + CreateCertVerifier(creation_params.get(), cert_net_fetcher, impl_params); // As an optimization, if the CertNetFetcher isn't used by the CertVerifier, // shut it down immediately. @@ -118,19 +115,8 @@ } // namespace CertVerifierServiceFactoryImpl::CertVerifierServiceFactoryImpl( - mojom::CertVerifierServiceParamsPtr params, mojo::PendingReceiver<mojom::CertVerifierServiceFactory> receiver) - : service_params_(std::move(params)), - crl_set_(net::CRLSet::BuiltinCRLSet()), - receiver_(this, std::move(receiver)) { - if (!service_params_) { - service_params_ = mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params_->use_chrome_root_store = - base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed); -#endif - } -} + : receiver_(this, std::move(receiver)) {} CertVerifierServiceFactoryImpl::~CertVerifierServiceFactoryImpl() = default; @@ -138,34 +124,23 @@ mojo::PendingReceiver<mojom::CertVerifierService> receiver, mojo::PendingRemote<mojom::CertVerifierServiceClient> client, mojom::CertVerifierCreationParamsPtr creation_params) { - net::ChromeRootStoreData* root_store_data = nullptr; -#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) - root_store_data = base::OptionalToPtr(root_store_data_); -#endif - - internal::CertVerifierServiceImpl* service_impl = GetNewCertVerifierImpl( - service_params_.get(), std::move(receiver), std::move(client), - std::move(creation_params), crl_set_, root_store_data, - /*out_cert_net_fetcher=*/nullptr); + internal::CertVerifierServiceImpl* service_impl = + GetNewCertVerifierImpl(std::move(receiver), std::move(client), + std::move(creation_params), proc_params_, + /*out_cert_net_fetcher=*/nullptr); verifier_services_.insert(service_impl); service_impl->SetCertVerifierServiceFactory(weak_factory_.GetWeakPtr()); } -void CertVerifierServiceFactoryImpl::GetServiceParamsForTesting( - GetServiceParamsForTestingCallback callback) { - std::move(callback).Run(service_params_.Clone()); -} - void CertVerifierServiceFactoryImpl::GetNewCertVerifierForTesting( mojo::PendingReceiver<mojom::CertVerifierService> receiver, mojo::PendingRemote<mojom::CertVerifierServiceClient> client, mojom::CertVerifierCreationParamsPtr creation_params, scoped_refptr<CertNetFetcherURLLoader>* cert_net_fetcher_ptr) { - GetNewCertVerifierImpl(service_params_.get(), std::move(receiver), - std::move(client), std::move(creation_params), - crl_set_, - /*root_store_data=*/nullptr, cert_net_fetcher_ptr); + GetNewCertVerifierImpl(std::move(receiver), std::move(client), + std::move(creation_params), proc_params_, + cert_net_fetcher_ptr); } void CertVerifierServiceFactoryImpl::UpdateCRLSet( @@ -185,13 +160,13 @@ return; } - if (crl_set_->sequence() >= parsed_crl_set->sequence()) { + if (proc_params_.crl_set->sequence() >= parsed_crl_set->sequence()) { // Don't allow downgrades, and don't refresh CRLSets that are identical // (the sequence is globally unique for all CRLSets). return; } - crl_set_ = std::move(parsed_crl_set); + proc_params_.crl_set = std::move(parsed_crl_set); UpdateVerifierServices(); } @@ -238,7 +213,7 @@ // Update the stored Chrome Root Store so that new CertVerifierService // instances will start with the updated store. - root_store_data_ = std::move(root_store_data); + proc_params_.root_store_data = std::move(root_store_data); UpdateVerifierServices(); } @@ -246,9 +221,9 @@ void CertVerifierServiceFactoryImpl::GetChromeRootStoreInfo( GetChromeRootStoreInfoCallback callback) { mojom::ChromeRootStoreInfoPtr info_ptr = mojom::ChromeRootStoreInfo::New(); - if (root_store_data_) { - info_ptr->version = root_store_data_->version(); - for (auto cert : root_store_data_->anchors()) { + if (proc_params_.root_store_data) { + info_ptr->version = proc_params_.root_store_data->version(); + for (auto cert : proc_params_.root_store_data->anchors()) { info_ptr->root_cert_info.push_back( mojom::ChromeRootCertInfo::New(GetName(cert), GetHash(cert))); } @@ -263,18 +238,26 @@ } #endif +#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) +void CertVerifierServiceFactoryImpl::SetUseChromeRootStore( + bool use_crs, + SetUseChromeRootStoreCallback callback) { + if (use_crs != proc_params_.use_chrome_root_store) { + proc_params_.use_chrome_root_store = use_crs; + UpdateVerifierServices(); + } + std::move(callback).Run(); +} +#endif + void CertVerifierServiceFactoryImpl::RemoveService( internal::CertVerifierServiceImpl* service_impl) { verifier_services_.erase(service_impl); } void CertVerifierServiceFactoryImpl::UpdateVerifierServices() { - net::ChromeRootStoreData* root_store_data = nullptr; -#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) - root_store_data = base::OptionalToPtr(root_store_data_); -#endif for (internal::CertVerifierServiceImpl* service : verifier_services_) { - service->UpdateVerifierData(crl_set_, root_store_data); + service->UpdateVerifierData(proc_params_); } }
diff --git a/services/cert_verifier/cert_verifier_service_factory.h b/services/cert_verifier/cert_verifier_service_factory.h index 1a53614..96cfe5a 100644 --- a/services/cert_verifier/cert_verifier_service_factory.h +++ b/services/cert_verifier/cert_verifier_service_factory.h
@@ -33,10 +33,8 @@ class CertVerifierServiceFactoryImpl : public mojom::CertVerifierServiceFactory { public: - // Creates a CertVerifierServiceFactoryImpl. `params` may be null to use - // defaults. + // Creates a CertVerifierServiceFactoryImpl. explicit CertVerifierServiceFactoryImpl( - mojom::CertVerifierServiceParamsPtr params, mojo::PendingReceiver<mojom::CertVerifierServiceFactory> receiver); ~CertVerifierServiceFactoryImpl() override; @@ -45,8 +43,6 @@ mojo::PendingReceiver<mojom::CertVerifierService> receiver, mojo::PendingRemote<mojom::CertVerifierServiceClient> client, mojom::CertVerifierCreationParamsPtr creation_params) override; - void GetServiceParamsForTesting( - GetServiceParamsForTestingCallback callback) override; // Performs the same function as above, but stores a ref to the new // CertNetFetcherURLLoader in |*cert_net_fetcher_ptr|, if the @@ -66,6 +62,10 @@ UpdateChromeRootStoreCallback callback) override; void GetChromeRootStoreInfo(GetChromeRootStoreInfoCallback callback) override; #endif +#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) + void SetUseChromeRootStore(bool use_crs, + SetUseChromeRootStoreCallback callback) override; +#endif // Remove a CertVerifyService from needing updates to the Chrome Root Store. void RemoveService(internal::CertVerifierServiceImpl* service_impl); @@ -76,15 +76,7 @@ void OnCRLSetParsed(scoped_refptr<net::CRLSet> parsed_crl_set); - mojom::CertVerifierServiceParamsPtr service_params_; - - // The most recent version of CRLSet that we've seen. - scoped_refptr<net::CRLSet> crl_set_; - -#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) - // The most recent version of the Chrome Root Store that we've seen. - absl::optional<net::ChromeRootStoreData> root_store_data_; -#endif + net::CertVerifyProcFactory::ImplParams proc_params_; mojo::Receiver<mojom::CertVerifierServiceFactory> receiver_;
diff --git a/services/cert_verifier/cert_verifier_service_factory_unittest.cc b/services/cert_verifier/cert_verifier_service_factory_unittest.cc index 8761d1c..9cb322289 100644 --- a/services/cert_verifier/cert_verifier_service_factory_unittest.cc +++ b/services/cert_verifier/cert_verifier_service_factory_unittest.cc
@@ -12,6 +12,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/functional/bind.h" +#include "base/functional/callback_helpers.h" #include "base/memory/scoped_refptr.h" #include "base/run_loop.h" #include "base/test/bind.h" @@ -132,6 +133,17 @@ update_run_loop.Run(); } +void EnableChromeRootStoreIfOptional(CertVerifierServiceFactoryImpl* factory) { +#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) + // Configure with Chrome Root Store enabled. + { + base::RunLoop run_loop; + factory->SetUseChromeRootStore(true, run_loop.QuitClosure()); + run_loop.Run(); + } +#endif +} + } // namespace TEST(CertVerifierServiceFactoryTest, GetNewCertVerifier) { @@ -144,7 +156,6 @@ mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - /*params=*/nullptr, cv_service_factory_remote.BindNewPipeAndPassReceiver()); mojo::Remote<mojom::CertVerifierService> cv_service_remote; @@ -201,18 +212,12 @@ cert_verifier::mojom::ChromeRootStore::New( base::as_bytes(base::make_span(proto_serialized))); - // Configure with Chrome Root Store enabled. - mojom::CertVerifierServiceParamsPtr service_params = - mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params->use_chrome_root_store = true; -#endif - mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - std::move(service_params), cv_service_factory_remote.BindNewPipeAndPassReceiver()); + EnableChromeRootStoreIfOptional(&cv_service_factory_impl); + // Feed factory the new Chrome Root Store. { base::RunLoop update_run_loop; @@ -265,18 +270,12 @@ base::Time now = base::Time::Now(); leaf->SetValidity(now - base::Days(1), now + base::Days(1)); - // Configure with Chrome Root Store enabled. - mojom::CertVerifierServiceParamsPtr service_params = - mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params->use_chrome_root_store = true; -#endif - mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - std::move(service_params), cv_service_factory_remote.BindNewPipeAndPassReceiver()); + EnableChromeRootStoreIfOptional(&cv_service_factory_impl); + mojo::Remote<mojom::CertVerifierService> cv_service_remote; DummyCVServiceClient cv_service_client; mojom::CertVerifierCreationParamsPtr cv_creation_params = @@ -379,18 +378,12 @@ cert_verifier::mojom::ChromeRootStore::New( base::as_bytes(base::make_span(proto_serialized))); - // Configure with Chrome Root Store enabled. - mojom::CertVerifierServiceParamsPtr service_params = - mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params->use_chrome_root_store = true; -#endif - mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - std::move(service_params), cv_service_factory_remote.BindNewPipeAndPassReceiver()); + EnableChromeRootStoreIfOptional(&cv_service_factory_impl); + // Feed factory the new Chrome Root Store. { base::RunLoop update_run_loop; @@ -454,18 +447,12 @@ cert_verifier::mojom::ChromeRootStore::New( base::as_bytes(base::make_span(proto_serialized))); - // Configure with Chrome Root Store enabled. - mojom::CertVerifierServiceParamsPtr service_params = - mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params->use_chrome_root_store = true; -#endif - mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - std::move(service_params), cv_service_factory_remote.BindNewPipeAndPassReceiver()); + EnableChromeRootStoreIfOptional(&cv_service_factory_impl); + // Feed factory the new Chrome Root Store. { base::RunLoop update_run_loop; @@ -621,7 +608,6 @@ mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - /*params=*/nullptr, cv_service_factory_remote.BindNewPipeAndPassReceiver()); // Feed factory the new Chrome Root Store. @@ -660,7 +646,6 @@ mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - /*params=*/nullptr, cv_service_factory_remote.BindNewPipeAndPassReceiver()); cert_verifier::mojom::ChromeRootStoreInfoPtr info_ptr; base::RunLoop request_completed_run_loop; @@ -718,18 +703,12 @@ net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem")); ASSERT_TRUE(ok_cert); - // Configure with Chrome Root Store enabled. - mojom::CertVerifierServiceParamsPtr service_params = - mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params->use_chrome_root_store = true; -#endif - mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - std::move(service_params), cv_service_factory_remote.BindNewPipeAndPassReceiver()); + EnableChromeRootStoreIfOptional(&cv_service_factory_impl); + // Feed factory the CRLSet which blocks |ok_cert|. UpdateCRLSetWithTestFile(&cv_service_factory_impl, "crlset_by_leaf_spki.raw"); @@ -766,18 +745,12 @@ net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem")); ASSERT_TRUE(ok_cert); - // Configure with Chrome Root Store enabled. - mojom::CertVerifierServiceParamsPtr service_params = - mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params->use_chrome_root_store = true; -#endif - mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - std::move(service_params), cv_service_factory_remote.BindNewPipeAndPassReceiver()); + EnableChromeRootStoreIfOptional(&cv_service_factory_impl); + mojo::Remote<mojom::CertVerifierService> cv_service_remote; DummyCVServiceClient cv_service_client; mojom::CertVerifierCreationParamsPtr cv_creation_params = @@ -820,18 +793,12 @@ net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem")); ASSERT_TRUE(ok_cert); - // Configure with Chrome Root Store enabled. - mojom::CertVerifierServiceParamsPtr service_params = - mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params->use_chrome_root_store = true; -#endif - mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - std::move(service_params), cv_service_factory_remote.BindNewPipeAndPassReceiver()); + EnableChromeRootStoreIfOptional(&cv_service_factory_impl); + mojo::Remote<mojom::CertVerifierService> cv_service_remote; DummyCVServiceClient cv_service_client; mojom::CertVerifierCreationParamsPtr cv_creation_params = @@ -890,18 +857,12 @@ net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem")); ASSERT_TRUE(ok_cert); - // Configure with Chrome Root Store enabled. - mojom::CertVerifierServiceParamsPtr service_params = - mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params->use_chrome_root_store = true; -#endif - mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - std::move(service_params), cv_service_factory_remote.BindNewPipeAndPassReceiver()); + EnableChromeRootStoreIfOptional(&cv_service_factory_impl); + mojo::Remote<mojom::CertVerifierService> cv_service_remote; DummyCVServiceClient cv_service_client; mojom::CertVerifierCreationParamsPtr cv_creation_params = @@ -978,18 +939,12 @@ net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem")); ASSERT_TRUE(ok_cert); - // Configure with Chrome Root Store enabled. - mojom::CertVerifierServiceParamsPtr service_params = - mojom::CertVerifierServiceParams::New(); -#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL) - service_params->use_chrome_root_store = true; -#endif - mojo::Remote<mojom::CertVerifierServiceFactory> cv_service_factory_remote; CertVerifierServiceFactoryImpl cv_service_factory_impl( - std::move(service_params), cv_service_factory_remote.BindNewPipeAndPassReceiver()); + EnableChromeRootStoreIfOptional(&cv_service_factory_impl); + mojo::Remote<mojom::CertVerifierService> cv_service_remote; DummyCVServiceClient cv_service_client; mojom::CertVerifierCreationParamsPtr cv_creation_params =
diff --git a/services/cert_verifier/cert_verifier_service_unittest.cc b/services/cert_verifier/cert_verifier_service_unittest.cc index 95e2747..5f549b2 100644 --- a/services/cert_verifier/cert_verifier_service_unittest.cc +++ b/services/cert_verifier/cert_verifier_service_unittest.cc
@@ -109,8 +109,9 @@ void RemoveObserver(Observer* observer) override { observer_ = nullptr; } void UpdateVerifyProcData( scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) override {} + const net::CertVerifyProcFactory::ImplParams& impl_params) override { + ADD_FAILURE() << "not handled"; + } void RespondToRequest(const net::CertVerifier::RequestParams& params) { auto it = dummy_requests_.find(params);
diff --git a/services/cert_verifier/integration_tests/network_context_unittest.cc b/services/cert_verifier/integration_tests/network_context_unittest.cc index 3a30fa7..a30610a 100644 --- a/services/cert_verifier/integration_tests/network_context_unittest.cc +++ b/services/cert_verifier/integration_tests/network_context_unittest.cc
@@ -72,9 +72,10 @@ if (!cert_verifier_service_factory_) { cert_verifier_service_factory_ = std::make_unique<CertVerifierServiceFactoryImpl>( - GetCertVerifierServiceParams(), cert_verifier_service_factory_remote_ .BindNewPipeAndPassReceiver()); + InitializeCertVerifierServiceFactory( + cert_verifier_service_factory_.get()); } // Create a cert verifier service. @@ -83,9 +84,8 @@ std::move(cert_verifier_creation_params)); } - virtual mojom::CertVerifierServiceParamsPtr GetCertVerifierServiceParams() { - return nullptr; - } + virtual void InitializeCertVerifierServiceFactory( + mojom::CertVerifierServiceFactory* factory) {} network::mojom::NetworkService* network_service() const { return network_service_.get(); @@ -169,13 +169,12 @@ net::features::kChromeRootStoreUsed, feature_use_chrome_root_store()); } - mojom::CertVerifierServiceParamsPtr GetCertVerifierServiceParams() override { - mojom::CertVerifierServiceParamsPtr params; + void InitializeCertVerifierServiceFactory( + mojom::CertVerifierServiceFactory* factory) override { if (param_use_chrome_root_store().has_value()) { - params = mojom::CertVerifierServiceParams::New(); - params->use_chrome_root_store = *param_use_chrome_root_store(); + factory->SetUseChromeRootStore(*param_use_chrome_root_store(), + base::DoNothing()); } - return params; } bool feature_use_chrome_root_store() const { return std::get<0>(GetParam()); }
diff --git a/services/cert_verifier/integration_tests/network_service_unittest.cc b/services/cert_verifier/integration_tests/network_service_unittest.cc index 8258d19..e12dda4 100644 --- a/services/cert_verifier/integration_tests/network_service_unittest.cc +++ b/services/cert_verifier/integration_tests/network_service_unittest.cc
@@ -54,7 +54,6 @@ : task_environment_(base::test::TaskEnvironment::MainThreadType::IO), service_(network::NetworkService::CreateForTesting()), cert_verifier_service_impl_( - /*params=*/nullptr, cert_verifier_service_remote_.BindNewPipeAndPassReceiver()) {} ~NetworkServiceIntegrationTest() override = default;
diff --git a/services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom b/services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom index faeed5881..1472419 100644 --- a/services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom +++ b/services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom
@@ -37,15 +37,6 @@ TrialComparisonCertVerifierParams? trial_comparison_cert_verifier_params; }; -// Parameters for the CertVerifierServiceFactory. As opposed to -// CertVerifierCreationParams, which can vary for each CertVerifier created, -// the CertVerifierServiceParams are fixed and all CertVerifiers created by the -// factory will be created with the same service parameters. -struct CertVerifierServiceParams { - [EnableIf=is_chrome_root_store_optional] - bool use_chrome_root_store; -}; - // Serialized copy of the Chrome Root store. struct ChromeRootStore { // Serialized proto of type chrome_root_store::RootStore. @@ -75,9 +66,6 @@ pending_remote<CertVerifierServiceClient> client, CertVerifierCreationParams? creation_params); - // Returns the parameters that the service was configured with. - GetServiceParamsForTesting() => (CertVerifierServiceParams service_params); - // Updates the CRLSet used in the verification of certificates. CRLSets that // cannot be parsed using net::CRLSet::Parse will be ignored, as will older // CRLSets (where older is determined by the sequence number). All @@ -93,6 +81,12 @@ [EnableIf=is_chrome_root_store_supported] UpdateChromeRootStore(ChromeRootStore new_root_store) => (); + // Sets whether verification should use the Chrome Root Store or not. All + // CertVerifierServices created by the CertVerifierServiceFactory, including + // those created after this call, will use the same setting. + [EnableIf=is_chrome_root_store_optional] + SetUseChromeRootStore(bool use_crs) => (); + // Returns information about the current Chrome Root Store. [EnableIf=is_chrome_root_store_supported] GetChromeRootStoreInfo() => (ChromeRootStoreInfo root_store_info);
diff --git a/services/cert_verifier/trial_comparison_cert_verifier_mojo.cc b/services/cert_verifier/trial_comparison_cert_verifier_mojo.cc index 17cda9d9..69b3b320 100644 --- a/services/cert_verifier/trial_comparison_cert_verifier_mojo.cc +++ b/services/cert_verifier/trial_comparison_cert_verifier_mojo.cc
@@ -78,16 +78,15 @@ config_client_receiver, mojo::PendingRemote<mojom::TrialComparisonCertVerifierReportClient> report_client, - scoped_refptr<net::CertVerifyProc> primary_verify_proc, - scoped_refptr<net::CertVerifyProcFactory> primary_verify_proc_factory, - scoped_refptr<net::CertVerifyProc> trial_verify_proc, - scoped_refptr<net::CertVerifyProcFactory> trial_verify_proc_factory) + scoped_refptr<net::CertVerifyProcFactory> verify_proc_factory, + scoped_refptr<net::CertNetFetcher> cert_net_fetcher, + const net::CertVerifyProcFactory::ImplParams& impl_params) : receiver_(this, std::move(config_client_receiver)), report_client_(std::move(report_client)) { trial_comparison_cert_verifier_ = std::make_unique<net::TrialComparisonCertVerifier>( - primary_verify_proc, primary_verify_proc_factory, trial_verify_proc, - trial_verify_proc_factory, + std::move(verify_proc_factory), std::move(cert_net_fetcher), + impl_params, base::BindRepeating( &TrialComparisonCertVerifierMojo::OnSendTrialReport, // Unretained safe because the report_callback will not be called @@ -122,10 +121,9 @@ void TrialComparisonCertVerifierMojo::UpdateVerifyProcData( scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) { + const net::CertVerifyProcFactory::ImplParams& impl_params) { trial_comparison_cert_verifier_->UpdateVerifyProcData( - std::move(cert_net_fetcher), std::move(crl_set), root_store_data); + std::move(cert_net_fetcher), impl_params); } void TrialComparisonCertVerifierMojo::OnTrialConfigUpdated(bool allowed) {
diff --git a/services/cert_verifier/trial_comparison_cert_verifier_mojo.h b/services/cert_verifier/trial_comparison_cert_verifier_mojo.h index e3d4106..e9ad8d8 100644 --- a/services/cert_verifier/trial_comparison_cert_verifier_mojo.h +++ b/services/cert_verifier/trial_comparison_cert_verifier_mojo.h
@@ -22,7 +22,6 @@ class CertNetFetcher; class CertVerifyResult; class TrialComparisonCertVerifier; -class ChromeRootStoreData; } // namespace net FORWARD_DECLARE_TEST(TrialComparisonCertVerifierMojoTest, SendReportDebugInfo); @@ -47,10 +46,9 @@ config_client_receiver, mojo::PendingRemote<mojom::TrialComparisonCertVerifierReportClient> report_client, - scoped_refptr<net::CertVerifyProc> primary_verify_proc, - scoped_refptr<net::CertVerifyProcFactory> primary_verify_proc_factory, - scoped_refptr<net::CertVerifyProc> trial_verify_proc, - scoped_refptr<net::CertVerifyProcFactory> trial_verify_proc_factory); + scoped_refptr<net::CertVerifyProcFactory> verify_proc_factory, + scoped_refptr<net::CertNetFetcher> cert_net_fetcher, + const net::CertVerifyProcFactory::ImplParams& impl_params); TrialComparisonCertVerifierMojo(const TrialComparisonCertVerifierMojo&) = delete; @@ -70,8 +68,7 @@ void RemoveObserver(Observer* observer) override; void UpdateVerifyProcData( scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) override; + const net::CertVerifyProcFactory::ImplParams& impl_params) override; private: FRIEND_TEST_ALL_PREFIXES(::TrialComparisonCertVerifierMojoTest,
diff --git a/services/cert_verifier/trial_comparison_cert_verifier_mojo_unittest.cc b/services/cert_verifier/trial_comparison_cert_verifier_mojo_unittest.cc index fb3df96..1a83058c 100644 --- a/services/cert_verifier/trial_comparison_cert_verifier_mojo_unittest.cc +++ b/services/cert_verifier/trial_comparison_cert_verifier_mojo_unittest.cc
@@ -124,39 +124,14 @@ public: scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc( scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) override { - ADD_FAILURE() << "NotCalledProcFactory was called!"; - return nullptr; + const ImplParams& impl_params) override { + return base::MakeRefCounted<NotCalledCertVerifyProc>(); } protected: ~NotCalledProcFactory() override = default; }; -class SwapWithNewProcFactory : public net::CertVerifyProcFactory { - public: - explicit SwapWithNewProcFactory(scoped_refptr<net::CertVerifyProc> new_proc) - : verify_proc_(std::move(new_proc)) {} - - scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc( - scoped_refptr<net::CertNetFetcher> cert_net_fetcher, - scoped_refptr<net::CRLSet> crl_set, - const net::ChromeRootStoreData* root_store_data) override { - return verify_proc_; - } - - protected: - ~SwapWithNewProcFactory() override = default; - - scoped_refptr<net::CertVerifyProc> verify_proc_; -}; - -scoped_refptr<net::CertVerifyProcFactory> SwapWithNotCalledProcFactory() { - return base::MakeRefCounted<SwapWithNewProcFactory>( - base::MakeRefCounted<NotCalledCertVerifyProc>()); -} - } // namespace TEST(TrialComparisonCertVerifierMojoTest, SendReportDebugInfo) { @@ -219,10 +194,7 @@ report_client_remote.InitWithNewPipeAndPassReceiver()); cert_verifier::TrialComparisonCertVerifierMojo tccvm( true, {}, std::move(report_client_remote), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - base::MakeRefCounted<NotCalledProcFactory>(), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - base::MakeRefCounted<NotCalledProcFactory>()); + base::MakeRefCounted<NotCalledProcFactory>(), nullptr, {}); tccvm.OnSendTrialReport("example.com", unverified_cert, false, false, false, false, "stapled ocsp", "sct list", primary_result, @@ -291,13 +263,12 @@ report_client_remote.InitWithNewPipeAndPassReceiver()); cert_verifier::TrialComparisonCertVerifierMojo tccvm( true, {}, std::move(report_client_remote), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - SwapWithNotCalledProcFactory(), - base::MakeRefCounted<NotCalledCertVerifyProc>(), - SwapWithNotCalledProcFactory()); + base::MakeRefCounted<NotCalledProcFactory>(), nullptr, {}); net::CertVerifierObserverCounter observer_(&tccvm); EXPECT_EQ(observer_.change_count(), 0u); - tccvm.UpdateVerifyProcData(nullptr, nullptr, nullptr); - EXPECT_EQ(observer_.change_count(), 1u); + tccvm.UpdateVerifyProcData(nullptr, {}); + // Observer is called twice since the TrialComparisonCertVerifier currently + // forwards notifications from both the primary and secondary verifiers. + EXPECT_EQ(observer_.change_count(), 2u); }
diff --git a/services/device/compute_pressure/README.md b/services/device/compute_pressure/README.md index e829490..b7a18e85 100644 --- a/services/device/compute_pressure/README.md +++ b/services/device/compute_pressure/README.md
@@ -34,7 +34,11 @@ `blink::PressureObserver` implements bindings for the PressureObserver interface. There can be more than one PressureObserver per frame. -`blink::PressureObserverManager` maintains the list of active observers. -The class receives `device::mojom::PressureUpdate` from +`blink::PressureObserverManager` keeps track of `blink::PressureClientImpl` and +the connection to the `device::mojom::PressureManager` remote. + +`blink::PressureClientImpl` implements the `device::mojom::PressureClient` +interface to receive `device::mojom::PressureUpdate` from `device::PressureManagerImpl` and broadcasts the information to active -observers. +`blink::PressureObserver`. This class also keeps track of State and active +`blink::PressureObserver` per source type.
diff --git a/services/device/compute_pressure/pressure_manager_impl.cc b/services/device/compute_pressure/pressure_manager_impl.cc index 2c409d8..cac2b33 100644 --- a/services/device/compute_pressure/pressure_manager_impl.cc +++ b/services/device/compute_pressure/pressure_manager_impl.cc
@@ -12,7 +12,6 @@ #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "services/device/compute_pressure/cpu_probe.h" -#include "services/device/public/mojom/pressure_update.mojom.h" namespace device { @@ -29,13 +28,20 @@ : cpu_probe_(CpuProbe::Create( sampling_interval, base::BindRepeating(&PressureManagerImpl::UpdateClients, - base::Unretained(this)))) { - // base::Unretained use is safe because mojo guarantees the callback will not - // be called after `clients_` is deallocated, and `clients_` is owned by - // PressureManagerImpl. - clients_.set_disconnect_handler( - base::BindRepeating(&PressureManagerImpl::OnClientRemoteDisconnected, - base::Unretained(this))); + base::Unretained(this), + mojom::PressureSource::kCpu))) { + constexpr size_t kPressureSourceSize = + static_cast<size_t>(mojom::PressureSource::kMaxValue) + 1u; + for (size_t source_index = 0u; source_index < kPressureSourceSize; + ++source_index) { + auto source = static_cast<mojom::PressureSource>(source_index); + // base::Unretained use is safe because mojo guarantees the callback will + // not be called after `clients_` is deallocated, and `clients_` is owned by + // PressureManagerImpl. + clients_[source].set_disconnect_handler( + base::BindRepeating(&PressureManagerImpl::OnClientRemoteDisconnected, + base::Unretained(this), source)); + } } PressureManagerImpl::~PressureManagerImpl() { @@ -51,37 +57,51 @@ void PressureManagerImpl::AddClient( mojo::PendingRemote<mojom::PressureClient> client, + mojom::PressureSource source, AddClientCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!cpu_probe_) { - std::move(callback).Run(mojom::PressureStatus::kNotSupported); - return; + switch (source) { + case mojom::PressureSource::kCpu: { + if (!cpu_probe_) { + std::move(callback).Run(mojom::PressureStatus::kNotSupported); + return; + } + clients_[source].Add(std::move(client)); + cpu_probe_->EnsureStarted(); + std::move(callback).Run(mojom::PressureStatus::kOk); + break; + } } - clients_.Add(std::move(client)); - cpu_probe_->EnsureStarted(); - std::move(callback).Run(mojom::PressureStatus::kOk); } -void PressureManagerImpl::UpdateClients(mojom::PressureState state) { +void PressureManagerImpl::UpdateClients(mojom::PressureSource source, + mojom::PressureState state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const base::Time timestamp = base::Time::Now(); // TODO(crbug.com/1365627): Implement algorithm for pressure factors. // https://wicg.github.io/compute-pressure/#contributing-factors - mojom::PressureUpdate update(state, {}, timestamp); - for (auto& client : clients_) { + mojom::PressureUpdate update(source, state, {}, timestamp); + for (auto& client : clients_[source]) { client->OnPressureUpdated(update.Clone()); } } void PressureManagerImpl::OnClientRemoteDisconnected( + mojom::PressureSource source, mojo::RemoteSetElementId /*id*/) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (clients_.empty()) - cpu_probe_->Stop(); + if (clients_[source].empty()) { + switch (source) { + case mojom::PressureSource::kCpu: { + cpu_probe_->Stop(); + return; + } + } + } } void PressureManagerImpl::SetCpuProbeForTesting(
diff --git a/services/device/compute_pressure/pressure_manager_impl.h b/services/device/compute_pressure/pressure_manager_impl.h index 3e46a330..0dc888d 100644 --- a/services/device/compute_pressure/pressure_manager_impl.h +++ b/services/device/compute_pressure/pressure_manager_impl.h
@@ -5,6 +5,7 @@ #ifndef SERVICES_DEVICE_COMPUTE_PRESSURE_PRESSURE_MANAGER_IMPL_H_ #define SERVICES_DEVICE_COMPUTE_PRESSURE_PRESSURE_MANAGER_IMPL_H_ +#include <map> #include <memory> #include "base/sequence_checker.h" @@ -15,6 +16,7 @@ #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote_set.h" #include "services/device/public/mojom/pressure_manager.mojom.h" +#include "services/device/public/mojom/pressure_update.mojom.h" namespace device { @@ -22,10 +24,10 @@ // Handles the communication between the renderer process and services. // -// This class owns one instance of CpuProbe. The CpuProbe +// This class owns one instance of probe for each PressureSource. The probe // instance keeps collecting compute pressure information from the -// underlying operating system when `clients_` is not empty and stops -// collecting when `clients_` becomes empty. +// underlying operating system when its `clients_` is not empty and stops +// collecting when its `clients_` becomes empty. // // DeviceService owns one instance of this class. // @@ -48,6 +50,7 @@ // device::mojom::PressureManager implementation. void AddClient(mojo::PendingRemote<mojom::PressureClient> client, + mojom::PressureSource source, AddClientCallback callback) override; void SetCpuProbeForTesting(std::unique_ptr<CpuProbe>); @@ -57,11 +60,12 @@ explicit PressureManagerImpl(base::TimeDelta sampling_interval); - // Called periodically by PlatformCollector. - void UpdateClients(mojom::PressureState state); + // Called periodically by probe for each PressureSource. + void UpdateClients(mojom::PressureSource source, mojom::PressureState state); - // Stop `cpu_probe_` once there is no client. - void OnClientRemoteDisconnected(mojo::RemoteSetElementId /*id*/); + // Stop corresponding probe once there is no client. + void OnClientRemoteDisconnected(mojom::PressureSource source, + mojo::RemoteSetElementId /*id*/); SEQUENCE_CHECKER(sequence_checker_); @@ -70,8 +74,8 @@ mojo::ReceiverSet<mojom::PressureManager> receivers_ GUARDED_BY_CONTEXT(sequence_checker_); - mojo::RemoteSet<mojom::PressureClient> clients_ - GUARDED_BY_CONTEXT(sequence_checker_); + std::map<mojom::PressureSource, mojo::RemoteSet<mojom::PressureClient>> + clients_ GUARDED_BY_CONTEXT(sequence_checker_); }; } // namespace device
diff --git a/services/device/compute_pressure/pressure_manager_impl_unittest.cc b/services/device/compute_pressure/pressure_manager_impl_unittest.cc index 8fab604e..fe154dc54 100644 --- a/services/device/compute_pressure/pressure_manager_impl_unittest.cc +++ b/services/device/compute_pressure/pressure_manager_impl_unittest.cc
@@ -41,9 +41,10 @@ PressureManagerImplSync& operator=(const PressureManagerImplSync&) = delete; mojom::PressureStatus AddClient( - mojo::PendingRemote<mojom::PressureClient> client) { + mojo::PendingRemote<mojom::PressureClient> client, + mojom::PressureSource source) { base::test::TestFuture<mojom::PressureStatus> future; - manager_->AddClient(std::move(client), future.GetCallback()); + manager_->AddClient(std::move(client), source, future.GetCallback()); return future.Get(); } @@ -125,7 +126,8 @@ manager_impl_->SetCpuProbeForTesting(std::make_unique<FakeCpuProbe>( kDefaultSamplingIntervalForTesting, base::BindRepeating(&PressureManagerImpl::UpdateClients, - base::Unretained(manager_impl_.get())))); + base::Unretained(manager_impl_.get()), + mojom::PressureSource::kCpu))); manager_.reset(); manager_impl_->Bind(manager_.BindNewPipeAndPassReceiver()); manager_impl_sync_ = @@ -140,31 +142,39 @@ TEST_F(PressureManagerImplTest, OneClient) { FakePressureClient client; - ASSERT_EQ(manager_impl_sync_->AddClient(client.BindNewPipeAndPassRemote()), + ASSERT_EQ(manager_impl_sync_->AddClient(client.BindNewPipeAndPassRemote(), + mojom::PressureSource::kCpu), mojom::PressureStatus::kOk); client.WaitForUpdate(); ASSERT_EQ(client.updates().size(), 1u); + EXPECT_EQ(client.updates()[0].source, mojom::PressureSource::kCpu); EXPECT_EQ(client.updates()[0].state, mojom::PressureState::kFair); } TEST_F(PressureManagerImplTest, ThreeClients) { FakePressureClient client1; - ASSERT_EQ(manager_impl_sync_->AddClient(client1.BindNewPipeAndPassRemote()), + ASSERT_EQ(manager_impl_sync_->AddClient(client1.BindNewPipeAndPassRemote(), + mojom::PressureSource::kCpu), mojom::PressureStatus::kOk); FakePressureClient client2; - ASSERT_EQ(manager_impl_sync_->AddClient(client2.BindNewPipeAndPassRemote()), + ASSERT_EQ(manager_impl_sync_->AddClient(client2.BindNewPipeAndPassRemote(), + mojom::PressureSource::kCpu), mojom::PressureStatus::kOk); FakePressureClient client3; - ASSERT_EQ(manager_impl_sync_->AddClient(client3.BindNewPipeAndPassRemote()), + ASSERT_EQ(manager_impl_sync_->AddClient(client3.BindNewPipeAndPassRemote(), + mojom::PressureSource::kCpu), mojom::PressureStatus::kOk); FakePressureClient::WaitForUpdates({&client1, &client2, &client3}); ASSERT_EQ(client1.updates().size(), 1u); + EXPECT_EQ(client1.updates()[0].source, mojom::PressureSource::kCpu); EXPECT_EQ(client1.updates()[0].state, mojom::PressureState::kFair); ASSERT_EQ(client2.updates().size(), 1u); + EXPECT_EQ(client2.updates()[0].source, mojom::PressureSource::kCpu); EXPECT_EQ(client2.updates()[0].state, mojom::PressureState::kFair); ASSERT_EQ(client3.updates().size(), 1u); + EXPECT_EQ(client3.updates()[0].source, mojom::PressureSource::kCpu); EXPECT_EQ(client3.updates()[0].state, mojom::PressureState::kFair); } @@ -172,7 +182,8 @@ manager_impl_->SetCpuProbeForTesting(nullptr); FakePressureClient client; - ASSERT_EQ(manager_impl_sync_->AddClient(client.BindNewPipeAndPassRemote()), + ASSERT_EQ(manager_impl_sync_->AddClient(client.BindNewPipeAndPassRemote(), + mojom::PressureSource::kCpu), mojom::PressureStatus::kNotSupported); }
diff --git a/services/device/public/cpp/test/scoped_pressure_manager_overrider.cc b/services/device/public/cpp/test/scoped_pressure_manager_overrider.cc index 7a19f86..664048f 100644 --- a/services/device/public/cpp/test/scoped_pressure_manager_overrider.cc +++ b/services/device/public/cpp/test/scoped_pressure_manager_overrider.cc
@@ -25,9 +25,10 @@ void FakePressureManager::AddClient( mojo::PendingRemote<mojom::PressureClient> client, + mojom::PressureSource source, AddClientCallback callback) { if (is_supported_) { - clients_.Add(std::move(client)); + clients_[source].Add(std::move(client)); std::move(callback).Run(mojom::PressureStatus::kOk); } else { std::move(callback).Run(mojom::PressureStatus::kNotSupported); @@ -35,8 +36,9 @@ } void FakePressureManager::UpdateClients(const mojom::PressureUpdate& update) { - for (auto& client : clients_) + for (auto& client : clients_[update.source]) { client->OnPressureUpdated(update.Clone()); + } } void FakePressureManager::set_is_supported(bool is_supported) {
diff --git a/services/device/public/cpp/test/scoped_pressure_manager_overrider.h b/services/device/public/cpp/test/scoped_pressure_manager_overrider.h index 50f1056e..9429da05 100644 --- a/services/device/public/cpp/test/scoped_pressure_manager_overrider.h +++ b/services/device/public/cpp/test/scoped_pressure_manager_overrider.h
@@ -5,6 +5,8 @@ #ifndef SERVICES_DEVICE_PUBLIC_CPP_TEST_SCOPED_PRESSURE_MANAGER_OVERRIDER_H_ #define SERVICES_DEVICE_PUBLIC_CPP_TEST_SCOPED_PRESSURE_MANAGER_OVERRIDER_H_ +#include <map> + #include "base/time/time.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -28,6 +30,7 @@ // mojom::PressureManager implementation. void AddClient(mojo::PendingRemote<mojom::PressureClient> client, + mojom::PressureSource source, AddClientCallback callback) override; void UpdateClients(const mojom::PressureUpdate& update); @@ -37,7 +40,8 @@ private: bool is_supported_ = true; mojo::ReceiverSet<mojom::PressureManager> receivers_; - mojo::RemoteSet<mojom::PressureClient> clients_; + std::map<mojom::PressureSource, mojo::RemoteSet<mojom::PressureClient>> + clients_; }; class ScopedPressureManagerOverrider {
diff --git a/services/device/public/mojom/pressure_manager.mojom b/services/device/public/mojom/pressure_manager.mojom index 017eb4b6..6966481 100644 --- a/services/device/public/mojom/pressure_manager.mojom +++ b/services/device/public/mojom/pressure_manager.mojom
@@ -17,13 +17,14 @@ // This interface is used to subscribe to notification about OnPressureUpdated. // -// This interface is implemented by PressureServiceImpl in content/browser and -// PressureManagerImpl in services/device. PressureObserverManager in Blink -// uses this interface to make a PressureClient subscribe to notification -// about OnPressureUpdated. +// This interface is implemented by PressureManagerImpl in services/device. +// PressureObserverManager in Blink uses this interface to make a +// PressureClient subscribe to notification about OnPressureUpdated. interface PressureManager { - // Add a client that will be notified when a new PressureUpdate is obtained. - AddClient(pending_remote<PressureClient> client) => (PressureStatus status); + // Add a client that will be notified when a new PressureUpdate for `source` + // is obtained. + AddClient(pending_remote<PressureClient> client, PressureSource source) + => (PressureStatus status); }; // Interface that client of the PressureManager interface must
diff --git a/services/device/public/mojom/pressure_update.mojom b/services/device/public/mojom/pressure_update.mojom index c67233a8..a9c15d1 100644 --- a/services/device/public/mojom/pressure_update.mojom +++ b/services/device/public/mojom/pressure_update.mojom
@@ -6,6 +6,12 @@ import "mojo/public/mojom/base/time.mojom"; +enum PressureSource { + // TODO(crbug.com/1342184): Consider other sources. + // For now, "cpu" is the only source. + kCpu, +}; + enum PressureFactor { // Current pressure factor is thermal. kThermal, @@ -31,6 +37,7 @@ // Represents availability of compute resources. struct PressureUpdate { + PressureSource source; PressureState state; array<PressureFactor> factors; mojo_base.mojom.Time timestamp;
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json index 6451ab75..d4a03a0 100644 --- a/testing/buildbot/chrome.json +++ b/testing/buildbot/chrome.json
@@ -1555,7 +1555,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "octopus", - "cros_img": "octopus-release/R114-15408.0.0", + "cros_img": "octopus-release/R114-15419.0.0", "name": "chrome_all_tast_tests OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM", "shards": 10, "swarming": {}, @@ -1794,7 +1794,7 @@ { "args": [], "cros_board": "dedede", - "cros_img": "dedede-release/R114-15410.0.0", + "cros_img": "dedede-release/R114-15419.0.0", "name": "lacros_all_tast_tests DEDEDE_RELEASE_LKGM", "resultdb": { "enable": true, @@ -1811,7 +1811,7 @@ { "args": [], "cros_board": "dedede", - "cros_img": "dedede-release/R113-15393.12.0", + "cros_img": "dedede-release/R114-15416.0.0", "name": "lacros_all_tast_tests DEDEDE_RELEASE_DEV", "resultdb": { "enable": true, @@ -1828,7 +1828,7 @@ { "args": [], "cros_board": "dedede", - "cros_img": "dedede-release/R112-15359.37.0", + "cros_img": "dedede-release/R113-15393.12.0", "name": "lacros_all_tast_tests DEDEDE_RELEASE_BETA", "resultdb": { "enable": true, @@ -1862,7 +1862,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R114-15410.0.0", + "cros_img": "eve-release/R114-15419.0.0", "name": "lacros_all_tast_tests EVE_RELEASE_LKGM", "resultdb": { "enable": true, @@ -1879,7 +1879,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R113-15393.12.0", + "cros_img": "eve-release/R114-15416.0.0", "name": "lacros_all_tast_tests EVE_RELEASE_DEV", "resultdb": { "enable": true, @@ -1896,7 +1896,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R112-15359.37.0", + "cros_img": "eve-release/R113-15393.12.0", "name": "lacros_all_tast_tests EVE_RELEASE_BETA", "resultdb": { "enable": true, @@ -1913,7 +1913,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R111-15329.59.0", + "cros_img": "eve-release/R112-15359.45.0", "name": "lacros_all_tast_tests EVE_RELEASE_STABLE", "resultdb": { "enable": true, @@ -1965,7 +1965,7 @@ { "args": [], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R114-15410.0.0", + "cros_img": "jacuzzi-release/R114-15419.0.0", "name": "lacros_all_tast_tests JACUZZI_RELEASE_LKGM", "resultdb": { "enable": true, @@ -1982,7 +1982,7 @@ { "args": [], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R113-15393.12.0", + "cros_img": "jacuzzi-release/R114-15416.0.0", "name": "lacros_all_tast_tests JACUZZI_RELEASE_DEV", "resultdb": { "enable": true, @@ -1999,7 +1999,7 @@ { "args": [], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R112-15359.37.0", + "cros_img": "jacuzzi-release/R113-15393.12.0", "name": "lacros_all_tast_tests JACUZZI_RELEASE_BETA", "resultdb": { "enable": true, @@ -2016,7 +2016,7 @@ { "args": [], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R111-15329.59.0", + "cros_img": "jacuzzi-release/R112-15359.45.0", "name": "lacros_all_tast_tests JACUZZI_RELEASE_STABLE", "resultdb": { "enable": true, @@ -2068,7 +2068,7 @@ { "args": [], "cros_board": "herobrine", - "cros_img": "herobrine-release/R114-15410.0.0", + "cros_img": "herobrine-release/R114-15419.0.0", "name": "lacros_all_tast_tests HEROBRINE_RELEASE_LKGM", "resultdb": { "enable": true,
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index dbff023a..737457d7 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -1620,7 +1620,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "jacuzzi", - "cros_img": "jacuzzi-public/R114-15410.0.0", + "cros_img": "jacuzzi-public/R114-15419.0.0", "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -1650,7 +1650,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin64-public/R114-15410.0.0", + "cros_img": "kevin64-public/R114-15419.0.0", "name": "lacros_all_tast_tests KEVIN64_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -5618,9 +5618,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5631,8 +5631,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -5783,9 +5783,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5796,8 +5796,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -5930,9 +5930,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5943,8 +5943,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index cfb6f6c..ed30e49a 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -25212,9 +25212,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25225,8 +25225,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -25377,9 +25377,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25390,8 +25390,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -25524,9 +25524,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25537,8 +25537,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index bcdada6..1c26746 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -31093,7 +31093,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "octopus", - "cros_img": "octopus-public/R114-15410.0.0", + "cros_img": "octopus-public/R114-15419.0.0", "name": "lacros_all_tast_tests OCTOPUS_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31111,7 +31111,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "eve", - "cros_img": "eve-public/R114-15410.0.0", + "cros_img": "eve-public/R114-15419.0.0", "name": "lacros_all_tast_tests EVE_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31136,7 +31136,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "jacuzzi", - "cros_img": "jacuzzi-public/R114-15410.0.0", + "cros_img": "jacuzzi-public/R114-15419.0.0", "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31154,7 +31154,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin64-public/R114-15410.0.0", + "cros_img": "kevin64-public/R114-15419.0.0", "name": "lacros_all_tast_tests KEVIN64_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31179,7 +31179,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "jacuzzi", - "cros_img": "jacuzzi-public/R114-15410.0.0", + "cros_img": "jacuzzi-public/R114-15419.0.0", "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -31197,7 +31197,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "jacuzzi", - "cros_img": "jacuzzi-public/R114-15410.0.0", + "cros_img": "jacuzzi-public/R114-15419.0.0", "name": "lacros_all_tast_tests JACUZZI_CQ_PUBLIC_LKGM", "public_builder": "cros_test_platform_public", "public_builder_bucket": "testplatform-public", @@ -31217,7 +31217,7 @@ "args": [], "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin64-public/R114-15410.0.0", + "cros_img": "kevin64-public/R114-15419.0.0", "name": "lacros_all_tast_tests KEVIN64_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -33946,9 +33946,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -33958,8 +33958,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -34111,9 +34111,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -34123,8 +34123,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -34258,9 +34258,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -34270,8 +34270,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -35698,9 +35698,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -35710,8 +35710,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -35863,9 +35863,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -35875,8 +35875,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -36010,9 +36010,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -36022,8 +36022,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -36739,9 +36739,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -36751,8 +36751,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index b0a284e..5b684fa7 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -1809,7 +1809,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1826,7 +1826,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1843,7 +1843,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1861,7 +1861,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1878,7 +1878,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1895,7 +1895,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1912,7 +1912,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1929,7 +1929,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1946,7 +1946,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1963,7 +1963,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1981,7 +1981,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1998,7 +1998,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2015,7 +2015,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2053,7 +2053,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2070,7 +2070,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2087,7 +2087,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2104,7 +2104,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2121,7 +2121,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2138,7 +2138,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2155,7 +2155,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2189,7 +2189,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2224,7 +2224,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2241,7 +2241,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2258,7 +2258,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2275,7 +2275,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2292,7 +2292,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2309,7 +2309,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2326,7 +2326,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2343,7 +2343,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2360,7 +2360,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2377,7 +2377,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2394,7 +2394,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2411,7 +2411,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2428,7 +2428,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2445,7 +2445,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2462,7 +2462,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2479,7 +2479,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2496,7 +2496,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2513,7 +2513,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2530,7 +2530,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2547,7 +2547,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2582,7 +2582,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2599,7 +2599,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2616,7 +2616,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2633,7 +2633,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2650,7 +2650,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2667,7 +2667,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2684,7 +2684,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2701,7 +2701,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2718,7 +2718,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2735,7 +2735,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2752,7 +2752,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2769,7 +2769,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2786,7 +2786,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2803,7 +2803,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2820,7 +2820,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2837,7 +2837,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2854,7 +2854,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2871,7 +2871,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2888,7 +2888,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2905,7 +2905,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2922,7 +2922,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2939,7 +2939,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2956,7 +2956,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2973,7 +2973,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2990,7 +2990,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3007,7 +3007,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3024,7 +3024,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3058,7 +3058,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3075,7 +3075,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3092,7 +3092,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3109,7 +3109,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3126,7 +3126,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3143,7 +3143,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3160,7 +3160,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3177,7 +3177,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3194,7 +3194,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3212,7 +3212,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3229,7 +3229,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3253,7 +3253,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3275,7 +3275,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3376,7 +3376,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3394,7 +3394,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3416,7 +3416,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3438,7 +3438,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3460,7 +3460,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3482,7 +3482,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3504,7 +3504,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3525,7 +3525,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3563,7 +3563,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3601,7 +3601,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -3623,7 +3623,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3661,7 +3661,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "quickrun_shards": 18, @@ -3700,7 +3700,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -3722,7 +3722,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "idempotent": false, @@ -3776,7 +3776,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "idempotent": false, @@ -3800,7 +3800,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3824,7 +3824,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3862,7 +3862,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-18.04" + "os": "Ubuntu-22.04" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 8e72a8d..a10cad8 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -17723,12 +17723,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -17739,8 +17739,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -17908,12 +17908,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -17924,8 +17924,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [ @@ -18070,12 +18070,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 114.0.5710.0", + "description": "Run with ash-chrome version 114.0.5711.3", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -18086,8 +18086,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v114.0.5710.0", - "revision": "version:114.0.5710.0" + "location": "lacros_version_skew_tests_v114.0.5711.3", + "revision": "version:114.0.5711.3" } ], "dimension_sets": [
diff --git a/testing/buildbot/filters/linux-lacros.browser_tests.filter b/testing/buildbot/filters/linux-lacros.browser_tests.filter index 4bd90575..36d61f1 100644 --- a/testing/buildbot/filters/linux-lacros.browser_tests.filter +++ b/testing/buildbot/filters/linux-lacros.browser_tests.filter
@@ -9,7 +9,6 @@ -BrowserTest.RestorePinnedTabs -BrowserViewTest.GetAccessibleTabModalDialogTitle -BrowsingDataRemoverBrowserTest.StorageRemovedFromDisk --ContextMenuBrowserTest.OpenLinkInProfile -DeclarativeContentApiTest.RulesPersistence -ExternalProtocolDialogBrowserTest.TestFocus -FolderUploadConfirmationViewTest.InitiallyFocusesCancel
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json index d8e0b29..a996be2 100644 --- a/testing/buildbot/internal.chromeos.fyi.json +++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1117,7 +1117,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "brya", - "cros_img": "brya-release/R114-15407.0.0", + "cros_img": "brya-release/R114-15419.0.0", "name": "chrome_all_tast_tests BRYA_RELEASE_LKGM", "shards": 10, "swarming": {}, @@ -1129,6 +1129,29 @@ } ] }, + "chromeos-jacuzzi-chrome-skylab-fyi": { + "additional_compile_targets": [ + "chrome", + "linux_symbols", + "symupload" + ], + "skylab_tests": [ + { + "args": [], + "autotest_name": "tast.chrome-from-tls", + "cros_board": "jacuzzi", + "cros_img": "jacuzzi-release/R114-15410.0.0", + "name": "chrome_all_tast_tests JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM", + "shards": 10, + "swarming": {}, + "tast_expr": "(\"group:mainline\" && !informational)", + "test": "chrome_all_tast_tests", + "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", + "timeout_sec": 21600, + "variant_id": "JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM" + } + ] + }, "chromeos-octopus-chrome-skylab-fyi": { "additional_compile_targets": [ "chrome", @@ -1140,7 +1163,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "octopus", - "cros_img": "octopus-release/R114-15408.0.0", + "cros_img": "octopus-release/R114-15419.0.0", "name": "chrome_all_tast_tests OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM", "shards": 10, "swarming": {}, @@ -1163,7 +1186,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "trogdor", - "cros_img": "trogdor-release/R114-15407.0.0", + "cros_img": "trogdor-release/R114-15419.0.0", "name": "chrome_all_tast_tests TROGDOR_RELEASE_LKGM", "shards": 10, "swarming": {}, @@ -1186,7 +1209,7 @@ "args": [], "autotest_name": "tast.chrome-from-tls", "cros_board": "volteer", - "cros_img": "volteer-release/R114-15407.0.0", + "cros_img": "volteer-release/R114-15419.0.0", "name": "chrome_all_tast_tests VOLTEER_RELEASE_LKGM", "shards": 10, "swarming": {}, @@ -1206,7 +1229,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R114-15410.0.0", + "cros_img": "octopus-release/R114-15419.0.0", "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_LKGM", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1218,7 +1241,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R113-15393.12.0", + "cros_img": "octopus-release/R114-15416.0.0", "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_DEV", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1230,7 +1253,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R112-15359.37.0", + "cros_img": "octopus-release/R113-15393.12.0", "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_BETA", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1242,7 +1265,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R111-15329.59.0", + "cros_img": "octopus-release/R112-15359.45.0", "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_STABLE", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1254,7 +1277,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R114-15410.0.0", + "cros_img": "octopus-release/R114-15419.0.0", "name": "ozone_unittests OCTOPUS_RELEASE_LKGM", "swarming": {}, "test": "ozone_unittests", @@ -1265,7 +1288,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R113-15393.12.0", + "cros_img": "octopus-release/R114-15416.0.0", "name": "ozone_unittests OCTOPUS_RELEASE_DEV", "swarming": {}, "test": "ozone_unittests", @@ -1276,7 +1299,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R112-15359.37.0", + "cros_img": "octopus-release/R113-15393.12.0", "name": "ozone_unittests OCTOPUS_RELEASE_BETA", "swarming": {}, "test": "ozone_unittests", @@ -1287,7 +1310,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R111-15329.59.0", + "cros_img": "octopus-release/R112-15359.45.0", "name": "ozone_unittests OCTOPUS_RELEASE_STABLE", "swarming": {}, "test": "ozone_unittests", @@ -1305,7 +1328,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R114-15410.0.0", + "cros_img": "hana-release/R114-15419.0.0", "name": "lacros_all_tast_tests HANA_RELEASE_LKGM", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1317,7 +1340,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R113-15393.12.0", + "cros_img": "hana-release/R114-15410.0.0", "name": "lacros_all_tast_tests HANA_RELEASE_DEV", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1329,7 +1352,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R112-15359.37.0", + "cros_img": "hana-release/R113-15393.12.0", "name": "lacros_all_tast_tests HANA_RELEASE_BETA", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1341,7 +1364,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R111-15329.59.0", + "cros_img": "hana-release/R112-15359.45.0", "name": "lacros_all_tast_tests HANA_RELEASE_STABLE", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1353,7 +1376,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R114-15410.0.0", + "cros_img": "strongbad-release/R114-15419.0.0", "name": "lacros_all_tast_tests STRONGBAD_RELEASE_LKGM", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1365,7 +1388,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R113-15393.12.0", + "cros_img": "strongbad-release/R114-15416.0.0", "name": "lacros_all_tast_tests strongbad_RELEASE_DEV", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1377,7 +1400,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R112-15359.37.0", + "cros_img": "strongbad-release/R113-15393.12.0", "name": "lacros_all_tast_tests STRONGBAD_RELEASE_BETA", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1389,7 +1412,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R111-15329.59.0", + "cros_img": "strongbad-release/R112-15359.45.0", "name": "lacros_all_tast_tests STRONGBAD_RELEASE_STABLE", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1401,7 +1424,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R114-15410.0.0", + "cros_img": "hana-release/R114-15419.0.0", "name": "ozone_unittests HANA_RELEASE_LKGM", "swarming": {}, "test": "ozone_unittests", @@ -1412,7 +1435,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R113-15393.12.0", + "cros_img": "hana-release/R114-15410.0.0", "name": "ozone_unittests HANA_RELEASE_DEV", "swarming": {}, "test": "ozone_unittests", @@ -1423,7 +1446,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R112-15359.37.0", + "cros_img": "hana-release/R113-15393.12.0", "name": "ozone_unittests HANA_RELEASE_BETA", "swarming": {}, "test": "ozone_unittests", @@ -1434,7 +1457,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R111-15329.59.0", + "cros_img": "hana-release/R112-15359.45.0", "name": "ozone_unittests HANA_RELEASE_STABLE", "swarming": {}, "test": "ozone_unittests", @@ -1445,7 +1468,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R114-15410.0.0", + "cros_img": "strongbad-release/R114-15419.0.0", "name": "ozone_unittests STRONGBAD_RELEASE_LKGM", "swarming": {}, "test": "ozone_unittests", @@ -1456,7 +1479,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R113-15393.12.0", + "cros_img": "strongbad-release/R114-15416.0.0", "name": "ozone_unittests strongbad_RELEASE_DEV", "swarming": {}, "test": "ozone_unittests", @@ -1467,7 +1490,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R112-15359.37.0", + "cros_img": "strongbad-release/R113-15393.12.0", "name": "ozone_unittests STRONGBAD_RELEASE_BETA", "swarming": {}, "test": "ozone_unittests", @@ -1478,7 +1501,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R111-15329.59.0", + "cros_img": "strongbad-release/R112-15359.45.0", "name": "ozone_unittests STRONGBAD_RELEASE_STABLE", "swarming": {}, "test": "ozone_unittests", @@ -1489,7 +1512,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R114-15410.0.0", + "cros_img": "hana-release/R114-15419.0.0", "name": "viz_unittests HANA_RELEASE_LKGM", "swarming": {}, "test": "viz_unittests", @@ -1500,7 +1523,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R113-15393.12.0", + "cros_img": "hana-release/R114-15410.0.0", "name": "viz_unittests HANA_RELEASE_DEV", "swarming": {}, "test": "viz_unittests", @@ -1511,7 +1534,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R112-15359.37.0", + "cros_img": "hana-release/R113-15393.12.0", "name": "viz_unittests HANA_RELEASE_BETA", "swarming": {}, "test": "viz_unittests", @@ -1522,7 +1545,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R111-15329.59.0", + "cros_img": "hana-release/R112-15359.45.0", "name": "viz_unittests HANA_RELEASE_STABLE", "swarming": {}, "test": "viz_unittests", @@ -1533,7 +1556,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R114-15410.0.0", + "cros_img": "strongbad-release/R114-15419.0.0", "name": "viz_unittests STRONGBAD_RELEASE_LKGM", "swarming": {}, "test": "viz_unittests", @@ -1544,7 +1567,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R113-15393.12.0", + "cros_img": "strongbad-release/R114-15416.0.0", "name": "viz_unittests strongbad_RELEASE_DEV", "swarming": {}, "test": "viz_unittests", @@ -1555,7 +1578,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R112-15359.37.0", + "cros_img": "strongbad-release/R113-15393.12.0", "name": "viz_unittests STRONGBAD_RELEASE_BETA", "swarming": {}, "test": "viz_unittests", @@ -1566,7 +1589,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R111-15329.59.0", + "cros_img": "strongbad-release/R112-15359.45.0", "name": "viz_unittests STRONGBAD_RELEASE_STABLE", "swarming": {}, "test": "viz_unittests",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index af94686..523ace0 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -267,12 +267,6 @@ "--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw", ], 'swarming': { - 'dimension_sets': [ - { - # TODO(crbug.com/1412588): Remove when Jammy is the default. - 'os': 'Ubuntu-22.04', - }, - ], 'shards': 8, }, }, @@ -636,12 +630,6 @@ "--additional-env-var=LLVM_PROFILE_FILE=${ISOLATED_OUTDIR}/profraw/default-%2m.profraw", ], 'swarming': { - 'dimension_sets': [ - { - # TODO(crbug.com/1412588): Remove when Jammy is the default. - 'os': 'Ubuntu-22.04', - }, - ], 'shards': 10, }, }, @@ -1050,12 +1038,6 @@ }, 'Linux Tests': { 'swarming': { - 'dimension_sets': [ - { - # TODO(crbug.com/1412588): Remove when Jammy is the default. - 'os': 'Ubuntu-22.04', - }, - ], 'shards': 20, }, }, @@ -1744,16 +1726,6 @@ 'shards': 2, }, }, - 'Linux Tests': { - 'swarming': { - 'dimension_sets': [ - { - # TODO(crbug.com/1412588): Remove when Jammy is the default. - 'os': 'Ubuntu-22.04', - }, - ], - }, - }, # https://crbug.com/1344223 'Mac10.13 Tests': { 'swarming': { @@ -1857,16 +1829,6 @@ 'shards': 30, }, }, - 'Linux Tests': { - 'swarming': { - 'dimension_sets': [ - { - # TODO(crbug.com/1412588): Remove when Jammy is the default. - 'os': 'Ubuntu-22.04', - }, - ], - }, - }, 'Mac ASan 64 Tests (1)': { # https://crbug.com/1200640 'experiment_percentage': 100, }, @@ -2778,16 +2740,6 @@ 'shards': 32, # Adjusted for testing, see https://crbug.com/1179567 }, }, - 'Linux Tests': { - 'swarming': { - 'dimension_sets': [ - { - # TODO(crbug.com/1412588): Remove when Jammy is the default. - 'os': 'Ubuntu-22.04', - }, - ], - }, - }, # https://crbug.com/1192997 'Linux Tests (Wayland)': { 'args': [ @@ -3693,16 +3645,6 @@ 'shards': 6, }, }, - 'Linux Tests': { - 'swarming': { - 'dimension_sets': [ - { - # TODO(crbug.com/1412588): Remove when Jammy is the default. - 'os': 'Ubuntu-22.04', - }, - ], - }, - }, 'Mac ASan 64 Tests (1)': { 'swarming': { 'shards': 3, @@ -3836,14 +3778,6 @@ '--xvfb', '--jobs=1', ], - 'swarming': { - 'dimension_sets': [ - { - # TODO(crbug.com/1412588): Remove when Jammy is the default. - 'os': 'Ubuntu-22.04', - }, - ], - }, }, 'Linux Tests (dbg)(1)': { 'args': [
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 82648a3..5868cb0 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -6699,6 +6699,14 @@ }, }, + 'chromeos_jacuzzi_skylab_tests': { + 'chromeos_chrome_all_tast_tests': { + 'variants': [ + 'CROS_JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM', + ] + }, + }, + 'chromeos_octopus_skylab_tests': { 'chromeos_chrome_all_tast_tests': { 'variants': [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index ccb6e0549..bbcc5dc 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,16 +22,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5710.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5711.3/test_ash_chrome', ], - 'description': 'Run with ash-chrome version 114.0.5710.0', + 'description': 'Run with ash-chrome version 114.0.5711.3', 'identifier': 'Lacros version skew testing ash canary', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v114.0.5710.0', - 'revision': 'version:114.0.5710.0', + 'location': 'lacros_version_skew_tests_v114.0.5711.3', + 'revision': 'version:114.0.5711.3', }, ], }, @@ -383,8 +383,8 @@ 'CROS_BRYA_RELEASE_LKGM': { 'skylab': { 'cros_board': 'brya', - 'cros_chrome_version': '114.0.5685.0', - 'cros_img': 'brya-release/R114-15407.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'brya-release/R114-15419.0.0', 'autotest_name': 'tast.chrome-from-tls', 'shards': 10, }, @@ -394,8 +394,8 @@ 'CROS_DEDEDE_RELEASE_LKGM': { 'skylab': { 'cros_board': 'dedede', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'dedede-release/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'dedede-release/R114-15419.0.0', }, 'enabled': True, 'identifier': 'DEDEDE_RELEASE_LKGM', @@ -403,8 +403,8 @@ 'CROS_DEDEDE_RELEASE_DEV': { 'skylab': { 'cros_board': 'dedede', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'dedede-release/R113-15393.12.0', + 'cros_chrome_version': '114.0.5703.0', + 'cros_img': 'dedede-release/R114-15416.0.0', }, 'enabled': True, 'identifier': 'DEDEDE_RELEASE_DEV', @@ -412,8 +412,8 @@ 'CROS_DEDEDE_RELEASE_BETA': { 'skylab': { 'cros_board': 'dedede', - 'cros_chrome_version': '112.0.5615.45', - 'cros_img': 'dedede-release/R112-15359.37.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'dedede-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'DEDEDE_RELEASE_BETA', @@ -430,8 +430,8 @@ 'CROS_EVE_RELEASE_LKGM': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'eve-release/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'eve-release/R114-15419.0.0', }, 'enabled': True, 'identifier': 'EVE_RELEASE_LKGM', @@ -439,8 +439,8 @@ 'CROS_EVE_RELEASE_DEV': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'eve-release/R113-15393.12.0', + 'cros_chrome_version': '114.0.5703.0', + 'cros_img': 'eve-release/R114-15416.0.0', }, 'enabled': True, 'identifier': 'EVE_RELEASE_DEV', @@ -448,8 +448,8 @@ 'CROS_EVE_RELEASE_BETA': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '112.0.5615.45', - 'cros_img': 'eve-release/R112-15359.37.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'eve-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'EVE_RELEASE_BETA', @@ -457,8 +457,8 @@ 'CROS_EVE_RELEASE_STABLE': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '111.0.5563.118', - 'cros_img': 'eve-release/R111-15329.59.0', + 'cros_chrome_version': '112.0.5615.62', + 'cros_img': 'eve-release/R112-15359.45.0', }, 'enabled': True, 'identifier': 'EVE_RELEASE_STABLE', @@ -466,8 +466,8 @@ 'CROS_EVE_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'eve-public/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'eve-public/R114-15419.0.0', 'bucket': 'chromiumos-image-archive', }, 'enabled': True, @@ -476,8 +476,8 @@ 'CROS_HANA_RELEASE_LKGM': { 'skylab': { 'cros_board': 'hana', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'hana-release/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'hana-release/R114-15419.0.0', }, 'enabled': True, 'identifier': 'HANA_RELEASE_LKGM', @@ -485,8 +485,8 @@ 'CROS_HANA_RELEASE_DEV': { 'skylab': { 'cros_board': 'hana', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'hana-release/R113-15393.12.0', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'hana-release/R114-15410.0.0', }, 'enabled': True, 'identifier': 'HANA_RELEASE_DEV', @@ -494,8 +494,8 @@ 'CROS_HANA_RELEASE_BETA': { 'skylab': { 'cros_board': 'hana', - 'cros_chrome_version': '112.0.5615.45', - 'cros_img': 'hana-release/R112-15359.37.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'hana-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'HANA_RELEASE_BETA', @@ -503,8 +503,8 @@ 'CROS_HANA_RELEASE_STABLE': { 'skylab': { 'cros_board': 'hana', - 'cros_chrome_version': '111.0.5563.118', - 'cros_img': 'hana-release/R111-15329.59.0', + 'cros_chrome_version': '112.0.5615.62', + 'cros_img': 'hana-release/R112-15359.45.0', }, 'enabled': True, 'identifier': 'HANA_RELEASE_STABLE', @@ -512,8 +512,8 @@ 'CROS_HEROBRINE_RELEASE_LKGM': { 'skylab': { 'cros_board': 'herobrine', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'herobrine-release/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'herobrine-release/R114-15419.0.0', }, 'enabled': True, 'identifier': 'HEROBRINE_RELEASE_LKGM', @@ -521,8 +521,8 @@ 'CROS_JACUZZI_RELEASE_LKGM': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'jacuzzi-release/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'jacuzzi-release/R114-15419.0.0', }, 'enabled': True, 'identifier': 'JACUZZI_RELEASE_LKGM', @@ -530,8 +530,8 @@ 'CROS_JACUZZI_RELEASE_DEV': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'jacuzzi-release/R113-15393.12.0', + 'cros_chrome_version': '114.0.5703.0', + 'cros_img': 'jacuzzi-release/R114-15416.0.0', }, 'enabled': True, 'identifier': 'JACUZZI_RELEASE_DEV', @@ -539,17 +539,29 @@ 'CROS_JACUZZI_RELEASE_BETA': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '112.0.5615.45', - 'cros_img': 'jacuzzi-release/R112-15359.37.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'jacuzzi-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'JACUZZI_RELEASE_BETA', }, + 'CROS_JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM': { + 'skylab': { + 'cros_board': 'jacuzzi', + 'cros_chrome_version': '114.0.5692.0', + 'cros_img': 'jacuzzi-release/R114-15410.0.0', + 'tast_expr': '("group:mainline" && !informational)', + 'autotest_name': 'tast.chrome-from-tls', + 'shards': 10, + }, + 'enabled': True, + 'identifier': 'JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM', + }, 'CROS_JACUZZI_RELEASE_STABLE': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '111.0.5563.118', - 'cros_img': 'jacuzzi-release/R111-15329.59.0', + 'cros_chrome_version': '112.0.5615.62', + 'cros_img': 'jacuzzi-release/R112-15359.45.0', }, 'enabled': True, 'identifier': 'JACUZZI_RELEASE_STABLE', @@ -557,8 +569,8 @@ 'CROS_JACUZZI_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'jacuzzi-public/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'jacuzzi-public/R114-15419.0.0', 'bucket': 'chromiumos-image-archive', }, 'enabled': True, @@ -567,8 +579,8 @@ 'CROS_JACUZZI_CQ_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'jacuzzi-public/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'jacuzzi-public/R114-15419.0.0', 'bucket': 'chromiumos-image-archive', 'public_builder': 'cros_test_platform_public', 'public_builder_bucket': 'testplatform-public', @@ -579,8 +591,8 @@ 'CROS_KEVIN64_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'kevin', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'kevin64-public/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'kevin64-public/R114-15419.0.0', 'bucket': 'chromiumos-image-archive', }, 'enabled': True, @@ -599,8 +611,8 @@ 'CROS_OCTOPUS_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'octopus-public/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'octopus-public/R114-15419.0.0', 'bucket': 'chromiumos-image-archive', }, 'enabled': True, @@ -609,8 +621,8 @@ 'CROS_OCTOPUS_RELEASE_CHROME_FROM_TLS_LKGM': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '114.0.5689.0', - 'cros_img': 'octopus-release/R114-15408.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'octopus-release/R114-15419.0.0', 'tast_expr': '("group:mainline" && !informational)', 'autotest_name': 'tast.chrome-from-tls', 'shards': 10, @@ -621,8 +633,8 @@ 'CROS_OCTOPUS_RELEASE_LKGM': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'octopus-release/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'octopus-release/R114-15419.0.0', }, 'enabled': True, 'identifier': 'OCTOPUS_RELEASE_LKGM', @@ -630,8 +642,8 @@ 'CROS_OCTOPUS_RELEASE_DEV': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'octopus-release/R113-15393.12.0', + 'cros_chrome_version': '114.0.5703.0', + 'cros_img': 'octopus-release/R114-15416.0.0', }, 'enabled': True, 'identifier': 'OCTOPUS_RELEASE_DEV', @@ -639,8 +651,8 @@ 'CROS_OCTOPUS_RELEASE_BETA': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '112.0.5615.45', - 'cros_img': 'octopus-release/R112-15359.37.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'octopus-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'OCTOPUS_RELEASE_BETA', @@ -648,8 +660,8 @@ 'CROS_OCTOPUS_RELEASE_STABLE': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '111.0.5563.118', - 'cros_img': 'octopus-release/R111-15329.59.0', + 'cros_chrome_version': '112.0.5615.62', + 'cros_img': 'octopus-release/R112-15359.45.0', }, 'enabled': True, 'identifier': 'OCTOPUS_RELEASE_STABLE', @@ -657,8 +669,8 @@ 'CROS_STRONGBAD_RELEASE_LKGM': { 'skylab': { 'cros_board': 'strongbad', - 'cros_chrome_version': '114.0.5692.0', - 'cros_img': 'strongbad-release/R114-15410.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'strongbad-release/R114-15419.0.0', }, 'enabled': True, 'identifier': 'STRONGBAD_RELEASE_LKGM', @@ -666,8 +678,8 @@ 'CROS_STRONGBAD_RELEASE_DEV': { 'skylab': { 'cros_board': 'strongbad', - 'cros_chrome_version': '113.0.5672.21', - 'cros_img': 'strongbad-release/R113-15393.12.0', + 'cros_chrome_version': '114.0.5703.0', + 'cros_img': 'strongbad-release/R114-15416.0.0', }, 'enabled': True, 'identifier': 'strongbad_RELEASE_DEV', @@ -675,8 +687,8 @@ 'CROS_STRONGBAD_RELEASE_BETA': { 'skylab': { 'cros_board': 'strongbad', - 'cros_chrome_version': '112.0.5615.45', - 'cros_img': 'strongbad-release/R112-15359.37.0', + 'cros_chrome_version': '113.0.5672.21', + 'cros_img': 'strongbad-release/R113-15393.12.0', }, 'enabled': True, 'identifier': 'STRONGBAD_RELEASE_BETA', @@ -684,8 +696,8 @@ 'CROS_STRONGBAD_RELEASE_STABLE': { 'skylab': { 'cros_board': 'strongbad', - 'cros_chrome_version': '111.0.5563.118', - 'cros_img': 'strongbad-release/R111-15329.59.0', + 'cros_chrome_version': '112.0.5615.62', + 'cros_img': 'strongbad-release/R112-15359.45.0', }, 'enabled': True, 'identifier': 'STRONGBAD_RELEASE_STABLE', @@ -693,8 +705,8 @@ 'CROS_TROGDOR_RELEASE_LKGM': { 'skylab': { 'cros_board': 'trogdor', - 'cros_chrome_version': '114.0.5685.0', - 'cros_img': 'trogdor-release/R114-15407.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'trogdor-release/R114-15419.0.0', 'autotest_name': 'tast.chrome-from-tls', 'shards': 10, }, @@ -704,8 +716,8 @@ 'CROS_VOLTEER_RELEASE_LKGM': { 'skylab': { 'cros_board': 'volteer', - 'cros_chrome_version': '114.0.5685.0', - 'cros_img': 'volteer-release/R114-15407.0.0', + 'cros_chrome_version': '114.0.5707.0', + 'cros_img': 'volteer-release/R114-15419.0.0', 'autotest_name': 'tast.chrome-from-tls', 'shards': 10, },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index bc1dd9c..bb48f58f 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -4948,7 +4948,7 @@ 'Linux Tests': { 'mixins': [ 'isolate_profile_data', - 'linux-bionic', + 'linux-jammy', ], 'test_suites': { 'gtest_tests': 'chromium_linux_gtests', @@ -6716,6 +6716,16 @@ ], 'test_suites': { 'skylab_tests': 'chromeos_brya_skylab_tests', + } + }, + 'chromeos-jacuzzi-chrome-skylab-fyi': { + 'additional_compile_targets': [ + "chrome", + "linux_symbols", + "symupload", + ], + 'test_suites': { + 'skylab_tests': 'chromeos_jacuzzi_skylab_tests', }, 'os_type': 'chromeos', },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index e5c51d40..084619c 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -4325,21 +4325,6 @@ ] } ], - "DiscoverFeedMultiColumn": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "DiscoverFeedMultiColumn" - ] - } - ] - } - ], "DnsHttpsSvcbTimeout": [ { "platforms": [
diff --git a/third_party/blink/public/common/input/web_gesture_event.h b/third_party/blink/public/common/input/web_gesture_event.h index 16a5540f3..889e607 100644 --- a/third_party/blink/public/common/input/web_gesture_event.h +++ b/third_party/blink/public/common/input/web_gesture_event.h
@@ -107,14 +107,14 @@ // True if this event is generated from a mousewheel or scrollbar. // Synthetic GSB(s) are ignored by the blink::ElasticOverscrollController. bool synthetic; - // If true, this event has been hit tested by the main thread and the - // result is stored in scrollable_area_element_id. Used only in scroll - // unification when the event is sent back the the compositor for a - // second time after the main thread hit test is complete. - bool main_thread_hit_tested; // If true, this event will be used for cursor control instead of // scrolling. the entire scroll sequence will be used for cursor control. bool cursor_control; + // If nonzero, this event has been hit tested by the main thread and the + // result is stored in scrollable_area_element_id. Used only in scroll + // unification when the event is sent back the the compositor for a + // second time after the main thread hit test is complete. + uint32_t main_thread_hit_tested_reasons; } scroll_begin; struct {
diff --git a/third_party/blink/renderer/controller/BUILD.gn b/third_party/blink/renderer/controller/BUILD.gn index 64214a7..53cc163 100644 --- a/third_party/blink/renderer/controller/BUILD.gn +++ b/third_party/blink/renderer/controller/BUILD.gn
@@ -88,20 +88,17 @@ "memory_usage_monitor_win.h", ] } - if (is_mac) { + if (is_apple) { sources += [ "memory_usage_monitor_mac.cc", "memory_usage_monitor_mac.h", ] - frameworks = [ - "AppKit.framework", - "Foundation.framework", - ] + frameworks = [ "Foundation.framework" ] } # HighestPmfReporter depends on MemoryUsageMonitor and MemoryUsageMonitor # depends on platform specific code. Explicitly specify supported platforms. - if (is_linux || is_chromeos || is_win || is_android || is_mac) { + if (is_linux || is_chromeos || is_win || is_android || is_apple) { sources += [ "highest_pmf_reporter.cc", "highest_pmf_reporter.h", @@ -262,7 +259,7 @@ ] } - if (is_linux || is_chromeos || is_android || is_mac || is_win) { + if (is_linux || is_chromeos || is_android || is_apple || is_win) { sources += [ "highest_pmf_reporter_test.cc", "memory_usage_monitor_test.cc",
diff --git a/third_party/blink/renderer/controller/blink_initializer.cc b/third_party/blink/renderer/controller/blink_initializer.cc index f2063994..0de3ed1 100644 --- a/third_party/blink/renderer/controller/blink_initializer.cc +++ b/third_party/blink/renderer/controller/blink_initializer.cc
@@ -83,7 +83,7 @@ #endif #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ - BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) + BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) #include "third_party/blink/renderer/controller/highest_pmf_reporter.h" #include "third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.h" #endif @@ -270,7 +270,7 @@ #endif #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ - BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) + BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) // Start reporting the highest private memory footprint after the first // navigation. HighestPmfReporter::Initialize(main_thread_task_runner);
diff --git a/third_party/blink/renderer/controller/memory_usage_monitor_mac.cc b/third_party/blink/renderer/controller/memory_usage_monitor_mac.cc index 8eba47c..286a9591 100644 --- a/third_party/blink/renderer/controller/memory_usage_monitor_mac.cc +++ b/third_party/blink/renderer/controller/memory_usage_monitor_mac.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/renderer/controller/memory_usage_monitor_mac.h" #include <mach/mach.h> -#include <mach/mach_vm.h> #include "base/mac/mac_util.h" #include "third_party/blink/public/platform/platform.h"
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 1884b9a3..68fd971 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -2988,31 +2988,58 @@ RecalcStyle(change, StyleRecalcContext::FromAncestors(container)); } -void StyleEngine::RecalcStyleForNonLayoutNGContainerDescendants( - Element& container) { +void StyleEngine::UpdateStyleForNonEligibleContainer(Element& container) { DCHECK(InRebuildLayoutTree()); - - // This method is called from AttachLayoutTree() when we are forced to use - // legacy layout for a query container. At the time of RecalcStyle, it is not - // necessarily known that some sibling tree may enforce us to have legacy - // layout, which means we may have skipped style recalc for the container - // subtree. Style recalc will not be resumed during layout for legacy layout. - // Instead, finish recalc for the subtree when it is discovered that the - // container is in legacy layout. - // Also, this method is called to complete a skipped style recalc where we - // could not predict that the LayoutObject would not be created, like if the - // parent LayoutObject returns false for IsChildAllowed. + // This method is called from AttachLayoutTree() when we skipped style recalc + // for descendants of a size query container but figured that the LayoutObject + // we created is not going to be reached for layout in ng_block_node.cc where + // we would otherwise resume style recalc. + // + // This may be due to legacy layout fallback, inline box, table box, etc. + // Also, if we could not predict that the LayoutObject would not be created, + // like if the parent LayoutObject returns false for IsChildAllowed. auto* cq_data = container.GetContainerQueryData(); if (!cq_data) { return; } - if (cq_data->SkippedStyleRecalc()) { - DecrementSkippedContainerRecalc(); - AllowMarkForReattachFromRebuildLayoutTreeScope allow_reattach(*this); - base::AutoReset<bool> cq_recalc(&in_container_query_style_recalc_, true); - RecalcStyleForContainer(container, {}); + StyleRecalcChange change; + if (ContainerQueryEvaluator* evaluator = + cq_data->GetContainerQueryEvaluator()) { + ContainerQueryEvaluator::Change query_change = + evaluator->SizeContainerChanged(GetDocument(), container, + PhysicalSize(), kPhysicalAxisNone); + switch (query_change) { + case ContainerQueryEvaluator::Change::kNone: + DCHECK(cq_data->SkippedStyleRecalc()); + break; + case ContainerQueryEvaluator::Change::kNearestContainer: + if (!IsShadowHost(container)) { + change = change.ForceRecalcSizeContainer(); + break; + } + // Since the nearest container is found in shadow-including ancestors + // and not in flat tree ancestors, and style recalc traversal happens in + // flat tree order, we need to invalidate inside flat tree descendant + // containers if such containers are inside shadow trees. + // + // See also StyleRecalcChange::FlagsForChildren where we turn + // kRecalcContainer into kRecalcDescendantContainers when traversing + // past a shadow host. + [[fallthrough]]; + case ContainerQueryEvaluator::Change::kDescendantContainers: + change = change.ForceRecalcDescendantSizeContainers(); + break; + } + if (query_change != ContainerQueryEvaluator::Change::kNone) { + container.ComputedStyleRef().ClearCachedPseudoElementStyles(); + } } + + DecrementSkippedContainerRecalc(); + AllowMarkForReattachFromRebuildLayoutTreeScope allow_reattach(*this); + base::AutoReset<bool> cq_recalc(&in_container_query_style_recalc_, true); + RecalcStyleForContainer(container, change); } void StyleEngine::UpdateStyleAndLayoutTreeForContainer(
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index eeb1ca0b..3730954 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -578,7 +578,10 @@ void UpdateStyleAndLayoutTreeForContainer(Element& container, const LogicalSize&, LogicalAxes contained_axes); - void RecalcStyleForNonLayoutNGContainerDescendants(Element& container); + // To be called from layout-tree building for subtree skipped for style + // recalcs when we found out the container is eligible for size containment + // after all. + void UpdateStyleForNonEligibleContainer(Element& container); void RecalcStyle(); void ClearEnsuredDescendantStyles(Element& element);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index b3cfc15f..1a445402 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2793,11 +2793,16 @@ bool being_rendered = context.parent && style && !style->IsEnsuredInDisplayNone(); + bool skipped_container_descendants = SkippedContainerStyleRecalc(); + if (!being_rendered && !ChildNeedsReattachLayoutTree()) { - // We may have skipped recalc for this Element if it's a container query - // container. This recalc must be resumed now, since we're not going to + // We may have skipped recalc for this Element if it's a query container for + // size queries. This recalc must be resumed now, since we're not going to // create a LayoutObject for the Element after all. - style_engine.RecalcStyleForNonLayoutNGContainerDescendants(*this); + if (skipped_container_descendants) { + style_engine.UpdateStyleForNonEligibleContainer(*this); + skipped_container_descendants = false; + } // The above recalc may have marked some descendant for reattach, which // would set the child-needs flag. if (!ChildNeedsReattachLayoutTree()) { @@ -2834,20 +2839,14 @@ } children_context.use_previous_in_flow = true; - if ((being_rendered && !children_context.parent) || - (layout_object && - !IsGuaranteedToEnterNGBlockNodeLayout(*layout_object))) { - // If the created LayoutObject is forced into a legacy object, or if a - // LayoutObject was not created, even if we thought it should have been, for - // instance because the parent LayoutObject returns false for - // IsChildAllowed, we need to complete the skipped style recalc for size - // query containers as we would not have an NGBlockNode to resume from. - style_engine.RecalcStyleForNonLayoutNGContainerDescendants(*this); + if (skipped_container_descendants && + (!layout_object || !layout_object->IsEligibleForSizeContainment())) { + style_engine.UpdateStyleForNonEligibleContainer(*this); + skipped_container_descendants = false; } - bool skip_container_descendants = SkippedContainerStyleRecalc(); bool skip_lock_descendants = ChildStyleRecalcBlockedByDisplayLock(); - if (skip_container_descendants || skip_lock_descendants) { + if (skipped_container_descendants || skip_lock_descendants) { // Since we block style recalc on descendants of this node due to display // locking or container queries, none of its descendants should have the // NeedsReattachLayoutTree bit set. @@ -3104,12 +3103,8 @@ DCHECK(!child_change.TraverseChildren(*this)); return false; } - if (child_change.ReattachLayoutTree()) { - if (!LayoutObjectIsNeeded(style) || style.Display() == EDisplay::kInline || - style.IsDisplayTableType()) { - return false; - } - } else { + + if (!child_change.ReattachLayoutTree()) { LayoutObject* layout_object = GetLayoutObject(); if (!layout_object || !layout_object->SelfNeedsLayout() || !layout_object->IsEligibleForSizeContainment() || @@ -3528,6 +3523,9 @@ // ending up calling StyleResolver::ResolveStyle()). new_style = StyleForLayoutObject(new_style_recalc_context); } + bool base_is_display_none = + !new_style || + new_style->GetBaseComputedStyleOrThis()->Display() == EDisplay::kNone; if (new_style && !ShouldStoreComputedStyle(*new_style)) { new_style = nullptr; if (auto* ax_cache = GetDocument().ExistingAXObjectCache()) { @@ -3642,7 +3640,14 @@ ElementRareDataVector* rare_data = GetElementRareData(); if (ElementAnimations* element_animations = rare_data->GetElementAnimations()) { - element_animations->CssAnimations().Cancel(); + // The animation should only be canceled when the base style is + // display:none. If new_style is otherwise set to display:none, then it + // means an animation set display:none, and an animation shouldn't + // cancel itself in this case. + if (base_is_display_none || + !RuntimeEnabledFeatures::CSSDisplayAnimationEnabled()) { + element_animations->CssAnimations().Cancel(); + } } rare_data->SetContainerQueryEvaluator(nullptr); rare_data->ClearPseudoElements();
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index ab0751f..9bd1f83 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -3532,7 +3532,10 @@ if (injected_type == WebInputEvent::Type::kGestureScrollBegin) { gesture_event->data.scroll_begin.scrollable_area_element_id = scrollable_area_element_id.GetInternalValue(); - gesture_event->data.scroll_begin.main_thread_hit_tested = true; + gesture_event->data.scroll_begin.main_thread_hit_tested_reasons = + device == WebGestureDevice::kScrollbar + ? cc::MainThreadScrollingReason::kScrollbarScrolling + : cc::MainThreadScrollingReason::kFailedHitTest; } // Notifies TestWebFrameWidget of the injected event. Does nothing outside
diff --git a/third_party/blink/renderer/core/html/forms/resources/time_picker.css b/third_party/blink/renderer/core/html/forms/resources/time_picker.css index d03b7e1..85d7192e 100644 --- a/third_party/blink/renderer/core/html/forms/resources/time_picker.css +++ b/third_party/blink/renderer/core/html/forms/resources/time_picker.css
@@ -40,11 +40,12 @@ border-radius: 2px; color: #101010; font-size: 14px; - height: 32px; + height: 36px; line-height: 32px; position: relative; text-align: center; - width: 48px; + width: 52px; + box-sizing: border-box; } .time-cell:hover {
diff --git a/third_party/blink/renderer/core/html/forms/resources/time_picker.js b/third_party/blink/renderer/core/html/forms/resources/time_picker.js index 3a2309c1..e81e2782 100644 --- a/third_party/blink/renderer/core/html/forms/resources/time_picker.js +++ b/third_party/blink/renderer/core/html/forms/resources/time_picker.js
@@ -521,10 +521,16 @@ setupScrollHandler_ = () => { let lastScrollPosition = 0; let upcomingSnapToCellEdge = null; + let suppressScrollChange = false; this.addEventListener('scroll', (event) => { const isGoingDown = (this.scrollTop > lastScrollPosition); lastScrollPosition = this.scrollTop; + if (suppressScrollChange) { + suppressScrollChange = false; + return; + } + // Rotate cells down until there is one cell beyond the bottom // of the visible scroller area. while (this.cellsInLayoutOrder[this.cellsInLayoutOrder.length - 1] @@ -548,27 +554,32 @@ // CSS scroll-snap-align, but it interferes with this scroll handler // and causes jittery scrolling. window.clearTimeout(upcomingSnapToCellEdge); - upcomingSnapToCellEdge = - window.setTimeout(() => {this.snapToCellEdge_(isGoingDown)}, 1000); + upcomingSnapToCellEdge = window.setTimeout(() => { + const offset = this.calcOffsetFromCellEdge_(isGoingDown); + if (offset != 0) { + suppressScrollChange = true; + this.scrollTop += offset; + } + }, 1000); }); }; /* - * Scroll the column so that the top is aligned with the top edge of the - * nearest TimeCell in the given direction. + * Calculate offset form a cell top / bottom edge based on scrolling direction. */ - snapToCellEdge_ = (isGoingDown) => { + calcOffsetFromCellEdge_ = (isGoingDown) => { const offsetFromCellEdge = (this.cellsInLayoutOrder[this.cellsInLayoutOrder.length - 1].offsetTop - this.scrollTop) % TimeColumn.CELL_HEIGHT; if (isGoingDown) { - this.scrollTop += offsetFromCellEdge; + return offsetFromCellEdge; } else { if (offsetFromCellEdge != 0) { - this.scrollTop -= TimeColumn.CELL_HEIGHT - offsetFromCellEdge; + return -(TimeColumn.CELL_HEIGHT - offsetFromCellEdge); } } + return 0; }; // Ideally we would have truly infinite scrolling in both directions.
diff --git a/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc b/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc index e7e6a848d..3daa237 100644 --- a/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc
@@ -159,7 +159,8 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // cc reports the below reasons because #box is not composited. EXPECT_TOUCH_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_TOUCH_BUCKET( BucketIndex(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText), 1); @@ -195,7 +196,8 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // cc reports the below reasons because #box is not composited. EXPECT_WHEEL_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_WHEEL_BUCKET( BucketIndex(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText), 1); @@ -243,7 +245,8 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // cc reports the below reasons because #box is not composited. EXPECT_WHEEL_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_WHEEL_BUCKET( BucketIndex(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText), 1); @@ -305,7 +308,8 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // cc reports the below reasons because #box is not composited. EXPECT_WHEEL_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_WHEEL_BUCKET( BucketIndex(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText), 1); @@ -342,13 +346,14 @@ if (base::FeatureList::IsEnabled(::features::kScrollUnification)) { // The overflow: hidden element is still a non-fast scroll region, so cc // reports the following for the second scroll: - // kFailedHitTest + // kNonFastScrollableRegion // kScrollingOnMainForAnyReason // // Since #box is overflow: hidden, the hit test returns the viewport, and // so we do not log kNoScrollingLayer again. EXPECT_WHEEL_BUCKET( - BucketIndex(cc::MainThreadScrollingReason::kFailedHitTest), 1); + BucketIndex(cc::MainThreadScrollingReason::kNonFastScrollableRegion), + 1); EXPECT_WHEEL_BUCKET( cc::MainThreadScrollingReason::kScrollingOnMainForAnyReason, 1); EXPECT_WHEEL_TOTAL(2);
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc index 18d8aac..8a1d560c 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -30,6 +30,10 @@ namespace { bool ShouldPreferCompositingForLayoutView(const LayoutView& layout_view) { + if (layout_view.GetFrame()->IsLocalRoot()) { + return true; + } + auto has_direct_compositing_reasons = [](const LayoutObject* object) -> bool { return object && CompositingReasonFinder:: @@ -315,11 +319,9 @@ reasons |= CompositingReason::kPreserve3DWith3DDescendants; } - if (layer->IsRootLayer() && object.GetFrame()->IsLocalRoot()) - reasons |= CompositingReason::kRoot; - - if (RequiresCompositingForRootScroller(*layer)) + if (RequiresCompositingForRootScroller(object)) { reasons |= CompositingReason::kRootScroller; + } reasons |= CompositingReasonsForScrollDependentPosition( *layer, container_for_fixed_position); @@ -458,16 +460,16 @@ } bool CompositingReasonFinder::RequiresCompositingForRootScroller( - const PaintLayer& layer) { + const LayoutObject& object) { // The root scroller needs composited scrolling layers even if it doesn't // actually have scrolling since CC has these assumptions baked in for the // viewport. Because this is only needed for CC, we can skip it if // compositing is not enabled. - const auto& settings = *layer.GetLayoutObject().GetDocument().GetSettings(); - if (!settings.GetAcceleratedCompositingEnabled()) + if (!object.GetFrame()->GetSettings()->GetAcceleratedCompositingEnabled()) { return false; + } - return layer.GetLayoutObject().IsGlobalRootScroller(); + return object.IsGlobalRootScroller(); } } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h index b78cf9d..f8812574 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
@@ -11,17 +11,13 @@ namespace blink { -class PaintLayer; class LayoutObject; class ComputedStyle; class CORE_EXPORT CompositingReasonFinder { - DISALLOW_NEW(); + STATIC_ONLY(CompositingReasonFinder); public: - CompositingReasonFinder(const CompositingReasonFinder&) = delete; - CompositingReasonFinder& operator=(const CompositingReasonFinder&) = delete; - // Composited scrolling reason is not included because // PaintLayerScrollableArea needs the result of this function to determine // composited scrolling status. @@ -46,7 +42,7 @@ // that the LayoutObject does not end up using. static CompositingReasons PotentialCompositingReasonsFor3DTransform( const ComputedStyle&); - static bool RequiresCompositingForRootScroller(const PaintLayer&); + static bool RequiresCompositingForRootScroller(const LayoutObject&); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index f53c5af9..25c1af4 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -2499,7 +2499,8 @@ non_composited_main_thread_scrolling_reasons_ = 0; - if (CompositingReasonFinder::RequiresCompositingForRootScroller(*layer_)) { + const auto* box = GetLayoutBox(); + if (CompositingReasonFinder::RequiresCompositingForRootScroller(*box)) { return true; } if (!ScrollsOverflow()) { @@ -2515,7 +2516,6 @@ return false; } - const auto* box = GetLayoutBox(); bool needs_composited_scrolling = true; if (box->GetDocument().GetSettings()->GetLCDTextPreference() == LCDTextPreference::kStronglyPreferred) {
diff --git a/third_party/blink/renderer/modules/compute_pressure/BUILD.gn b/third_party/blink/renderer/modules/compute_pressure/BUILD.gn index afec86ee..d2a222d 100644 --- a/third_party/blink/renderer/modules/compute_pressure/BUILD.gn +++ b/third_party/blink/renderer/modules/compute_pressure/BUILD.gn
@@ -6,6 +6,8 @@ blink_modules_sources("compute_pressure") { sources = [ + "pressure_client_impl.cc", + "pressure_client_impl.h", "pressure_observer.cc", "pressure_observer.h", "pressure_observer_manager.cc",
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_client_impl.cc b/third_party/blink/renderer/modules/compute_pressure/pressure_client_impl.cc new file mode 100644 index 0000000..16e4c63 --- /dev/null +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_client_impl.cc
@@ -0,0 +1,184 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/compute_pressure/pressure_client_impl.h" + +#include "base/task/single_thread_task_runner.h" +#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/page/focus_controller.h" +#include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.h" +#include "third_party/blink/renderer/modules/document_picture_in_picture/picture_in_picture_controller_impl.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" + +using device::mojom::blink::PressureFactor; +using device::mojom::blink::PressureSource; +using device::mojom::blink::PressureState; + +namespace blink { + +namespace { + +V8PressureFactor::Enum PressureFactorToV8PressureFactor(PressureFactor factor) { + switch (factor) { + case PressureFactor::kThermal: + return V8PressureFactor::Enum::kThermal; + case PressureFactor::kPowerSupply: + return V8PressureFactor::Enum::kPowerSupply; + } + NOTREACHED_NORETURN(); +} + +V8PressureState::Enum PressureStateToV8PressureState(PressureState state) { + switch (state) { + case PressureState::kNominal: + return V8PressureState::Enum::kNominal; + case PressureState::kFair: + return V8PressureState::Enum::kFair; + case PressureState::kSerious: + return V8PressureState::Enum::kSerious; + case PressureState::kCritical: + return V8PressureState::Enum::kCritical; + } + NOTREACHED_NORETURN(); +} + +V8PressureSource::Enum PressureSourceToV8PressureSource(PressureSource source) { + switch (source) { + case PressureSource::kCpu: + return V8PressureSource::Enum::kCpu; + } + NOTREACHED_NORETURN(); +} + +} // namespace + +PressureClientImpl::PressureClientImpl(ExecutionContext* context, + PressureObserverManager* manager) + : ExecutionContextClient(context), + manager_(manager), + receiver_(this, context) {} + +PressureClientImpl::~PressureClientImpl() = default; + +void PressureClientImpl::OnPressureUpdated( + device::mojom::blink::PressureUpdatePtr update) { + if (!PassesPrivacyTest()) { + return; + } + + auto source = PressureSourceToV8PressureSource(update->source); + Vector<V8PressureFactor> v8_factors; + for (const auto& factor : update->factors) { + v8_factors.push_back( + V8PressureFactor(PressureFactorToV8PressureFactor(factor))); + } + // New observers may be created and added. Take a snapshot so as + // to safely iterate. + HeapVector<Member<blink::PressureObserver>> observers(observers_); + for (const auto& observer : observers) { + observer->OnUpdate(GetExecutionContext(), source, + PressureStateToV8PressureState(update->state), + v8_factors, + ConvertTimeToDOMHighResTimeStamp(update->timestamp)); + } +} + +void PressureClientImpl::AddObserver(PressureObserver* observer) { + observers_.insert(observer); +} + +void PressureClientImpl::RemoveObserver(PressureObserver* observer) { + observers_.erase(observer); + if (observers_.empty()) { + Reset(); + } +} + +mojo::PendingRemote<device::mojom::blink::PressureClient> +PressureClientImpl::BindNewPipeAndPassRemote() { + scoped_refptr<base::SingleThreadTaskRunner> task_runner = + GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI); + auto remote = receiver_.BindNewPipeAndPassRemote(std::move(task_runner)); + receiver_.set_disconnect_handler( + WTF::BindOnce(&PressureClientImpl::Reset, WrapWeakPersistent(this))); + return remote; +} + +void PressureClientImpl::Reset() { + state_ = State::kUninitialized; + observers_.clear(); + receiver_.reset(); +} + +void PressureClientImpl::Trace(Visitor* visitor) const { + visitor->Trace(manager_); + visitor->Trace(receiver_); + visitor->Trace(observers_); + ExecutionContextClient::Trace(visitor); +} + +// https://wicg.github.io/compute-pressure/#dfn-passes-privacy-test +bool PressureClientImpl::PassesPrivacyTest() const { + const ExecutionContext* context = GetExecutionContext(); + + // TODO(crbug.com/1425053): Check for active needed worker. + if (context->IsDedicatedWorkerGlobalScope() || + context->IsSharedWorkerGlobalScope()) { + return true; + } + + if (!DomWindow()) { + return false; + } + + LocalFrame* this_frame = DomWindow()->GetFrame(); + // 2. If associated document is not fully active, return false. + if (context->IsContextDestroyed() || !this_frame) { + return false; + } + + // 4. If associated document is same-domain with initiators of active + // Picture-in-Picture sessions, return true. + // + // TODO(crbug.com/1396177): A frame should be able to access to + // PressureRecord if it is same-domain with initiators of active + // Picture-in-Picture sessions. However, it is hard to implement now. In + // current implementation, only the frame that triggers Picture-in-Picture + // can access to PressureRecord. + auto& pip_controller = + PictureInPictureControllerImpl::From(*(this_frame->GetDocument())); + if (pip_controller.PictureInPictureElement()) { + return true; + } + + // 5. If browsing context is capturing, return true. + if (this_frame->IsCapturingMedia()) { + return true; + } + + // 7. If top-level browsing context does not have system focus, return false. + DCHECK(this_frame->GetPage()); + const auto& focus_controller = this_frame->GetPage()->GetFocusController(); + if (!focus_controller.IsFocused()) { + return false; + } + + // 8. Let focused document be the currently focused area's node document. + const LocalFrame* focused_frame = focus_controller.FocusedFrame(); + if (!focused_frame) { + return false; + } + + // 9. If origin is same origin-domain with focused document, return true. + // 10. Otherwise, return false. + const SecurityOrigin* focused_frame_origin = + focused_frame->GetSecurityContext()->GetSecurityOrigin(); + const SecurityOrigin* this_origin = + this_frame->GetSecurityContext()->GetSecurityOrigin(); + return focused_frame_origin->CanAccess(this_origin); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_client_impl.h b/third_party/blink/renderer/modules/compute_pressure/pressure_client_impl.h new file mode 100644 index 0000000..3ae6dfcb --- /dev/null +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_client_impl.h
@@ -0,0 +1,80 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COMPUTE_PRESSURE_PRESSURE_CLIENT_IMPL_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_COMPUTE_PRESSURE_PRESSURE_CLIENT_IMPL_H_ + +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "services/device/public/mojom/pressure_manager.mojom-blink.h" +#include "services/device/public/mojom/pressure_update.mojom-blink.h" +#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" +#include "third_party/blink/renderer/modules/compute_pressure/pressure_observer.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h" + +namespace blink { + +class ExecutionContext; +class PressureObserverManager; + +// This class implements the "device::mojom::blink::PressureClient" +// interface to receive "device::mojom::blink::PressureUpdate" from +// "device::PressureManagerImpl" and broadcasts the information to active +// PressureObservers. +// +// This class keeps track of State and active PressureObservers per source type. +class MODULES_EXPORT PressureClientImpl final + : public GarbageCollected<PressureClientImpl>, + public ExecutionContextClient, + public device::mojom::blink::PressureClient { + public: + // kUninitialized: receiver_ is not bound. + // kInitializing: receiver_ is bound but the remote side is not bound. + // kInitialized: receiver_ and the remote side are both bound. + enum class State { kUninitialized, kInitializing, kInitialized }; + + PressureClientImpl(ExecutionContext*, PressureObserverManager*); + ~PressureClientImpl() override; + + PressureClientImpl(const PressureClientImpl&) = delete; + PressureClientImpl& operator=(const PressureClientImpl&) = delete; + + // device::mojom::blink::PressureClient implementation. + void OnPressureUpdated(device::mojom::blink::PressureUpdatePtr) override; + + State state() const { return state_; } + void set_state(State state) { state_ = state; } + + void AddObserver(PressureObserver*); + void RemoveObserver(PressureObserver*); + const HeapHashSet<Member<PressureObserver>>& observers() const { + return observers_; + } + + mojo::PendingRemote<device::mojom::blink::PressureClient> + BindNewPipeAndPassRemote(); + + void Reset(); + + void Trace(Visitor*) const override; + + private: + // Verifies if the data should be delivered according to privacy status. + bool PassesPrivacyTest() const; + + WeakMember<PressureObserverManager> manager_; + + HeapMojoReceiver<device::mojom::blink::PressureClient, PressureClientImpl> + receiver_; + + HeapHashSet<Member<PressureObserver>> observers_; + + State state_ = State::kUninitialized; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COMPUTE_PRESSURE_PRESSURE_CLIENT_IMPL_H_
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc index d72f8db..dffbb7d5 100644 --- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/compute_pressure/pressure_observer.h" +#include "base/ranges/algorithm.h" #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -50,8 +51,8 @@ } // static -size_t PressureObserver::ToSourceIndex(V8PressureSource::Enum source) { - size_t index = static_cast<size_t>(source); +wtf_size_t PressureObserver::ToSourceIndex(V8PressureSource::Enum source) { + wtf_size_t index = static_cast<wtf_size_t>(source); DCHECK_LT(index, V8PressureSource::kEnumSize); return index; } @@ -105,11 +106,11 @@ // Reject all pending promises for `source`. RejectPendingResolvers(source.AsEnum(), DOMExceptionCode::kNotSupportedError, "Called unobserve method."); - switch (source.AsEnum()) { - case V8PressureSource::Enum::kCpu: - records_.clear(); - break; - } + records_.erase(base::ranges::remove_if(records_, + [source](const auto& record) { + return record->source() == source; + }), + records_.end()); } void PressureObserver::disconnect() {
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h index 80d8ea1..59ac5c81 100644 --- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h
@@ -52,7 +52,7 @@ PressureObserverOptions*, ExceptionState&); - static size_t ToSourceIndex(V8PressureSource::Enum); + static wtf_size_t ToSourceIndex(V8PressureSource::Enum); // PressureObserver IDL implementation. ScriptPromise observe(ScriptState*, V8PressureSource, ExceptionState&); @@ -67,12 +67,14 @@ // GarbageCollected implementation. void Trace(blink::Visitor*) const override; - // Called by PressureObserverManager. + // Called by PressureClientImpl. void OnUpdate(ExecutionContext*, V8PressureSource::Enum, V8PressureState::Enum, const Vector<V8PressureFactor>&, DOMHighResTimeStamp); + + // Called by PressureObserverManager. void OnBindingSucceeded(V8PressureSource::Enum); void OnBindingFailed(V8PressureSource::Enum, DOMExceptionCode); void OnConnectionError(); @@ -108,7 +110,7 @@ HeapHashSet<Member<ScriptPromiseResolver>> pending_resolvers_[V8PressureSource::kEnumSize]; - // The last valid record received from the observer manager. + // The last valid record received from PressureClientImpl. // Stored to avoid sending updates whenever the new record is the same. Member<PressureRecord> last_record_map_[V8PressureSource::kEnumSize];
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.cc b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.cc index 9427887..146225d4 100644 --- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.cc +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.cc
@@ -4,52 +4,26 @@ #include "third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.h" -#include "base/task/single_thread_task_runner.h" +#include "base/notreached.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" -#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_pressure_observer_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_pressure_source.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/core/page/focus_controller.h" -#include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/modules/document_picture_in_picture/picture_in_picture_controller_impl.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" -#include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/vector.h" -using device::mojom::blink::PressureFactor; -using device::mojom::blink::PressureState; +using device::mojom::blink::PressureSource; namespace blink { namespace { -constexpr auto ToSourceIndex = &blink::PressureObserver::ToSourceIndex; - -V8PressureFactor::Enum PressureFactorToV8PressureFactor(PressureFactor factor) { - switch (factor) { - case PressureFactor::kThermal: - return V8PressureFactor::Enum::kThermal; - case PressureFactor::kPowerSupply: - return V8PressureFactor::Enum::kPowerSupply; +PressureSource V8PressureSourceToPressureSource(V8PressureSource::Enum source) { + switch (source) { + case V8PressureSource::Enum::kCpu: + return PressureSource::kCpu; } - NOTREACHED(); -} - -V8PressureState::Enum PressureStateToV8PressureState(PressureState state) { - switch (state) { - case PressureState::kNominal: - return V8PressureState::Enum::kNominal; - case PressureState::kFair: - return V8PressureState::Enum::kFair; - case PressureState::kSerious: - return V8PressureState::Enum::kSerious; - case PressureState::kCritical: - return V8PressureState::Enum::kCritical; - } - NOTREACHED(); + NOTREACHED_NORETURN(); } } // namespace @@ -73,55 +47,50 @@ PressureObserverManager::PressureObserverManager(ExecutionContext* context) : ExecutionContextLifecycleStateObserver(context), Supplement<ExecutionContext>(*context), - pressure_manager_(context), - receiver_(this, context) { + pressure_manager_(context) { UpdateStateIfNeeded(); + for (const auto& source : PressureObserver::supportedSources()) { + source_to_client_.insert( + source.AsEnum(), + MakeGarbageCollected<PressureClientImpl>(context, this)); + } } PressureObserverManager::~PressureObserverManager() = default; void PressureObserverManager::AddObserver(V8PressureSource::Enum source, - blink::PressureObserver* observer) { - observers_[ToSourceIndex(source)].insert(observer); - - if (state_ == State::kUninitialized) { - DCHECK(!receiver_.is_bound()); - state_ = State::kInitializing; + PressureObserver* observer) { + PressureClientImpl* client = source_to_client_.at(source); + client->AddObserver(observer); + const PressureClientImpl::State state = client->state(); + if (state == PressureClientImpl::State::kUninitialized) { + client->set_state(PressureClientImpl::State::kInitializing); EnsureServiceConnection(); - // Not connected to the browser process yet. Make the binding. - scoped_refptr<base::SingleThreadTaskRunner> task_runner = - GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI); + // Not connected to the services side for `source` yet. Make the binding. pressure_manager_->AddClient( - receiver_.BindNewPipeAndPassRemote(std::move(task_runner)), + client->BindNewPipeAndPassRemote(), + V8PressureSourceToPressureSource(source), WTF::BindOnce(&PressureObserverManager::DidAddClient, WrapWeakPersistent(this), source)); - receiver_.set_disconnect_handler(WTF::BindOnce( - &PressureObserverManager::Reset, WrapWeakPersistent(this))); - } else if (state_ == State::kInitialized) { + } else if (state == PressureClientImpl::State::kInitialized) { observer->OnBindingSucceeded(source); } } -void PressureObserverManager::RemoveObserver( - V8PressureSource::Enum source, - blink::PressureObserver* observer) { - observers_[ToSourceIndex(source)].erase(observer); - - // Disconnected from the browser process only when PressureObserverManager is - // active and there is no other observers. - if (receiver_.is_bound() && observers_[ToSourceIndex(source)].empty()) { - // TODO(crbug.com/1342184): Consider other sources. - // For now, "cpu" is the only source, so disconnect directly. - Reset(); +void PressureObserverManager::RemoveObserver(V8PressureSource::Enum source, + PressureObserver* observer) { + PressureClientImpl* client = source_to_client_.at(source); + client->RemoveObserver(observer); + if (client->state() == PressureClientImpl::State::kUninitialized) { + ResetPressureManagerIfNeeded(); } } void PressureObserverManager::RemoveObserverFromAllSources( - blink::PressureObserver* observer) { - // TODO(crbug.com/1342184): Consider other sources. - // For now, "cpu" is the only source. - auto source = V8PressureSource::Enum::kCpu; - RemoveObserver(source, observer); + PressureObserver* observer) { + for (auto source : source_to_client_.Keys()) { + RemoveObserver(source, observer); + } } void PressureObserverManager::ContextDestroyed() { @@ -134,40 +103,9 @@ // when frozen or send a disconnect event. } -void PressureObserverManager::OnPressureUpdated( - device::mojom::blink::PressureUpdatePtr update) { - if (!PassesPrivacyTest()) - return; - - // New observers may be created and added. Take a snapshot so as - // to safely iterate. - // - // TODO(crbug.com/1342184): Consider other sources. - // For now, "cpu" is the only source. - HeapVector<Member<blink::PressureObserver>> observers( - observers_[ToSourceIndex(V8PressureSource::Enum::kCpu)]); - for (const auto& observer : observers) { - Vector<V8PressureFactor> v8_factors; - for (const auto& factor : update->factors) { - v8_factors.push_back( - V8PressureFactor(PressureFactorToV8PressureFactor(factor))); - } - // TODO(crbug.com/1342184): Consider other sources. - // For now, "cpu" is the only source. - observer->OnUpdate(GetExecutionContext(), V8PressureSource::Enum::kCpu, - PressureStateToV8PressureState(update->state), - std::move(v8_factors), - static_cast<DOMHighResTimeStamp>( - update->timestamp.ToJsTimeIgnoringNull())); - } -} - -void PressureObserverManager::Trace(blink::Visitor* visitor) const { - for (const auto& observer_set : observers_) { - visitor->Trace(observer_set); - } +void PressureObserverManager::Trace(Visitor* visitor) const { visitor->Trace(pressure_manager_); - visitor->Trace(receiver_); + visitor->Trace(source_to_client_); ExecutionContextLifecycleStateObserver::Trace(visitor); Supplement<ExecutionContext>::Trace(visitor); } @@ -188,71 +126,10 @@ WrapWeakPersistent(this))); } -// https://wicg.github.io/compute-pressure/#dfn-passes-privacy-test -bool PressureObserverManager::PassesPrivacyTest() const { - const ExecutionContext* context = GetExecutionContext(); - - // TODO(crbug.com/1425053): Check for active needed worker. - if (context->IsDedicatedWorkerGlobalScope() || - context->IsSharedWorkerGlobalScope()) { - return true; - } - - if (!DomWindow()) { - return false; - } - - LocalFrame* this_frame = DomWindow()->GetFrame(); - // 2. If associated document is not fully active, return false. - if (GetSupplementable()->IsContextDestroyed() || !this_frame) { - return false; - } - - // 4. If associated document is same-domain with initiators of active - // Picture-in-Picture sessions, return true. - // - // TODO(crbug.com/1396177): A frame should be able to access to - // PressureRecord if it is same-domain with initiators of active - // Picture-in-Picture sessions. However, it is hard to implement now. In - // current implementation, only the frame that triggers Picture-in-Picture - // can access to PressureRecord. - auto& pip_controller = - PictureInPictureControllerImpl::From(*(this_frame->GetDocument())); - if (pip_controller.PictureInPictureElement()) { - return true; - } - - // 5. If browsing context is capturing, return true. - if (this_frame->IsCapturingMedia()) { - return true; - } - - // 7. If top-level browsing context does not have system focus, return false. - DCHECK(this_frame->GetPage()); - const auto& focus_controller = this_frame->GetPage()->GetFocusController(); - if (!focus_controller.IsFocused()) { - return false; - } - - // 8. Let focused document be the currently focused area's node document. - const LocalFrame* focused_frame = focus_controller.FocusedFrame(); - if (!focused_frame) { - return false; - } - - // 9. If origin is same origin-domain with focused document, return true. - // 10. Otherwise, return false. - const SecurityOrigin* focused_frame_origin = - focused_frame->GetSecurityContext()->GetSecurityOrigin(); - const SecurityOrigin* this_origin = - this_frame->GetSecurityContext()->GetSecurityOrigin(); - return focused_frame_origin->CanAccess(this_origin); -} - void PressureObserverManager::OnServiceConnectionError() { - for (const auto& observer_set : observers_) { + for (PressureClientImpl* client : source_to_client_.Values()) { // Take a snapshot so as to safely iterate. - HeapVector<Member<blink::PressureObserver>> observers(observer_set); + HeapVector<Member<PressureObserver>> observers(client->observers()); for (const auto& observer : observers) { observer->OnConnectionError(); } @@ -260,37 +137,46 @@ Reset(); } -void PressureObserverManager::Reset() { - state_ = State::kUninitialized; - receiver_.reset(); - pressure_manager_.reset(); - for (auto& observer_set : observers_) { - observer_set.clear(); +void PressureObserverManager::ResetPressureManagerIfNeeded() { + if (base::ranges::all_of( + source_to_client_.Values(), [](const PressureClientImpl* client) { + return client->state() == PressureClientImpl::State::kUninitialized; + })) { + pressure_manager_.reset(); } } +void PressureObserverManager::Reset() { + for (PressureClientImpl* client : source_to_client_.Values()) { + client->Reset(); + } + pressure_manager_.reset(); +} + void PressureObserverManager::DidAddClient( V8PressureSource::Enum source, device::mojom::blink::PressureStatus status) { - DCHECK_EQ(state_, State::kInitializing); - DCHECK(receiver_.is_bound()); - DCHECK(pressure_manager_.is_bound()); + PressureClientImpl* client = source_to_client_.at(source); + // PressureClientImpl may be reset by PressureObserver's + // unobserve()/disconnect() before this function is called. + if (client->state() != PressureClientImpl::State::kInitializing) { + return; + } + CHECK(pressure_manager_.is_bound()); // Take a snapshot so as to safely iterate. - HeapVector<Member<blink::PressureObserver>> observers( - observers_[ToSourceIndex(source)]); + HeapVector<Member<PressureObserver>> observers(client->observers()); switch (status) { case device::mojom::blink::PressureStatus::kOk: { - state_ = State::kInitialized; + client->set_state(PressureClientImpl::State::kInitialized); for (const auto& observer : observers) { observer->OnBindingSucceeded(source); } break; } case device::mojom::blink::PressureStatus::kNotSupported: { - // TODO(crbug.com/1342184): Consider other sources. - // For now, "cpu" is the only source. - Reset(); + client->Reset(); + ResetPressureManagerIfNeeded(); for (const auto& observer : observers) { observer->OnBindingFailed(source, DOMExceptionCode::kNotSupportedError); }
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.h b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.h index 1dab92d2..20480196 100644 --- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.h +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_manager.h
@@ -10,11 +10,11 @@ #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_pressure_source.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h" +#include "third_party/blink/renderer/modules/compute_pressure/pressure_client_impl.h" #include "third_party/blink/renderer/modules/compute_pressure/pressure_observer.h" #include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/supplementable.h" @@ -22,15 +22,12 @@ class ExecutionContext; -// This class implements the "device::mojom::blink::PressureClient" -// interface to receive "device::mojom::blink::PressureUpdate" from -// "device::PressureManagerImpl" and broadcasts the information to active -// PressureObservers. +// This class keeps track of PressureClientImpls and the connection to the +// PressureManager remote. class MODULES_EXPORT PressureObserverManager final : public GarbageCollected<PressureObserverManager>, public ExecutionContextLifecycleStateObserver, - public Supplement<ExecutionContext>, - public device::mojom::blink::PressureClient { + public Supplement<ExecutionContext> { public: static const char kSupplementName[]; @@ -42,55 +39,37 @@ PressureObserverManager(const PressureObserverManager&) = delete; PressureObserverManager& operator=(const PressureObserverManager&) = delete; - void AddObserver(V8PressureSource::Enum, blink::PressureObserver*); - void RemoveObserver(V8PressureSource::Enum, blink::PressureObserver*); - void RemoveObserverFromAllSources(blink::PressureObserver*); + void AddObserver(V8PressureSource::Enum, PressureObserver*); + void RemoveObserver(V8PressureSource::Enum, PressureObserver*); + void RemoveObserverFromAllSources(PressureObserver*); // ContextLifecycleStateimplementation. void ContextDestroyed() override; void ContextLifecycleStateChanged(mojom::blink::FrameLifecycleState) override; - // device::mojom::blink::PressureClient implementation. - void OnPressureUpdated(device::mojom::blink::PressureUpdatePtr) override; - // GarbageCollected implementation. void Trace(Visitor*) const override; private: - // kUninitialized: receiver_ is not bound and - // pressure_manager_->AddClient() must be called. - // kInitializing: pressure_manager_->AddClient() has been called, - // but DidAddClient() has not been called yet. - // kInitialized: DidAddClient() was invoked and succeeded. - enum class State { kUninitialized, kInitializing, kInitialized }; - void EnsureServiceConnection(); - // Verifies if the data should be delivered according to privacy status. - bool PassesPrivacyTest() const; - // Called when `pressure_manager_` is disconnected. void OnServiceConnectionError(); - // Called when `receiver_` is disconnected. + // Called to reset `pressure_manager_` when all PressureClientImpl are reset. + void ResetPressureManagerIfNeeded(); + + // Called to reset for all PressureSources. void Reset(); void DidAddClient(V8PressureSource::Enum, device::mojom::blink::PressureStatus); - constexpr static size_t kPressureSourceSize = V8PressureSource::kEnumSize; - - // Connection to the browser-side implementation. + // Connection to the services side implementation. HeapMojoRemote<device::mojom::blink::PressureManager> pressure_manager_; - // Routes PressureObserver mojo messages to this instance. - HeapMojoReceiver<device::mojom::blink::PressureClient, - PressureObserverManager> - receiver_; - - State state_ = State::kUninitialized; - - HeapHashSet<Member<blink::PressureObserver>> observers_[kPressureSourceSize]; + HeapHashMap<V8PressureSource::Enum, Member<PressureClientImpl>> + source_to_client_; }; } // namespace blink
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 e6c0d70..f4fa6835 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
@@ -163,6 +163,9 @@ bool PaintArtifactCompositor::NeedsCompositedScrolling( const TransformPaintPropertyNode& scroll_translation) const { + // This function needs scroll_translation_nodes_ which is only available + // during full update. + DCHECK(needs_update_); DCHECK(scroll_translation.ScrollNode()); if (scroll_translation.HasDirectCompositingReasons()) { return true; @@ -945,10 +948,10 @@ host->property_trees()->set_needs_rebuild(false); host->property_trees()->ResetCachedData(); previous_update_for_testing_ = PreviousUpdateType::kFull; - needs_update_ = false; - scroll_translation_nodes_.clear(); UpdateDebugInfo(); + scroll_translation_nodes_.clear(); + needs_update_ = false; g_s_property_tree_sequence_number++; @@ -1108,105 +1111,151 @@ } } -static void UpdateLayerDebugInfo( - cc::Layer& layer, - const PendingLayer& pending_layer, - CompositingReasons compositing_reasons, - RasterInvalidationTracking* raster_invalidation_tracking) { - cc::LayerDebugInfo& debug_info = layer.EnsureDebugInfo(); - debug_info.name = pending_layer.DebugName().Utf8(); - debug_info.compositing_reasons = - CompositingReason::Descriptions(compositing_reasons); - debug_info.compositing_reason_ids = - CompositingReason::ShortNames(compositing_reasons); - debug_info.owner_node_id = pending_layer.OwnerNodeId(); - - if (RasterInvalidationTracking::IsTracingRasterInvalidations() && - raster_invalidation_tracking) { - raster_invalidation_tracking->AddToLayerDebugInfo(debug_info); - raster_invalidation_tracking->ClearInvalidations(); - } -} - void PaintArtifactCompositor::UpdateDebugInfo() const { if (!layer_debug_info_enabled_) return; - const PendingLayer* previous_pending_layer = nullptr; + PropertyTreeState previous_layer_state = PropertyTreeState::Root(); for (const auto& pending_layer : pending_layers_) { cc::Layer& layer = pending_layer.CcLayer(); RasterInvalidationTracking* tracking = nullptr; - if (auto* client = pending_layer.GetContentLayerClient()) + if (auto* client = pending_layer.GetContentLayerClient()) { tracking = client->GetRasterInvalidator().GetTracking(); - UpdateLayerDebugInfo( - layer, pending_layer, - GetCompositingReasons(pending_layer, previous_pending_layer), tracking); - previous_pending_layer = &pending_layer; + } + cc::LayerDebugInfo& debug_info = layer.EnsureDebugInfo(); + debug_info.name = pending_layer.DebugName().Utf8(); + // GetCompositingReasons calls NeedsCompositedScrolling which is only + // available during full update. In repaint-only update, the original + // compositing reasons in debug_info will be kept. + if (needs_update_) { + auto compositing_reasons = + GetCompositingReasons(pending_layer, previous_layer_state); + debug_info.compositing_reasons = + CompositingReason::Descriptions(compositing_reasons); + debug_info.compositing_reason_ids = + CompositingReason::ShortNames(compositing_reasons); + } + debug_info.owner_node_id = pending_layer.OwnerNodeId(); + + if (RasterInvalidationTracking::IsTracingRasterInvalidations() && + tracking) { + tracking->AddToLayerDebugInfo(debug_info); + tracking->ClearInvalidations(); + } + previous_layer_state = pending_layer.GetPropertyTreeState(); } } +// The returned compositing reasons are informative for tracing/debugging. +// Some are based on heuristics so are not fully accurate. CompositingReasons PaintArtifactCompositor::GetCompositingReasons( const PendingLayer& layer, - const PendingLayer* previous_layer) const { + const PropertyTreeState& previous_layer_state) const { DCHECK(layer_debug_info_enabled_); + DCHECK(needs_update_); - if (layer.ChunkRequiresOwnLayer()) { - if (layer.GetCompositingType() == PendingLayer::kScrollHitTestLayer) - return CompositingReason::kOverflowScrolling; + if (layer.GetCompositingType() == PendingLayer::kScrollHitTestLayer) { + return CompositingReason::kOverflowScrolling; + } + if (layer.Chunks().size() == 1 && layer.FirstPaintChunk().size() == 1) { switch (layer.FirstDisplayItem().GetType()) { + case DisplayItem::kCaret: + return CompositingReason::kCaret; + case DisplayItem::kScrollbarHorizontal: + case DisplayItem::kScrollbarVertical: + return CompositingReason::kScrollbar; case DisplayItem::kForeignLayerCanvas: return CompositingReason::kCanvas; + case DisplayItem::kForeignLayerDevToolsOverlay: + return CompositingReason::kDevToolsOverlay; case DisplayItem::kForeignLayerPlugin: return CompositingReason::kPlugin; case DisplayItem::kForeignLayerVideo: return CompositingReason::kVideo; - case DisplayItem::kScrollbarHorizontal: - return CompositingReason::kLayerForHorizontalScrollbar; - case DisplayItem::kScrollbarVertical: - return CompositingReason::kLayerForVerticalScrollbar; + case DisplayItem::kForeignLayerRemoteFrame: + return CompositingReason::kIFrame; + case DisplayItem::kForeignLayerLinkHighlight: + return CompositingReason::kLinkHighlight; + case DisplayItem::kForeignLayerViewportScroll: + return CompositingReason::kViewport; + case DisplayItem::kForeignLayerViewportScrollbar: + return CompositingReason::kScrollbar; + case DisplayItem::kForeignLayerViewTransitionContent: + return CompositingReason::kViewTransitionContent; default: - return CompositingReason::kLayerForOther; + // Will determine compositing reasons based on paint properties. + break; } } CompositingReasons reasons = CompositingReason::kNone; - if (layer.GetPropertyTreeState().Transform().IsBackfaceHidden() && - (!previous_layer || !previous_layer->GetPropertyTreeState() - .Transform() - .IsBackfaceHidden())) { + const auto& transform = layer.GetPropertyTreeState().Transform(); + if (transform.IsBackfaceHidden() && + !previous_layer_state.Transform().IsBackfaceHidden()) { reasons = CompositingReason::kBackfaceVisibilityHidden; - } else if (layer.GetCompositingType() == PendingLayer::kOverlap) { - return CompositingReason::kOverlap; + } + if (layer.GetCompositingType() == PendingLayer::kOverlap) { + return reasons == CompositingReason::kNone ? CompositingReason::kOverlap + : reasons; } - if (!previous_layer || - &layer.GetPropertyTreeState().Transform() != - &previous_layer->GetPropertyTreeState().Transform()) { - reasons |= layer.GetPropertyTreeState() - .Transform() - .DirectCompositingReasonsForDebugging(); - if (!layer.GetPropertyTreeState() - .Transform() - .BackfaceVisibilitySameAsParent()) - reasons |= CompositingReason::kBackfaceVisibilityHidden; - } - - if (!previous_layer || &layer.GetPropertyTreeState().Effect() != - &previous_layer->GetPropertyTreeState().Effect()) { - const auto& effect = layer.GetPropertyTreeState().Effect(); - if (effect.HasDirectCompositingReasons()) - reasons |= effect.DirectCompositingReasonsForDebugging(); - if (reasons == CompositingReason::kNone && - layer.GetCompositingType() == PendingLayer::kOther) { - if (effect.Opacity() != 1.0f) - reasons |= CompositingReason::kOpacityWithCompositedDescendants; - if (!effect.Filter().IsEmpty()) - reasons |= CompositingReason::kFilterWithCompositedDescendants; - if (effect.BlendMode() == SkBlendMode::kDstIn) - reasons |= CompositingReason::kMaskWithCompositedDescendants; - else if (effect.BlendMode() != SkBlendMode::kSrcOver) - reasons |= CompositingReason::kBlendingWithCompositedDescendants; + auto composited_ancestor = [this](const TransformPaintPropertyNode& transform) + -> const TransformPaintPropertyNode* { + const auto* ancestor = transform.NearestDirectlyCompositedAncestor(); + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + const auto& scroll_translation = transform.NearestScrollTranslationNode(); + if (NeedsCompositedScrolling(scroll_translation) && + (!ancestor || ancestor->IsAncestorOf(scroll_translation))) { + return &scroll_translation; + } } + return ancestor; + }; + + auto transform_compositing_reasons = + [composited_ancestor]( + const TransformPaintPropertyNode& transform, + const TransformPaintPropertyNode& previous) -> CompositingReasons { + CompositingReasons reasons = CompositingReason::kNone; + const auto* ancestor = composited_ancestor(transform); + if (ancestor && ancestor != composited_ancestor(previous)) { + reasons = ancestor->DirectCompositingReasonsForDebugging(); + if (ancestor->ScrollNode()) { + reasons |= CompositingReason::kOverflowScrolling; + } + } + return reasons; + }; + + auto clip_compositing_reasons = + [transform_compositing_reasons]( + const ClipPaintPropertyNode& clip, + const ClipPaintPropertyNode& previous) -> CompositingReasons { + return transform_compositing_reasons( + clip.LocalTransformSpace().Unalias(), + previous.LocalTransformSpace().Unalias()); + }; + + reasons |= transform_compositing_reasons(transform, + previous_layer_state.Transform()); + const auto& effect = layer.GetPropertyTreeState().Effect(); + if (&effect != &previous_layer_state.Effect()) { + reasons |= effect.DirectCompositingReasonsForDebugging(); + if (reasons == CompositingReason::kNone) { + reasons = transform_compositing_reasons( + effect.LocalTransformSpace().Unalias(), + previous_layer_state.Effect().LocalTransformSpace().Unalias()); + if (reasons == CompositingReason::kNone && effect.OutputClip() && + previous_layer_state.Effect().OutputClip()) { + reasons = clip_compositing_reasons( + effect.OutputClip()->Unalias(), + previous_layer_state.Effect().OutputClip()->Unalias()); + } + } + } + if (reasons == CompositingReason::kNone) { + reasons = clip_compositing_reasons(layer.GetPropertyTreeState().Clip(), + previous_layer_state.Clip()); } return reasons;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h index 6164164..09ffccb3 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
@@ -330,7 +330,7 @@ CompositingReasons GetCompositingReasons( const PendingLayer& layer, - const PendingLayer* previous_layer) const; + const PropertyTreeState& previous_layer_state) const; void UpdateDebugInfo() const;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc index 430bf4a8..c2abae2 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -1897,8 +1897,8 @@ } TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleMask) { - auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto masked = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); @@ -1931,14 +1931,14 @@ } TEST_P(PaintArtifactCompositorTest, CompositedMaskOneChild) { - auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto masked = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); masking_state.blend_mode = SkBlendMode::kDstIn; masking_state.direct_compositing_reasons = - CompositingReason::kMaskWithCompositedDescendants; + CompositingReason::kWillChangeOpacity; auto masking = EffectPaintPropertyNode::Create(*masked, std::move(masking_state)); @@ -1975,8 +1975,8 @@ } TEST_P(PaintArtifactCompositorTest, NonCompositedMaskClearsOpaqueness) { - auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto masked = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); @@ -2003,8 +2003,8 @@ } TEST_P(PaintArtifactCompositorTest, CompositedMaskTwoChildren) { - auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto masked = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); @@ -2012,8 +2012,8 @@ auto masking = EffectPaintPropertyNode::Create(*masked, std::move(masking_state)); - auto child_of_masked = CreateOpacityEffect( - *masking, 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto child_of_masked = + CreateOpacityEffect(*masking, 1.0, CompositingReason::kWillChangeOpacity); TestPaintArtifact artifact; artifact.Chunk(t0(), c0(), *masked) @@ -2042,8 +2042,8 @@ } TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleExoticBlendMode) { - auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto masked = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); @@ -2069,8 +2069,8 @@ } TEST_P(PaintArtifactCompositorTest, ForcedCompositedExoticBlendMode) { - auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto masked = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); @@ -2104,8 +2104,8 @@ TEST_P(PaintArtifactCompositorTest, CompositedExoticBlendModeOnTwoOpacityAnimationLayers) { - auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto masked = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); auto masked_child1 = CreateOpacityEffect( *masked, 1.0, CompositingReason::kActiveOpacityAnimation); auto masked_child2 = CreateOpacityEffect( @@ -2144,8 +2144,8 @@ TEST_P(PaintArtifactCompositorTest, CompositedExoticBlendModeOnTwo3DTransformLayers) { - auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto masked = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); auto transform1 = CreateTransform(t0(), gfx::Transform(), gfx::Point3F(), CompositingReason::k3DTransform); auto transform2 = CreateTransform(t0(), gfx::Transform(), gfx::Point3F(), @@ -2183,8 +2183,8 @@ } TEST_P(PaintArtifactCompositorTest, DecompositeExoticBlendModeWithoutBackdrop) { - auto parent_effect = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto parent_effect = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); EffectPaintPropertyNode::State blend_state1; blend_state1.local_transform_space = &t0(); blend_state1.blend_mode = SkBlendMode::kScreen; @@ -2214,8 +2214,8 @@ TEST_P(PaintArtifactCompositorTest, DecompositeExoticBlendModeWithNonDrawingLayer) { - auto parent_effect = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); + auto parent_effect = + CreateOpacityEffect(e0(), 1.0, CompositingReason::kWillChangeOpacity); EffectPaintPropertyNode::State blend_state1; blend_state1.local_transform_space = &t0(); blend_state1.blend_mode = SkBlendMode::kScreen;
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc index 6175bbda..71cea4cc 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -11,149 +11,133 @@ namespace { -struct CompositingReasonStringMap { +#define V(name) #name, +constexpr const char* kShortNames[] = {FOR_EACH_COMPOSITING_REASON(V)}; +#undef V + +struct ReasonAndDescription { CompositingReasons reason; - const char* short_name; const char* description; }; - -constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = { - {CompositingReason::k3DTransform, "transform3D", "Has a 3d transform"}, - {CompositingReason::k3DScale, "scale3D", "Has a 3d scale"}, - {CompositingReason::k3DRotate, "rotate3D", "Has a 3d rotate"}, - {CompositingReason::k3DTranslate, "translate3D", "Has a 3d translate"}, - {CompositingReason::kTrivial3DTransform, "trivialTransform3D", - "Has a trivial 3d transform"}, - {CompositingReason::kVideo, "video", "Is an accelerated video"}, - {CompositingReason::kCanvas, "canvas", +constexpr ReasonAndDescription kReasonDescriptionMap[] = { + {CompositingReason::k3DTransform, "Has a 3d transform."}, + {CompositingReason::k3DScale, "Has a 3d scale."}, + {CompositingReason::k3DRotate, "Has a 3d rotate."}, + {CompositingReason::k3DTranslate, "Has a 3d translate."}, + {CompositingReason::kTrivial3DTransform, "Has a trivial 3d transform."}, + {CompositingReason::kIFrame, "Is an accelerated iFrame."}, + {CompositingReason::kActiveTransformAnimation, + "Has an active accelerated transform animation or transition."}, + {CompositingReason::kActiveScaleAnimation, + "Has an active accelerated scale animation or transition."}, + {CompositingReason::kActiveRotateAnimation, + "Has an active accelerated rotate animation or transition."}, + {CompositingReason::kActiveTranslateAnimation, + "Has an active accelerated translate animation or transition."}, + {CompositingReason::kActiveOpacityAnimation, + "Has an active accelerated opacity animation or transition."}, + {CompositingReason::kActiveFilterAnimation, + "Has an active accelerated filter animation or transition."}, + {CompositingReason::kActiveBackdropFilterAnimation, + "Has an active accelerated backdrop filter animation or transition."}, + {CompositingReason::kAffectedByOuterViewportBoundsDelta, + "Is fixed position affected by outer viewport bounds delta."}, + {CompositingReason::kFixedPosition, + "Is fixed position in a scrollable view."}, + {CompositingReason::kUndoOverscroll, + "Is fixed position that should undo overscroll of the viewport."}, + {CompositingReason::kStickyPosition, "Is sticky position."}, + {CompositingReason::kAnchorScroll, + "Is an element with anchor-scroll css property."}, + {CompositingReason::kBackdropFilter, "Has a backdrop filter."}, + {CompositingReason::kBackdropFilterMask, "Is a mask for backdrop filter."}, + {CompositingReason::kRootScroller, "Is the document.rootScroller."}, + {CompositingReason::kViewport, "Is for the visual viewport."}, + {CompositingReason::kWillChangeTransform, + "Has a will-change: transform compositing hint."}, + {CompositingReason::kWillChangeScale, + "Has a will-change: scale compositing hint."}, + {CompositingReason::kWillChangeRotate, + "Has a will-change: rotate compositing hint."}, + {CompositingReason::kWillChangeTranslate, + "Has a will-change: translate compositing hint."}, + {CompositingReason::kWillChangeOpacity, + "Has a will-change: opacity compositing hint."}, + {CompositingReason::kWillChangeFilter, + "Has a will-change: filter compositing hint."}, + {CompositingReason::kWillChangeBackdropFilter, + "Has a will-change: backdrop-filter compositing hint."}, + {CompositingReason::kWillChangeOther, + "Has a will-change compositing hint other than transform, opacity, filter" + " and backdrop-filter."}, + {CompositingReason::kBackfaceInvisibility3DAncestor, + "Ancestor in same 3D rendering context has a hidden backface."}, + {CompositingReason::kTransform3DSceneLeaf, + "Leaf of a 3D scene, for flattening its descendants into that scene."}, + {CompositingReason::kPerspectiveWith3DDescendants, + "Has a perspective transform that needs to be known by compositor because " + "of 3d descendants."}, + {CompositingReason::kPreserve3DWith3DDescendants, + "Has a preserves-3d property that needs to be known by compositor because " + "of 3d descendants."}, + {CompositingReason::kViewTransitionElement, + "This element is shared during view transition."}, + {CompositingReason::kViewTransitionPseudoElement, + "This element is a part of a pseudo element tree representing the view " + "transition."}, + {CompositingReason::kOverflowScrolling, + "Is a scrollable overflow element using accelerated scrolling."}, + {CompositingReason::kOverlap, "Overlaps other composited content."}, + {CompositingReason::kBackfaceVisibilityHidden, + "Has backface-visibility: hidden."}, + {CompositingReason::kCaret, "Is a caret in an editor."}, + {CompositingReason::kVideo, "Is an accelerated video."}, + {CompositingReason::kCanvas, "Is an accelerated canvas, or is a display list backed canvas that was " "promoted to a layer based on a performance heuristic."}, - {CompositingReason::kPlugin, "plugin", "Is an accelerated plugin"}, - {CompositingReason::kIFrame, "iFrame", "Is an accelerated iFrame"}, - {CompositingReason::kBackfaceVisibilityHidden, "backfaceVisibilityHidden", - "Has backface-visibility: hidden"}, - {CompositingReason::kActiveTransformAnimation, "activeTransformAnimation", - "Has an active accelerated transform animation or transition"}, - {CompositingReason::kActiveScaleAnimation, "activeScaleAnimation", - "Has an active accelerated scale animation or transition"}, - {CompositingReason::kActiveRotateAnimation, "activeRotateAnimation", - "Has an active accelerated rotate animation or transition"}, - {CompositingReason::kActiveTranslateAnimation, "activeTranslateAnimation", - "Has an active accelerated translate animation or transition"}, - {CompositingReason::kActiveOpacityAnimation, "activeOpacityAnimation", - "Has an active accelerated opacity animation or transition"}, - {CompositingReason::kActiveFilterAnimation, "activeFilterAnimation", - "Has an active accelerated filter animation or transition"}, - {CompositingReason::kActiveBackdropFilterAnimation, - "activeBackdropFilterAnimation", - "Has an active accelerated backdrop filter animation or transition"}, - {CompositingReason::kFixedPosition, "fixedPosition", "Is fixed position"}, - {CompositingReason::kStickyPosition, "stickyPosition", - "Is sticky position"}, - {CompositingReason::kOverflowScrolling, "overflowScrolling", - "Is a scrollable overflow element"}, - {CompositingReason::kWillChangeTransform, "willChangeTransform", - "Has a will-change: transform compositing hint"}, - {CompositingReason::kWillChangeScale, "willChangeScale", - "Has a will-change: scale compositing hint"}, - {CompositingReason::kWillChangeRotate, "willChangeRotate", - "Has a will-change: rotate compositing hint"}, - {CompositingReason::kWillChangeTranslate, "willChangeTranslate", - "Has a will-change: translate compositing hint"}, - {CompositingReason::kWillChangeOpacity, "willChangeOpacity", - "Has a will-change: opacity compositing hint"}, - {CompositingReason::kWillChangeFilter, "willChangeFilter", - "Has a will-change: filter compositing hint"}, - {CompositingReason::kWillChangeBackdropFilter, "willChangeBackdropFilter", - "Has a will-change: backdrop-filter compositing hint"}, - {CompositingReason::kWillChangeOther, "willChangeOther", - "Has a will-change compositing hint other than transform and opacity"}, - {CompositingReason::kBackdropFilter, "backdropFilter", - "Has a backdrop filter"}, - {CompositingReason::kBackdropFilterMask, "backdropFilterMask", - "Is a mask for backdrop filter"}, - {CompositingReason::kRootScroller, "rootScroller", - "Is the document.rootScroller"}, - {CompositingReason::kOverlap, "overlap", - "Overlaps other composited content"}, - {CompositingReason::kOpacityWithCompositedDescendants, - "opacityWithCompositedDescendants", - "Has opacity that needs to be applied by compositor because of composited " - "descendants"}, - {CompositingReason::kMaskWithCompositedDescendants, - "maskWithCompositedDescendants", - "Has a mask that needs to be known by compositor because of composited " - "descendants"}, - {CompositingReason::kFilterWithCompositedDescendants, - "filterWithCompositedDescendants", - "Has a filter effect that needs to be known by compositor because of " - "composited descendants"}, - {CompositingReason::kBlendingWithCompositedDescendants, - "blendingWithCompositedDescendants", - "Has a blending effect that needs to be known by compositor because of " - "composited descendants"}, - {CompositingReason::kPerspectiveWith3DDescendants, - "perspectiveWith3DDescendants", - "Has a perspective transform that needs to be known by compositor because " - "of 3d descendants"}, - {CompositingReason::kPreserve3DWith3DDescendants, - "preserve3DWith3DDescendants", - "Has a preserves-3d property that needs to be known by compositor because " - "of 3d descendants"}, - {CompositingReason::kRoot, "root", "Is the root layer"}, - {CompositingReason::kLayerForHorizontalScrollbar, - "layerForHorizontalScrollbar", - "Secondary layer, the horizontal scrollbar layer"}, - {CompositingReason::kLayerForVerticalScrollbar, "layerForVerticalScrollbar", - "Secondary layer, the vertical scrollbar layer"}, - {CompositingReason::kUndoOverscroll, "UndoOverscroll", - "The layer is fixed to viewport and doesn't move with overscroll"}, - {CompositingReason::kLayerForOther, "layerForOther", - "Layer for link highlight, frame overlay, etc."}, - {CompositingReason::kBackfaceInvisibility3DAncestor, - "BackfaceInvisibility3DAncestor", - "Ancestor in same 3D rendering context has a hidden backface"}, - {CompositingReason::kTransform3DSceneLeaf, "Transform3DSceneLeaf", - "Leaf of a 3D scene, for flattening its descendants into that scene"}, - {CompositingReason::kViewTransitionElement, "ViewTransitionElement", - "This element is shared during view transition"}, - {CompositingReason::kViewTransitionPseudoElement, - "ViewTransitionContentElement", - "This element is a part of a pseudo element tree representing the shared " - "element transition"}, + {CompositingReason::kPlugin, "Is an accelerated plugin."}, + {CompositingReason::kScrollbar, "Is an accelerated scrollbar."}, + {CompositingReason::kLinkHighlight, "Is a tap highlight on a link."}, + {CompositingReason::kDevToolsOverlay, "Is DevTools overlay."}, + {CompositingReason::kViewTransitionContent, + "The layer containing the contents of a view transition element."}, }; } // anonymous namespace std::vector<const char*> CompositingReason::ShortNames( CompositingReasons reasons) { -#define V(name) \ - static_assert( \ - CompositingReason::k##name == \ - kCompositingReasonsStringMap[CompositingReason::kE##name].reason, \ - "kCompositingReasonsStringMap needs update for " \ - "CompositingReason::k" #name); \ - FOR_EACH_COMPOSITING_REASON(V) -#undef V - std::vector<const char*> result; - if (reasons == kNone) + if (reasons == kNone) { return result; - for (auto& map : kCompositingReasonsStringMap) { - if (reasons & map.reason) - result.push_back(map.short_name); + } + for (size_t i = 0; i < std::size(kShortNames); i++) { + if (reasons & (UINT64_C(1) << i)) { + result.push_back(kShortNames[i]); + } } return result; } std::vector<const char*> CompositingReason::Descriptions( CompositingReasons reasons) { +#define V(name) \ + static_assert( \ + CompositingReason::k##name == \ + kReasonDescriptionMap[CompositingReason::kE##name].reason, \ + "kReasonDescriptionMap needs update for CompositingReason::k" #name); + + FOR_EACH_COMPOSITING_REASON(V) +#undef V + std::vector<const char*> result; - if (reasons == kNone) + if (reasons == kNone) { return result; - for (auto& map : kCompositingReasonsStringMap) { - if (reasons & map.reason) + } + for (auto& map : kReasonDescriptionMap) { + if (reasons & map.reason) { result.push_back(map.description); + } } return result; }
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/third_party/blink/renderer/platform/graphics/compositing_reasons.h index c21c1fa..befeb85 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.h +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -15,79 +15,76 @@ using CompositingReasons = uint64_t; -#define FOR_EACH_COMPOSITING_REASON(V) \ - /* Intrinsic reasons that can be known right away by the layer. */ \ - V(3DTransform) \ - V(3DScale) \ - V(3DRotate) \ - V(3DTranslate) \ - V(Trivial3DTransform) \ - V(Video) \ - V(Canvas) \ - V(Plugin) \ - V(IFrame) \ - V(ViewTransitionPseudoElement) \ - V(BackfaceVisibilityHidden) \ - V(ActiveTransformAnimation) \ - V(ActiveScaleAnimation) \ - V(ActiveRotateAnimation) \ - V(ActiveTranslateAnimation) \ - V(ActiveOpacityAnimation) \ - V(ActiveFilterAnimation) \ - V(ActiveBackdropFilterAnimation) \ - V(AffectedByOuterViewportBoundsDelta) \ - V(FixedPosition) \ - V(UndoOverscroll) \ - V(StickyPosition) \ - V(AnchorScroll) \ - V(OverflowScrolling) \ - V(WillChangeTransform) \ - V(WillChangeScale) \ - V(WillChangeRotate) \ - V(WillChangeTranslate) \ - V(WillChangeOpacity) \ - V(WillChangeFilter) \ - V(WillChangeBackdropFilter) \ - \ - /* Reasons that depend on ancestor properties */ \ - V(BackfaceInvisibility3DAncestor) \ - /* TODO(crbug.com/1256990): Transform3DSceneLeaf today depends only on the \ - element and its properties, but in the future it could be optimized \ - to consider descendants and moved to the subtree group below. */ \ - V(Transform3DSceneLeaf) \ - /* This flag is needed only when none of the explicit kWillChange* reasons \ - are set. */ \ - V(WillChangeOther) \ - V(BackdropFilter) \ - V(BackdropFilterMask) \ - V(RootScroller) \ - V(Viewport) \ - \ - /* This is based on overlapping relationship among pending layers, \ - determined after paint. See PaintArtifactCompositor. */ \ - V(Overlap) \ - \ - /* Subtree reasons that require knowing what the status of your subtree is \ - before knowing the answer. */ \ - V(OpacityWithCompositedDescendants) \ - V(MaskWithCompositedDescendants) \ - V(FilterWithCompositedDescendants) \ - V(BlendingWithCompositedDescendants) \ - V(PerspectiveWith3DDescendants) \ - V(Preserve3DWith3DDescendants) \ - \ - /* The root layer is a special case. It may be forced to be a layer, but it \ - also needs to be a layer if anything else in the subtree is composited. */ \ - V(Root) \ - \ - V(LayerForHorizontalScrollbar) \ - V(LayerForVerticalScrollbar) \ - /* Link highlight, frame overlay, etc. */ \ - V(LayerForOther) \ - \ - /* ViewTransition element. \ - See third_party/blink/renderer/core/view_transition/README.md. */ \ - V(ViewTransitionElement) +#define FOR_EACH_COMPOSITING_REASON(V) \ + /* Intrinsic reasons that can be known right away by the layer. */ \ + V(3DTransform) \ + V(3DScale) \ + V(3DRotate) \ + V(3DTranslate) \ + V(Trivial3DTransform) \ + V(IFrame) \ + V(ActiveTransformAnimation) \ + V(ActiveScaleAnimation) \ + V(ActiveRotateAnimation) \ + V(ActiveTranslateAnimation) \ + V(ActiveOpacityAnimation) \ + V(ActiveFilterAnimation) \ + V(ActiveBackdropFilterAnimation) \ + V(AffectedByOuterViewportBoundsDelta) \ + V(FixedPosition) \ + V(UndoOverscroll) \ + V(StickyPosition) \ + V(AnchorScroll) \ + V(BackdropFilter) \ + V(BackdropFilterMask) \ + V(RootScroller) \ + V(Viewport) \ + V(WillChangeTransform) \ + V(WillChangeScale) \ + V(WillChangeRotate) \ + V(WillChangeTranslate) \ + V(WillChangeOpacity) \ + V(WillChangeFilter) \ + V(WillChangeBackdropFilter) \ + /* This flag is needed only when none of the explicit kWillChange* reasons \ + are set. */ \ + V(WillChangeOther) \ + \ + /* Reasons that depend on ancestor properties */ \ + V(BackfaceInvisibility3DAncestor) \ + /* TODO(crbug.com/1256990): Transform3DSceneLeaf today depends only on the \ + element and its properties, but in the future it could be optimized \ + to consider descendants and moved to the subtree group below. */ \ + V(Transform3DSceneLeaf) \ + \ + /* Subtree reasons that require knowing what the status of your subtree is \ + before knowing the answer. */ \ + V(PerspectiveWith3DDescendants) \ + V(Preserve3DWith3DDescendants) \ + \ + /* ViewTransition element. \ + See third_party/blink/renderer/core/view_transition/README.md. */ \ + V(ViewTransitionElement) \ + V(ViewTransitionPseudoElement) \ + \ + /* For composited scrolling. In CompositeScrollAfterPaint, this is \ + determined after paint. */ \ + V(OverflowScrolling) \ + \ + /* The following reasons are not used in paint properties, but are \ + determined after paint, for debugging. See PaintArtifactCompositor. */ \ + /* This is based on overlapping relationship among pending layers. */ \ + V(Overlap) \ + /* These are based on the type of paint chunks and display items. */ \ + V(BackfaceVisibilityHidden) \ + V(Caret) \ + V(Video) \ + V(Canvas) \ + V(Plugin) \ + V(Scrollbar) \ + V(LinkHighlight) \ + V(DevToolsOverlay) \ + V(ViewTransitionContent) class PLATFORM_EXPORT CompositingReason { DISALLOW_NEW();
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc index ebeb76ca..83b52be 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
@@ -79,14 +79,14 @@ // If the target scroller comes from a main thread hit test, we're in // scroll unification. - scroll_state_data.is_main_thread_hit_tested = - event.data.scroll_begin.main_thread_hit_tested; - DCHECK(!event.data.scroll_begin.main_thread_hit_tested || + scroll_state_data.main_thread_hit_tested_reasons = + event.data.scroll_begin.main_thread_hit_tested_reasons; + DCHECK(!event.data.scroll_begin.main_thread_hit_tested_reasons || base::FeatureList::IsEnabled(::features::kScrollUnification)); } else { // If a main thread hit test didn't yield a target we should have // discarded this event before this point. - DCHECK(!event.data.scroll_begin.main_thread_hit_tested); + DCHECK(!event.data.scroll_begin.main_thread_hit_tested_reasons); } break; @@ -386,11 +386,14 @@ DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification)); DCHECK_EQ(event->Event().GetType(), WebGestureEvent::Type::kGestureScrollBegin); - DCHECK(hit_testing_scroll_begin_on_main_thread_); + DCHECK(scroll_begin_main_thread_hit_test_reasons_); DCHECK(currently_active_gesture_device_); DCHECK(input_handler_); - hit_testing_scroll_begin_on_main_thread_ = false; + uint32_t main_thread_hit_test_reasons = + scroll_begin_main_thread_hit_test_reasons_; + scroll_begin_main_thread_hit_test_reasons_ = + cc::MainThreadScrollingReason::kNotScrollingOnMain; // HandleGestureScrollBegin has logic to end an existing scroll when an // unexpected scroll begin arrives. We currently think we're in a scroll @@ -403,7 +406,8 @@ if (hit_test_result) { gesture_event->data.scroll_begin.scrollable_area_element_id = hit_test_result.GetInternalValue(); - gesture_event->data.scroll_begin.main_thread_hit_tested = true; + gesture_event->data.scroll_begin.main_thread_hit_tested_reasons = + main_thread_hit_test_reasons; if (metrics) { // The event is going to be re-processed on the compositor thread; so, @@ -516,7 +520,7 @@ // Block flushing the compositor gesture event queue while there's an async // scroll begin hit test outstanding. We'll flush the queue when the hit test // responds. - if (hit_testing_scroll_begin_on_main_thread_) { + if (scroll_begin_main_thread_hit_test_reasons_) { DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification)); return false; } @@ -844,7 +848,7 @@ void InputHandlerProxy::RecordScrollBegin( WebGestureDevice device, uint32_t reasons_from_scroll_begin, - bool was_main_thread_hit_tested, + uint32_t main_thread_hit_tested_reasons, uint32_t main_thread_repaint_reasons) { if (device != WebGestureDevice::kTouchpad && device != WebGestureDevice::kScrollbar && @@ -872,7 +876,7 @@ disposition.has_value() && disposition == DID_NOT_HANDLE; bool blocked_on_main_at_begin = - blocked_on_main_thread_handler || was_main_thread_hit_tested; + blocked_on_main_thread_handler || main_thread_hit_tested_reasons; auto scroll_start_state = RecordScrollingThread( is_compositor_scroll, blocked_on_main_at_begin, device); @@ -888,9 +892,7 @@ ? cc::MainThreadScrollingReason::kWheelEventHandlerRegion : cc::MainThreadScrollingReason::kTouchEventHandlerRegion); } - if (was_main_thread_hit_tested) { - reportable_reasons |= cc::MainThreadScrollingReason::kFailedHitTest; - } + reportable_reasons |= main_thread_hit_tested_reasons; // With scroll unification, we never scroll "on main" from the perspective // of cc::InputHandler, but we still want to log reasons if the user will not @@ -989,16 +991,17 @@ // If we need a hit test from the main thread, we'll reinject this scroll // begin event once the hit test is complete so avoid everything below for // now, it'll be run on the second iteration. - if (scroll_status.needs_main_thread_hit_test) { + if (scroll_status.main_thread_hit_test_reasons) { DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification)); - hit_testing_scroll_begin_on_main_thread_ = true; + scroll_begin_main_thread_hit_test_reasons_ = + scroll_status.main_thread_hit_test_reasons; return REQUIRES_MAIN_THREAD_HIT_TEST; } if (scroll_status.thread != ScrollThread::SCROLL_IGNORED) { RecordScrollBegin(gesture_event.SourceDevice(), scroll_status.main_thread_scrolling_reasons, - scroll_state.is_main_thread_hit_tested(), + scroll_state.main_thread_hit_tested_reasons(), scroll_status.main_thread_repaint_reasons); }
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h index a0c340d..e8ca90d3 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.h
@@ -322,7 +322,7 @@ void RecordScrollBegin(blink::WebGestureDevice device, uint32_t reasons_from_scroll_begin, - bool was_main_thread_hit_tested, + uint32_t main_thread_hit_tested_reasons, uint32_t main_thread_repaint_reasons); bool HasQueuedEventsReadyForDispatch(); @@ -401,13 +401,14 @@ bool skip_touch_filter_discrete_ = false; bool skip_touch_filter_all_ = false; - // This bit is set when the input handler proxy has requested that the client + // This is set when the input handler proxy has requested that the client // perform a hit test for a scroll begin on the main thread. During that // time, scroll updates need to be queued. The reply from the main thread // will come by calling ContinueScrollBeginAfterMainThreadHitTest where the // queue will be flushed and this bit cleared. Used only in scroll // unification. - bool hit_testing_scroll_begin_on_main_thread_ = false; + uint32_t scroll_begin_main_thread_hit_test_reasons_ = + cc::MainThreadScrollingReason::kNotScrollingOnMain; // This bit can be used to disable event attribution in cases where the // hit test information is unnecessary (e.g. tests).
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc index 598e185..9011d68 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
@@ -317,25 +317,25 @@ return point; } -const cc::InputHandler::ScrollStatus kImplThreadScrollState( +const cc::InputHandler::ScrollStatus kImplThreadScrollState{ cc::InputHandler::ScrollThread::SCROLL_ON_IMPL_THREAD, - cc::MainThreadScrollingReason::kNotScrollingOnMain); + cc::MainThreadScrollingReason::kNotScrollingOnMain}; -const cc::InputHandler::ScrollStatus kRequiresMainThreadHitTestState( +const cc::InputHandler::ScrollStatus kRequiresMainThreadHitTestState{ cc::InputHandler::ScrollThread::SCROLL_ON_IMPL_THREAD, cc::MainThreadScrollingReason::kNotScrollingOnMain, - /*needs_main_thread_hit_test=*/true); + cc::MainThreadScrollingReason::kNonFastScrollableRegion}; constexpr auto kSampleMainThreadScrollingReason = cc::MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; -const cc::InputHandler::ScrollStatus kMainThreadScrollState( +const cc::InputHandler::ScrollStatus kMainThreadScrollState{ cc::InputHandler::ScrollThread::SCROLL_ON_MAIN_THREAD, - kSampleMainThreadScrollingReason); + kSampleMainThreadScrollingReason}; -const cc::InputHandler::ScrollStatus kScrollIgnoredScrollState( +const cc::InputHandler::ScrollStatus kScrollIgnoredScrollState{ cc::InputHandler::ScrollThread::SCROLL_IGNORED, - cc::MainThreadScrollingReason::kNotScrollingOnMain); + cc::MainThreadScrollingReason::kNotScrollingOnMain}; } // namespace @@ -2041,7 +2041,8 @@ WebInputEvent::Type::kGestureScrollBegin, WebInputEvent::kNoModifiers, TimeForInputEvents(), WebGestureDevice::kTouchpad); gsb->data.scroll_begin.scrollable_area_element_id = 0; - gsb->data.scroll_begin.main_thread_hit_tested = false; + gsb->data.scroll_begin.main_thread_hit_tested_reasons = + cc::MainThreadScrollingReason::kNotScrollingOnMain; gsb->data.scroll_begin.delta_x_hint = 0; gsb->data.scroll_begin.delta_y_hint = 10; gsb->data.scroll_begin.pointer_count = 0; @@ -2086,7 +2087,8 @@ } bool MainThreadHitTestInProgress() const { - return input_handler_proxy_.hit_testing_scroll_begin_on_main_thread_; + return input_handler_proxy_.scroll_begin_main_thread_hit_test_reasons_ != + cc::MainThreadScrollingReason::kNotScrollingOnMain; } void BeginFrame() { @@ -2266,7 +2268,9 @@ mock_input_handler_, ScrollBegin( AllOf(Property(&ScrollState::target_element_id, Eq(ElementId())), - Property(&ScrollState::is_main_thread_hit_tested, Eq(false))), + Property( + &ScrollState::main_thread_hit_tested_reasons, + Eq(cc::MainThreadScrollingReason::kNotScrollingOnMain))), _)) .WillOnce(Return(kRequiresMainThreadHitTestState)); DispatchEvent(ScrollBegin()); @@ -2283,7 +2287,9 @@ mock_input_handler_, ScrollBegin( AllOf(Property(&ScrollState::target_element_id, Eq(kHitTestResult)), - Property(&ScrollState::is_main_thread_hit_tested, Eq(true))), + Property(&ScrollState::main_thread_hit_tested_reasons, + Eq(cc::MainThreadScrollingReason:: + kNonFastScrollableRegion))), _)) .Times(1); @@ -3748,7 +3754,8 @@ VERIFY_AND_RESET_MOCKS(); gesture_.data.scroll_begin.scrollable_area_element_id = 1; - gesture_.data.scroll_begin.main_thread_hit_tested = true; + gesture_.data.scroll_begin.main_thread_hit_tested_reasons = + cc::MainThreadScrollingReason::kNonFastScrollableRegion; EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _)) .WillOnce(testing::Return(kImplThreadScrollState)); @@ -3765,7 +3772,7 @@ VERIFY_AND_RESET_MOCKS(); EXPECT_MAIN_THREAD_WHEEL_SCROLL_SAMPLE( - cc::MainThreadScrollingReason::kFailedHitTest); + cc::MainThreadScrollingReason::kNonFastScrollableRegion); } TEST_P(InputHandlerProxyMainThreadScrollingReasonTest,
diff --git a/third_party/blink/tools/blinkpy/web_tests/results.html b/third_party/blink/tools/blinkpy/web_tests/results.html index 0b1b17e..3e4867d 100644 --- a/third_party/blink/tools/blinkpy/web_tests/results.html +++ b/third_party/blink/tools/blinkpy/web_tests/results.html
@@ -1761,9 +1761,7 @@ document.querySelector("#count_unexpected_pass").parentElement.classList.add("good"); document.querySelector("#summary_total").innerText = counts.count_all; - if (!GUI.hasBaseExpectations) - document.querySelector("#flag-toolbar").classList.add("hidden"); - else { + if (GUI.hasBaseExpectations || fullResults.flag_name) { document.querySelector("#flag-toolbar").classList.remove("hidden"); let flagName = fullResults.flag_name || ""; flagName = flagName.replace('/', '') @@ -1771,6 +1769,8 @@ Array.from(document.querySelectorAll(".flag_name")).forEach( el => { el.innerText = flagName; }); + } else { + document.querySelector("#flag-toolbar").classList.add("hidden"); } },
diff --git a/third_party/blink/tools/blinkpy/web_tests/results.html.version b/third_party/blink/tools/blinkpy/web_tests/results.html.version index 61bc78d..eba6e816 100644 --- a/third_party/blink/tools/blinkpy/web_tests/results.html.version +++ b/third_party/blink/tools/blinkpy/web_tests/results.html.version
@@ -1 +1 @@ -Version=1.3 +Version=1.4
diff --git a/third_party/blink/tools/run_wpt_tests.py b/third_party/blink/tools/run_wpt_tests.py index e1959ff..bde81fb 100755 --- a/third_party/blink/tools/run_wpt_tests.py +++ b/third_party/blink/tools/run_wpt_tests.py
@@ -745,6 +745,15 @@ include.extend(extra_include) exclude.extend(extra_exclude) namespace.include, namespace.exclude = include, exclude + # The `chromium_tests` recipe passes `--isolated-script-test-filter` to + # retry failed tests without the patch. Because the patch may have added + # the failed tests (common for imported tests), + # 1. `run_wpt_tests.py --isolated-script-test-filter` must tolerate + # test IDs that don't exist. + # 2. When all tests retried don't exist without the patch, wptrunner + # must run zero tests and exit successfully instead of interpreting + # the lack of explicit tests as running all tests. + namespace.default_exclude = True def _resolve_tests(self, test_filter: str) -> Tuple[List[str], List[str]]: """Resolve an isolated script-style filter string into lists of tests.
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 721f2a1..0536829 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1128,7 +1128,6 @@ crbug.com/882385 external/wpt/css/css-contain/quote-scoping-002.html [ Failure ] crbug.com/882385 external/wpt/css/css-contain/quote-scoping-003.html [ Failure ] crbug.com/882385 external/wpt/css/css-contain/quote-scoping-004.html [ Failure ] -crbug.com/1400979 external/wpt/css/css-contain/container-queries/nested-query-containers.html [ Crash Failure Pass Timeout ] # [css-align] @@ -2951,6 +2950,14 @@ crbug.com/626703 external/wpt/css/css-multicol/file-control-crash.html [ Crash ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/css/css-color/system-color-hightlights-vs-getSelection-001.html [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/mediacapture-record/MediaRecorder-mimetype.html [ Timeout ] +crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-record/MediaRecorder-mimetype.html [ Timeout ] +crbug.com/626703 [ Linux ] external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html [ Timeout ] +crbug.com/626703 [ Mac ] external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html [ Timeout ] +# `win-rel` fails but `win*-blink-rel` passes on this test. +crbug.com/626703 [ Win ] external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html [ Failure ] +crbug.com/626703 external/wpt/svg/text/reftests/opacity.svg [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webvtt/rendering/cues-with-video/processing-model/embedded_style_media_queries.html [ Failure ] crbug.com/626703 [ Mac10.14 ] external/wpt/webvtt/rendering/cues-with-video/processing-model/embedded_style_media_queries.html [ Failure ] crbug.com/626703 [ Mac10.14 ] external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-video-sibling.html [ Crash ] @@ -2962,7 +2969,6 @@ crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-fromelement/capture.html [ Crash ] crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-image/MediaStreamTrack-getConstraints.https.html [ Crash ] crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-audio.https.html [ Crash ] -crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-record/MediaRecorder-mimetype.html [ Crash ] crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https.html [ Crash ] crbug.com/626703 [ Mac10.14 ] external/wpt/screen-capture/getdisplaymedia.https.html [ Crash ] crbug.com/626703 [ Mac10.14 ] external/wpt/video-rvfc/request-video-frame-callback-during-xr-session.https.html [ Crash Timeout ] @@ -3023,7 +3029,6 @@ crbug.com/626703 [ Mac10.14 ] external/wpt/webvtt/rendering/cues-with-video/processing-model/audio_has_no_subtitles.html [ Crash ] crbug.com/626703 [ Mac10.14 ] external/wpt/webvtt/rendering/cues-with-video/processing-model/embedded_style_media_queries_resized.html [ Crash ] crbug.com/626703 [ Mac10.14 ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStream-finished-add.https.html [ Crash ] -crbug.com/626703 [ Mac10.14 ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html [ Crash ] crbug.com/626703 [ Mac10.14 ] wpt_internal/webcodecs/annexb_decoding.https.any.html [ Crash ] crbug.com/626703 [ Mac10.14 ] wpt_internal/webcodecs/annexb_decoding.https.any.worker.html [ Crash ] crbug.com/626703 [ Mac10.14 ] wpt_internal/webcodecs/avc_encoder_config.https.any.html [ Crash ] @@ -3046,8 +3051,6 @@ crbug.com/626703 external/wpt/css/css-box/margin-trim/flex-row-style-change-triggers-layout-inline.html [ Failure ] crbug.com/626703 [ Linux ] virtual/pending-beacon/external/wpt/pending-beacon/pending_beacon-sendonhidden.tentative.https.window.html [ Timeout ] crbug.com/626703 [ Mac13 ] virtual/pending-beacon/external/wpt/pending-beacon/pending_beacon-sendonhidden.tentative.https.window.html [ Timeout ] -crbug.com/626703 external/wpt/css/mediaqueries/scripting-print-noscript.html [ Failure ] -crbug.com/626703 external/wpt/css/mediaqueries/scripting-print-script.html [ Failure ] crbug.com/626703 [ Linux ] virtual/keepalive-in-browser-migration/external/wpt/fetch/api/response/response-clone.any.serviceworker.html [ Timeout ] crbug.com/626703 [ Mac12 ] virtual/keepalive-in-browser-migration/external/wpt/fetch/api/response/response-clone.any.serviceworker.html [ Timeout ] crbug.com/626703 [ Mac13 ] virtual/keepalive-in-browser-migration/external/wpt/fetch/api/response/response-clone.any.serviceworker.html [ Timeout ] @@ -6854,4 +6857,7 @@ crbug.com/1432272 [ Linux ] virtual/unsafe_webgpu/regress/regress-1104580.html [ Crash Pass ] # Sheriff 2023-04-12 -crbug.com/1432666 [ Mac ] external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Failure Pass ] \ No newline at end of file +crbug.com/1432666 [ Mac ] external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Failure Pass ] + +# Sheriff 2023-04-13 +crbug.com/1432763 [ Linux ] external/wpt/fetch/metadata/generated/element-picture.https.sub.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 11a2519..83087be 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -142,7 +142,8 @@ "scrollbars", "external/wpt/css/css-scroll-snap", "external/wpt/scroll-animations", - "external/wpt/css/css-overflow"], + "external/wpt/css/css-overflow", + "http/tests/devtools/layers"], "args": ["--enable-features=CompositeScrollAfterPaint"], "expires": "Sep 1, 2023" },
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 023cc42..7d825c2 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -1844,6 +1844,13 @@ null, {} ] + ], + "fontfaceset-worker-fontface-crash.html": [ + "11f7e1faf022178b3c6b127f9582ca80477f3c4f", + [ + null, + {} + ] ] }, "css-fonts": { @@ -57142,6 +57149,19 @@ {} ] ], + "absolute-non-replaced-max-001.html": [ + "4b208c5831e1b36a3c503129562175457ef41c0b", + [ + null, + [ + [ + "/css/CSS2/positioning/absolute-non-replaced-max-001-ref.html", + "==" + ] + ], + {} + ] + ], "absolute-non-replaced-max-height-002.xht": [ "7637068a9c4a2cc584acfa329d5aabb09e7101ab", [ @@ -57285,6 +57305,32 @@ {} ] ], + "absolute-non-replaced-min-001.html": [ + "0e6d17661e39beb872f886eba06acf47be9a931c", + [ + null, + [ + [ + "/css/CSS2/positioning/absolute-non-replaced-min-max-001-ref.html", + "==" + ] + ], + {} + ] + ], + "absolute-non-replaced-min-max-001.html": [ + "2e240b7509adc3bd8cb9cae67165e0dc42296e07", + [ + null, + [ + [ + "/css/CSS2/positioning/absolute-non-replaced-min-max-001-ref.html", + "==" + ] + ], + {} + ] + ], "absolute-non-replaced-width-001.xht": [ "6d2b8a33a0db793d9e52e94b33aa1c95884a2dbe", [ @@ -76454,7 +76500,7 @@ ] ], "clip-text-multi-line.html": [ - "e85a4f974bdea7063215654f2f1aeb9f12967a36", + "88ad111eb8400ee8c213f6f6f411c25ef61af42c", [ null, [ @@ -76463,7 +76509,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 5846 + ] + ] + ] + ] + } ] ] }, @@ -76832,7 +76894,7 @@ ] ], "background-gradient-subpixel-fills-area.html": [ - "2a305068fe4ceb41380f6447bb0f2adb2cd141b5", + "78d4c99c06f3d867cd1a567c5558b97fbc1f89b0", [ null, [ @@ -76851,7 +76913,7 @@ 1 ], [ - 6800, + 0, 6800 ] ] @@ -77082,7 +77144,7 @@ ] ], "background-image-none-gradient-repaint.html": [ - "3f39fb8d850d7561703f791135ea7dd4b3aa9fe8", + "1ddca5e21d9032a5658b08480f7b12e400b02b0a", [ null, [ @@ -77091,7 +77153,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 9693 + ] + ] + ] + ] + } ] ], "background-image-shared-stylesheet.html": [ @@ -77461,7 +77539,7 @@ ], "background-repeat": { "background-repeat-no-repeat.xht": [ - "00d428f6ec768f34772964b74ad45415b6bb32a9", + "d102e80cce939e617e1d8e6da7b71e096a222431", [ null, [ @@ -77470,7 +77548,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 5 + ] + ] + ] + ] + } ] ], "background-repeat-repeat-x.xht": [ @@ -77582,7 +77676,7 @@ ] ], "background-repeat-round-1b.html": [ - "b3e1e9684b85ed9d3ad9a2739109c278be77c38b", + "831666efd2ae810f1d20733113b991e3aa8efe74", [ null, [ @@ -77591,7 +77685,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 12 + ] + ] + ] + ] + } ] ], "background-repeat-round-1c.html": [ @@ -77608,7 +77718,7 @@ ] ], "background-repeat-round-1d.html": [ - "69045cf605a27d87c058572852ef445a738eab53", + "7b7d42606ddccf6c9cc06155ec7b9282be297e94", [ null, [ @@ -77617,11 +77727,27 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 12 + ] + ] + ] + ] + } ] ], "background-repeat-round-1e.html": [ - "5fd4973dcd8ec931dafe549af89aaea6ed73e150", + "9fbf786bd138181aca17cc979f973fcd0de38702", [ null, [ @@ -77630,11 +77756,27 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 12 + ] + ] + ] + ] + } ] ], "background-repeat-round-2.html": [ - "702931abe8496733ecc248c6faaf3d2bffb9d189", + "a49224cc1baca9bf37f49a30bba7f5033c7f83bd", [ null, [ @@ -77643,11 +77785,27 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 9 + ] + ] + ] + ] + } ] ], "background-repeat-round-3.html": [ - "c3b5e2b2d00399db1f05978b1595152548508e1c", + "e7d6f4527234b4785aea66fccfc82fcf8e5739fa", [ null, [ @@ -77656,7 +77814,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 9 + ] + ] + ] + ] + } ] ], "background-repeat-round-4.html": [ @@ -77831,7 +78005,7 @@ ] ], "background-repeat-space-4.html": [ - "36f92c01582119ec79fe4842628b88048c061f9e", + "c3b35d6a6dacc0855349e7cbf534f3824d9739a7", [ null, [ @@ -77851,7 +78025,7 @@ ], [ 0, - 7905 + 7908 ] ] ] @@ -77860,7 +78034,7 @@ ] ], "background-repeat-space-5.html": [ - "7b499a743e4a521c6baf79c5538a03c02560cfde", + "5594efb315a245a1f1282a782cc740d602407229", [ null, [ @@ -77880,7 +78054,7 @@ ], [ 0, - 7950 + 7960 ] ] ] @@ -77889,7 +78063,7 @@ ] ], "background-repeat-space-6.html": [ - "80728ca4d55d631977cdd76624e787824c268d2a", + "8d372dd2771dc4de9e357b6fd43359009a438459", [ null, [ @@ -77905,11 +78079,11 @@ [ [ 0, - 48 + 64 ], [ 0, - 15780 + 15894 ] ] ] @@ -77918,7 +78092,7 @@ ] ], "background-repeat-space-7.html": [ - "c8b8731cc01ec4f952533da6c7571bbdba0e0c48", + "d52f76fe5f4653a8a2b62d8cec74915ba4622bdd", [ null, [ @@ -77934,7 +78108,7 @@ [ [ 0, - 48 + 64 ], [ 0, @@ -77947,7 +78121,7 @@ ] ], "background-repeat-space-8.html": [ - "97a2d654952009c17a4f2d94cc7877752f80d995", + "17beb1caf822a2ec0351eb18a66dae0358901865", [ null, [ @@ -77963,7 +78137,7 @@ [ [ 0, - 48 + 80 ], [ 0, @@ -78005,7 +78179,7 @@ ] ], "background-rounded-image-clip.html": [ - "f492b2b419a486038a02aa6e4bab14b49b04a07c", + "e6222190c192c0fa3db307e2c0cecf6d9a99a13c", [ null, [ @@ -78021,11 +78195,11 @@ [ [ 0, - 1 + 2 ], [ 0, - 18461 + 22547 ] ] ] @@ -78074,7 +78248,7 @@ ] ], "background-size-cover-svg.html": [ - "091600a185fcd1b07fd7d457b93ddd17936fe502", + "67f3bcac7d5da84f4e1c120974ca0ceeeaf6ffa0", [ null, [ @@ -78090,7 +78264,7 @@ [ [ 0, - 1 + 2 ], [ 0, @@ -78546,7 +78720,7 @@ ] ], "diagonal-percentage-vector-background.html": [ - "a794e46622b2c2d2405b6d324f1aa308c4e96157", + "75c8fd468549a0aac8189e93a572a941725cf790", [ null, [ @@ -78555,7 +78729,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 5 + ], + [ + 0, + 360 + ] + ] + ] + ] + } ] ], "tall--auto--omitted-width-percent-height.html": [ @@ -81083,7 +81273,7 @@ ] ], "background-size-025.html": [ - "8b6fed3f3e533f93e2ffe7818ab6a9f2c42a936d", + "fb5437fa16822b45d413c2b3445bcb6d563b7abc", [ null, [ @@ -81092,7 +81282,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 70 + ], + [ + 0, + 7294 + ] + ] + ] + ] + } ] ], "background-size-026.html": [ @@ -81138,7 +81344,7 @@ ] ], "background-size-028.html": [ - "0326506f812efd1185dc263c9d005a3e820396d1", + "20efb4e77b1ef92ccf446970ef60246aead689a0", [ null, [ @@ -81153,7 +81359,7 @@ null, [ [ - 1, + 0, 1 ], [ @@ -81167,7 +81373,7 @@ ] ], "background-size-029.html": [ - "0d4c5bca4ae3192fcf3b4da7e4d6d6d55e3570b8", + "29df68962c4b5aed37f0267e9349091b1a2ea9a5", [ null, [ @@ -81187,7 +81393,7 @@ ], [ 0, - 5283 + 5292 ] ] ] @@ -81439,7 +81645,7 @@ ] ], "bg-color-with-gradient.html": [ - "7ef5d611bcf2c131dbeef8e72877328ef1be7710", + "be08fa5800b80cfbe84925722bc323cc9a4ce366", [ null, [ @@ -81448,7 +81654,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 3 + ], + [ + 0, + 6909 + ] + ] + ] + ] + } ] ], "border-bottom-left-radius-001.xht": [ @@ -81494,7 +81716,7 @@ ] ], "border-bottom-left-radius-005.xht": [ - "cc9fee12108c0c33325f9200d49dc8f30293fbb5", + "bceaa3d9e9c7b6e2d567813f980333d9a2d1f3dd", [ null, [ @@ -81503,7 +81725,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 1 + ] + ] + ] + ] + } ] ], "border-bottom-left-radius-010.xht": [ @@ -81559,7 +81797,7 @@ ] ], "border-bottom-right-radius-004.xht": [ - "24b7cd9f741285597bc01389869dc1229e588c61", + "2af4de7bfee9068db7fc664c4a8f41704296e4ac", [ null, [ @@ -81574,12 +81812,12 @@ null, [ [ - 1, - 1 + 0, + 73 ], [ 0, - 1 + 127 ] ] ] @@ -81588,7 +81826,7 @@ ] ], "border-bottom-right-radius-005.xht": [ - "899125420faaa9f8e3c5fa596490b2b3b546dd3c", + "f53ae0d92f1f6ac26e41a85579845aff8cb43ab7", [ null, [ @@ -81597,7 +81835,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 36 + ], + [ + 0, + 131 + ] + ] + ] + ] + } ] ], "border-bottom-right-radius-010.xht": [ @@ -81880,7 +82134,7 @@ ] ], "border-image-repeat-round-2.html": [ - "8e5ae553317d26b9d760326e480dbb5c0582e2d5", + "89f8dc0561542bf4f92881c178a3806a7e0436fb", [ null, [ @@ -81900,7 +82154,7 @@ ], [ 0, - 376 + 380 ] ] ] @@ -81909,7 +82163,7 @@ ] ], "border-image-repeat-round.html": [ - "5171eef5fd4f78903c0872d164dd7cc15ec0fe71", + "cf87e8d16306ed34a11b7e89f7d88fe1f1212c12", [ null, [ @@ -81925,7 +82179,7 @@ [ [ 0, - 92 + 111 ], [ 0, @@ -81967,7 +82221,7 @@ ] ], "border-image-repeat-space-10.html": [ - "306a91370674925106489003205362ee73792484", + "73423ef27031c4863b4b34faa3fed2ef33554a3d", [ null, [ @@ -81983,11 +82237,11 @@ [ [ 0, - 80 + 163 ], [ 0, - 1472 + 2400 ] ] ] @@ -82132,7 +82386,7 @@ ] ], "border-image-repeat-space-8.html": [ - "6f577e80b871246139d0e7102849a61a16c606f6", + "0edfba9e9273c533ebac6762a365c8a83b7de3a9", [ null, [ @@ -82141,7 +82395,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 110 + ], + [ + 0, + 10540 + ] + ] + ] + ] + } ] ], "border-image-repeat-space-9.html": [ @@ -82158,7 +82428,7 @@ ] ], "border-image-round-and-stretch.html": [ - "73909c1d0b77d17e6c84a53287c2af2b70b219cb", + "a9b4da706d39ab85617f8a952987d3035e0fc400", [ null, [ @@ -82174,11 +82444,11 @@ [ [ 0, - 66 + 163 ], [ 0, - 4781 + 6375 ] ] ] @@ -82323,7 +82593,7 @@ ] ], "border-image-slice-fill-001.html": [ - "4a2c3e9cc016aa0a348d373c62b67cdd4db7677a", + "b6eb589c38fc32383485cebfed439ed7f9749e4e", [ null, [ @@ -82332,11 +82602,27 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 112 + ], + [ + 0, + 199 + ] + ] + ] + ] + } ] ], "border-image-slice-fill-002.html": [ - "bc194e40621c288d76dad1ca1b62d126d9f188c9", + "26e40479e9e8f5e4bfe120511a36280a222c266c", [ null, [ @@ -82345,11 +82631,27 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 112 + ], + [ + 0, + 199 + ] + ] + ] + ] + } ] ], "border-image-slice-fill-003.html": [ - "fd0833ff7fff619300260edb750d78919f64cd09", + "05e37c1a20dc3a5c063a6dece89a90bce2102511", [ null, [ @@ -82358,11 +82660,27 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 112 + ], + [ + 0, + 199 + ] + ] + ] + ] + } ] ], "border-image-slice-percentage.html": [ - "d4d2bdbfb94605138f462ef7624bc0cb6ffbf91b", + "f53501c9df1099b7571adfdb5c0126dd9e2502a2", [ null, [ @@ -82378,11 +82696,11 @@ [ [ 0, - 92 + 164 ], [ 0, - 3435 + 3716 ] ] ] @@ -82391,7 +82709,7 @@ ] ], "border-image-space-001.html": [ - "8e04127fd41d18fccd68b1c975d017b012faab7a", + "720f0df188d962c9d3797d18df2517da46f203aa", [ null, [ @@ -82459,7 +82777,7 @@ ] ], "border-image-width-008.html": [ - "3158cdb5717b873065bc70537075234492796501", + "20775aeb9d6dcf2d499d4604370c832491919df8", [ null, [ @@ -82468,7 +82786,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 74 + ] + ] + ] + ] + } ] ], "border-image-width-009.html": [ @@ -82777,7 +83111,7 @@ ] ], "border-radius-clipping-with-transform-001.html": [ - "e7d173b3c4e400803ce1c599f3050660d1813b64", + "b2187cf07abfe0b6b7ee24f35f35a57a5bf58789", [ null, [ @@ -82786,7 +83120,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 48 + ], + [ + 0, + 6783 + ] + ] + ] + ] + } ] ], "border-radius-dynamic-from-no-radius.html": [ @@ -82910,7 +83260,7 @@ ] ], "border-top-left-radius-005.xht": [ - "37af580e067b95a71002590d1ca4fa329ad72b85", + "68fd36d710933c6412f56a9fb0f8813ce360206c", [ null, [ @@ -82919,7 +83269,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 1 + ] + ] + ] + ] + } ] ], "border-top-left-radius-010.xht": [ @@ -82975,7 +83341,7 @@ ] ], "border-top-right-radius-004.xht": [ - "2d1f95cd08652fc7b76b56a99accee72226d50cd", + "3068a24d4368e84594e75082ac861039915360bc", [ null, [ @@ -82990,12 +83356,12 @@ null, [ [ - 1, + 0, 1 ], [ 0, - 1 + 2 ] ] ] @@ -83004,7 +83370,7 @@ ] ], "border-top-right-radius-005.xht": [ - "8bd3965de5a3951ab5761d6779323f6e6a47d152", + "46004d6fa11736a3ddef2d11950026a16c1dc69a", [ null, [ @@ -83013,7 +83379,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 36 + ], + [ + 0, + 131 + ] + ] + ] + ] + } ] ], "border-top-right-radius-010.xht": [ @@ -83555,7 +83937,7 @@ ] ], "css-border-radius-001.html": [ - "023f7d180240d53792343dbe0b9a2d427bcb7223", + "8b0e2e9a36c67393f0497b174784c5245cee1d7c", [ null, [ @@ -83571,11 +83953,11 @@ [ [ 0, - 63 + 116 ], [ 0, - 400 + 8035 ] ] ] @@ -83917,7 +84299,7 @@ ] ], "linear-gradient-currentcolor-first-line.html": [ - "737618fb66634189aae2a6dbb85568e7e8913ca6", + "7c8f8a8fda63982a7ded20fcdd25077ce4c73c39", [ null, [ @@ -83937,7 +84319,7 @@ ], [ 0, - 244 + 265 ] ] ] @@ -92564,6 +92946,19 @@ ] ], "table": { + "border-collapse-001.html": [ + "626935f24952deb6b03875a7686c15adc806ee14", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "border-spacing-at-breaks.tentative.html": [ "67588f28b02e258539c456d55af2f421cb6ba96a", [ @@ -97383,6 +97778,19 @@ {} ] ], + "system-color-hightlights-vs-getSelection-001.html": [ + "7223ecdc92599db1334b747bb4b5b0605b8cc131", + [ + null, + [ + [ + "/css/css-color/reference/system-color-hightlights-vs-getSelection-001-ref.html", + "==" + ] + ], + {} + ] + ], "t31-color-currentColor-b.xht": [ "b4ff486168877f9eb7326bb8648b0d19abc5d8ff", [ @@ -243695,32 +244103,6 @@ {} ] ], - "scripting-print-noscript.html": [ - "701013bd7151fcb05b16c033542aef5e150763a2", - [ - null, - [ - [ - "/css/mediaqueries/scripting-print-noscript-ref.html", - "==" - ] - ], - {} - ] - ], - "scripting-print-script.html": [ - "25f064ba2040053f225d5cd4494468537564af42", - [ - null, - [ - [ - "/css/mediaqueries/scripting-print-script-ref.html", - "==" - ] - ], - {} - ] - ], "viewport-script-dynamic.html": [ "7433877972b09b3a03cd9f8a11dcd3efd1aa01d6", [ @@ -265139,6 +265521,19 @@ {} ] ], + "opacity.svg": [ + "949de0cbf0c8aeaf779a94aa01c2688698e756f6", + [ + null, + [ + [ + "/svg/text/reftests/opacity-ref.svg", + "==" + ] + ], + {} + ] + ], "text-clipped-offscreen-move-onscreen.html": [ "c29f790326537395d40f251d3a0be746014fbb5e", [ @@ -268979,11 +269374,11 @@ "support": { ".cache": { "gitignore2.json": [ - "3752af403990d729aa3ea5ded977ff63ef748861", + "fb67ea1db4520c1c9de6d60c661b4c68eef2335c", [] ], "mtime.json": [ - "83165ede78670378488bd79fcb1447abd616ed1b", + "38c343141c3b7b7309e1733a4174d62a0a76699a", [] ] }, @@ -279480,6 +279875,10 @@ "38b152c320c19d8c53818fcb2d1a0d4887a1ec60", [] ], + "clear-003.xht.ini": [ + "313d7a8a59b6fa9c333555c870bc8baad1e559ca", + [] + ], "clear-applies-to-000-ref.xht": [ "973d1c6a054c56c6cf4eda4a1114aa0ec610e35b", [] @@ -281320,6 +281719,10 @@ "51ec44e9cf55daa92b0822590933275a6706b9aa", [] ], + "absolute-non-replaced-max-001-ref.html": [ + "742b3063abd693a543ca4ce88bda161ae04d8668", + [] + ], "absolute-non-replaced-max-height-002-ref.xht": [ "75b0e54b442a868bfd5b86c671cbb8b67211c800", [] @@ -281340,6 +281743,10 @@ "aea00aaa43cbb10e905796731278e68f1033e428", [] ], + "absolute-non-replaced-min-max-001-ref.html": [ + "3bbba2be908c099806ffdaaca440cf4513e1e92b", + [] + ], "absolute-non-replaced-width-002-ref.xht": [ "e88ac8098391299e2e106a831fb02f22e7eff9c8", [] @@ -284049,7 +284456,7 @@ ], "mix-blend-mode": { "mix-blend-mode-animation.html.ini": [ - "31409686380e526e26b8be26ec4309c7977789b7", + "b11b88b982f7c6f58f92d01ba0f600ee743ee9e6", [] ], "mix-blend-mode-blended-element-overflow-scroll.html.ini": [ @@ -288683,6 +289090,12 @@ "68068041f9f81ac54c8b90ffd6e8cc4a787992b1", [] ], + "reference": { + "system-color-hightlights-vs-getSelection-001-ref.html": [ + "1792869411b1d0aa9f418da53e17fd15762a7a64", + [] + ] + }, "srgb-linear-003-ref.html": [ "9de25f6ba06ba86bb2be724d5955778376802819", [] @@ -288709,6 +289122,10 @@ [] ] }, + "system-color-hightlights-vs-getSelection-001.html.ini": [ + "be50491553aff8c07aff62e74b5b35d514f241d9", + [] + ], "t31-color-currentColor-b-ref.html": [ "3013c7050c3c6f057e295923d43c87da6c09751f", [] @@ -291793,7 +292210,7 @@ ], "parsing": { "display-valid-expected.txt": [ - "5111847919ecaa92aa25d970ed522ce9bc9959f1", + "e62ae15baec2ac7406a9587c663a43d83ec114f9", [] ], "display-valid.html.ini": [ @@ -305289,6 +305706,10 @@ "558cfe8ee36f341f40247b3d23861414417c8df3", [] ], + "object-view-box-fit-cover-canvas.html.ini": [ + "699d95dd1fe2bb22fea42587249780f64514977e", + [] + ], "object-view-box-fit-cover-img-ref.html": [ "7e2bdc754dce11e71526847759794ff38865d4fc", [] @@ -305305,6 +305726,10 @@ "be3b221400a4e889d258ee887a63635d0c55baba", [] ], + "object-view-box-fit-fill-canvas.html.ini": [ + "2f9f1a53cabda7cba0c7154d2745bb763b376ff4", + [] + ], "object-view-box-fit-fill-img-ref.html": [ "32c97c8312f4eb78faa9018b0cf8a5f791d451bc", [] @@ -325667,7 +326092,7 @@ [] ], "kind-of-widget-fallback-input-reset-border-block-end-color-001.html.ini": [ - "439a23231df3754f9c26d1d55c252ac6d5834fa8", + "552d58c4044b8bc2fda8444844edc174a2005f99", [] ], "kind-of-widget-fallback-input-reset-border-block-end-style-001.html.ini": [ @@ -325843,7 +326268,7 @@ [] ], "kind-of-widget-fallback-input-search-text-border-end-start-radius-001.html.ini": [ - "b6cb6a74c76032a0f569d98d681852dd120adae4", + "0705c9dbe06523889951dbee1529bb16af01495e", [] ], "kind-of-widget-fallback-input-search-text-border-image-repeat-001.html.ini": [ @@ -325862,6 +326287,10 @@ "e77afe1815439c7122c23490781221f94231750b", [] ], + "kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html.ini": [ + "6f8eb451f388a015e2dc7762d35cf9cca7c9c692", + [] + ], "kind-of-widget-fallback-input-search-text-border-start-start-radius-001.html.ini": [ "c972fa93f5877ddccfa30f5f71f7fdf1ae24ca54", [] @@ -326302,6 +326731,10 @@ "3cc5bd22eb10e85b8bae3dd4175b777989f12bc4", [] ], + "kind-of-widget-fallback-textarea-border-right-style-001.html.ini": [ + "fb3cbd161deb557d4a8d17afe5192470f5bf8d41", + [] + ], "kind-of-widget-fallback-textarea-border-start-start-radius-001.html.ini": [ "7507d0dd65818071cdfc2fdbe3a96d7249cc1e24", [] @@ -332433,6 +332866,10 @@ "8bcbf4110267dca94150e28c61fdb1783b73df08", [] ], + "client-props-inline-list-item.html.ini": [ + "162c187eefe92e49173f3f6de9038e8ba137bb63", + [] + ], "cssom-getBoundingClientRect-vertical-rl-ref.html": [ "0b68c4f210c95dde58ffac2442472321ef6480a0", [] @@ -333785,6 +334222,14 @@ "f277097263e7acf6f2e7b40fa810231c61b00e63", [] ], + "inverted-colors-expected.txt": [ + "907ecd3eb20bfc25bcac45b4f3ca9b7fe9867562", + [] + ], + "inverted-colors.html.ini": [ + "c7adba8b0e15e113d666839fa9cf5e7573617ddb", + [] + ], "media-query-matches-in-iframe.html.ini": [ "205bf45683a027fa5a579851879539762c1223a9", [] @@ -333865,26 +334310,6 @@ "b24009718e8958e6e753249b691b1bce2d3f47f0", [] ], - "scripting-print-noscript-ref.html": [ - "d0bf78f8d592995eb6b28b068e9be7af1b6b7802", - [] - ], - "scripting-print-noscript.html.ini": [ - "f8256a3571751ec315c9743226636d05fdff3667", - [] - ], - "scripting-print-script-ref.html": [ - "0e3b6fc3e59a4b9a9d291927d5253ce84c8a603e", - [] - ], - "scripting-print-script.html.ini": [ - "2143b97f4b4b810d80150c326dd0484d02280623", - [] - ], - "scripting.html.ini": [ - "cfe3783f2c342e818eff0077d5181ea7b045f362", - [] - ], "support": { "media_queries_iframe.html": [ "890eb6c46113afbaf1dc88188c52a791623590a8", @@ -351706,6 +352131,10 @@ "a19f4400cea33a60c99807330704a23ee363b146", [] ], + "popup-same-origin-unsafe-allow-outgoing-with-same-site.https.html.ini": [ + "8eb49f5a212bff324d3cda1f2fdce6305ecef148", + [] + ], "popup-same-site-unsafe-allow-outgoing-with-cross-origin.https.html.headers": [ "ab7b28948150ff64101ef080b0d9c7cc9a6a34d2", [] @@ -357978,7 +358407,7 @@ [] ], "computed-style-expected.txt": [ - "8135c007bcff630d04e1f8d2c26d169dabd1e100", + "54a7424529041f5555ff4a6a0ec62503666e94c9", [] ], "computed-style.html.ini": [ @@ -357986,7 +358415,7 @@ [] ], "display-other-expected.txt": [ - "8b5aeae1b3425002bf2a6394324ec7e48af5f100", + "07fe304399ff6f0e1c1363e67c5698757326d1cb", [] ], "display-other.html.ini": [ @@ -363367,11 +363796,11 @@ [] ], "html5lib_innerHTML_webkit02-expected.txt": [ - "062089f49a06dd4918b2ac00aca606777c632737", + "c3f914d0a1dc2b9c76f09e64ad8e871903a75f28", [] ], "html5lib_innerHTML_webkit02.html.ini": [ - "e4f12f060c555be0b5b2c89abe57b9a5b0053c5d", + "4d14f9cafd2ae2ac0310a74c502b9bb1042b4de1", [] ], "html5lib_isindex-expected.txt": [ @@ -363435,15 +363864,15 @@ [] ], "html5lib_webkit02_run_type=uri-expected.txt": [ - "90886a9d51b5369803daabbd494a614550841b8c", + "210903a670f17d0f232d3b8c574b9b18b7024ce4", [] ], "html5lib_webkit02_run_type=write-expected.txt": [ - "90886a9d51b5369803daabbd494a614550841b8c", + "210903a670f17d0f232d3b8c574b9b18b7024ce4", [] ], "html5lib_webkit02_run_type=write_single-expected.txt": [ - "90886a9d51b5369803daabbd494a614550841b8c", + "210903a670f17d0f232d3b8c574b9b18b7024ce4", [] ], "inhead-noscript-head-expected.txt": [ @@ -364740,7 +365169,7 @@ [] ], "html5lib_tests_revision": [ - "4535af29f6b43f6c178c97b021d00c4b3350a311", + "dae44a04416d95dc79736dbaca6a9669ad6d4e33", [] ], "update_html5lib_tests.py": [ @@ -368427,6 +368856,10 @@ [] ], "tentative": { + "loaf-blocking-duration.html.ini": [ + "5d138694f44866fb0a69985cf6a6510687c6f03d", + [] + ], "loaf-desired-exec-time.html.ini": [ "8e64d0a34431c6fcf2bc95fe1c7b06aa9be381ff", [] @@ -370604,10 +371037,6 @@ "d59e5e30845eaef12bab6419e348a01779313c56", [] ], - "MediaRecorder-bitrate.https-expected.txt": [ - "5097645753112feff9782fe5bb1069705a1badb5", - [] - ], "MediaRecorder-bitrate.https.html.ini": [ "ab1d160b4237f87edf11098cd2d7a16f2f917c24", [] @@ -370644,10 +371073,6 @@ "683f9ba04a615a3ee8b8f0d5525d038aca6e5677", [] ], - "MediaRecorder-start-expected.txt": [ - "c7381df2d8f856218b1e3b2a07d86e09dbdbdf64", - [] - ], "MediaRecorder-start.html.ini": [ "3011ef13bc230c0097a0dcf156fbae1f3f7b8015", [] @@ -370678,7 +371103,7 @@ }, "utils": { "peerconnection.js": [ - "26a925abf077827136f6f4755fee7e3f3ff9c800", + "8b0f266facae0296d4ca0f58da31cd5b87c1b260", [] ], "sources.js": [ @@ -372466,7 +372891,7 @@ [] ], "window_state_context.js": [ - "40f10a564484c97e33706f6a6df71f7984b72df4", + "fa96bf3b760ea95d2eb04a322a9ee15680a2caa0", [] ] }, @@ -376550,6 +376975,10 @@ "7674eb0ab835a1b02541a28b4ed9084e61b2e088", [] ], + "devicepixel2.html.ini": [ + "3f8d6d082f8bc49faea03d72e511f72f238392d1", + [] + ], "fragments-expected.txt": [ "3b584d2684ee96c7a53deb4246f26015120a6cf0", [] @@ -377164,7 +377593,7 @@ [] ], "mock-subapps.js": [ - "b63e97b8c4dccf7726671d7f372f24bc431ba2f1", + "b81936713b17db941ef380d4019cecfbe563caf6", [] ], "mock-textdetection.js": [ @@ -383312,7 +383741,7 @@ ], "resources": { "subapps-helpers.js": [ - "9158d15c6c89b7cb328ca9a378a7753deb4d5e91", + "38b8d1146603147667df405ef012358ae423fde4", [] ] } @@ -383511,6 +383940,14 @@ } }, "embedded": { + "image-crossorigin.sub-expected.txt": [ + "daad42056e272f54f9c2e0a0f9ea2b6549632470", + [] + ], + "image-crossorigin.sub.html.ini": [ + "b6fb429f1ee586faab2f9d05b7dbfeab7fa4b9eb", + [] + ], "image-embedding-svg-with-near-integral-width-ref.html": [ "655d982b16ce0582f6b83e26844b2a6e2437b17b", [] @@ -384682,6 +385119,14 @@ "18c6ed4f1bd5905652d209007322dc394769665b", [] ], + "opacity-ref.svg": [ + "18c00ab332c73f5c033e37d4429872d07210ade4", + [] + ], + "opacity.svg.ini": [ + "51c0b4735502fb2c5b00c091e6071558716a375e", + [] + ], "text-clipped-offscreen-move-onscreen-ref.html": [ "b03ac22aaa3155323ea1574e49241368ec1ad66c", [] @@ -388511,7 +388956,7 @@ [] ], "helpers.js": [ - "efe3537e4f82926a447287f38b1d3bd434613e3f", + "56d941a3ed89382eb4d6a863444a9d57c5edccfe", [] ], "idlharness.https.window-expected.txt": [ @@ -388522,6 +388967,10 @@ "85e649bdb14202fb040d6b4538d8bd197395aa7e", [] ], + "public-key-credential-to-json.https.window.js.ini": [ + "0919b04919cb055fe9b02b4fdd7760dedaddfa0a", + [] + ], "remote-desktop-client-override.tentative.https-expected.txt": [ "3b4985b5ff8ee0d01cb22d8a6dddfb2d1d7150e6", [] @@ -389109,7 +389558,7 @@ [] ], "conftest.py": [ - "f28fb06ce2999518b6071df8d8931a9410a709b3", + "30069a02386566c6c707c83bc5281d49e82ce08f", [] ], "support": { @@ -389163,7 +389612,7 @@ [] ], "conftest.py": [ - "34c8e5de183e54415e6285359f744129ee91de92", + "8275efc23b70de3f06eb9d081d4fa2d3c13d7fc5", [] ], "support": { @@ -389172,11 +389621,7 @@ [] ], "refine.py": [ - "90f722587c3be0e4066fbb6a604668a6d40f359f", - [] - ], - "test_actions_wdspec.html": [ - "6f844cd255a075d31caf1c19957af3d6ac833778", + "d40520974938b1dd226021be40a79e1661860249", [] ] } @@ -389842,18 +390287,10 @@ "84de391397eff5f76f98b80e5988d4fc37c478f0", [] ], - "prelu.https.any-expected.txt": [ - "07469cfba321101484bad3705e3ab6d4a1e7c41a", - [] - ], "prelu.https.any.js.ini": [ "9cf6e47b28341aed6d84753a0068f943ff0ecd40", [] ], - "prelu.https.any.worker-expected.txt": [ - "88368d4a6f4b0d15bc93896bbad5eb4abc91dd49", - [] - ], "reduction.https.any-expected.txt": [ "6257e70f7946e50d223d2aa9b6fd8a936fac5432", [] @@ -464489,6 +464926,13 @@ {} ] ], + "inverted-colors.html": [ + "69672f77912fe643c7777d5f010725e30bf3660c", + [ + null, + {} + ] + ], "match-media-parsing.html": [ "c029f5494569f17f8fbe6d556de4e5b34a840fc6", [ @@ -464594,13 +465038,6 @@ {} ] ], - "scripting.html": [ - "5606b9fc6802ce98246c6a4eb13f4f90bd60aa05", - [ - null, - {} - ] - ], "test_media_queries.html": [ "20fca4affd24e5a3d1335b9d39420f653c7cd9fb", [ @@ -502162,7 +502599,7 @@ ] ], "join-leave-ad-interest-group.https.sub.window.js": [ - "32924a8d8724c203b21bbd52b26a40d15b901f1d", + "973c586ca4f1b3d35bd6c0814dc5fe3a012bbdda", [ "fledge/tentative/join-leave-ad-interest-group.https.sub.window.html", { @@ -552950,7 +553387,7 @@ ] ], "html5lib_innerHTML_webkit02.html": [ - "b321c413c21d79bf4fbe9a6369d7c257938ab971", + "ae78d7bd22dd694581d5543a6898932d680b8cfa", [ null, { @@ -553253,7 +553690,7 @@ ] ], "html5lib_template.html": [ - "5d6f4fc5dd977f795fa3a04b9057cf69d004ef31", + "90e0779fdbc5eb7e76bc145a37cb2aab5c7436d6", [ "html/syntax/parsing/html5lib_template.html?run_type=uri", { @@ -553799,7 +554236,7 @@ ] ], "html5lib_webkit01.html": [ - "4fd9f01f1ff15a81afdd228683a40af35481ba13", + "a94cdc72256535a98ae68aac2140bd355a5f7904", [ "html/syntax/parsing/html5lib_webkit01.html?run_type=uri", { @@ -553820,7 +554257,7 @@ ] ], "html5lib_webkit02.html": [ - "55ee1aad538db98a74adefdb385fe46bd8e81dea", + "5c9bf4efc868de50af3c50ac9ed964572f1545de", [ "html/syntax/parsing/html5lib_webkit02.html?run_type=uri", { @@ -562286,6 +562723,13 @@ } ] ], + "loaf-blocking-duration.html": [ + "3514d413e9eb763eb12563180437b0a9d8211cee", + [ + null, + {} + ] + ], "loaf-buffered.html": [ "1a07036b157a93f1f4c099a8cd5c0917d71424e0", [ @@ -562406,7 +562850,7 @@ ] ], "loaf-toJSON.html": [ - "f78e95da6d11e25d355d71d26bbc56bf2c967b1f", + "5b249e697245c5b9002c1a5fcbd6f456ab220005", [ null, {} @@ -565785,7 +566229,7 @@ ] ], "MediaStreamTrack-MediaElement-disabled-video-is-black.https.html": [ - "5bb168ee5449d0ea9438078d0570831232228dd7", + "f920eccdf2bcdfd330b86ce92565afe8c611d557", [ null, { @@ -571582,7 +572026,7 @@ ] ], "visibility-state-entry.tentative.html": [ - "c62b6c583f42ca97c812480a0842c15d26543a6f", + "0dbe634d25bef37fb2293cbbcd113fa33a8ddceb", [ null, { @@ -601413,6 +601857,13 @@ } ] ], + "different-initiators-2.https.html": [ + "69e84333aa4dec9f5602f299bd224c58ee13a66a", + [ + null, + {} + ] + ], "different-initiators.sub.https.html": [ "74e79323d9413da5196d7b1b57b340b205bc2099", [ @@ -607957,14 +608408,14 @@ ] ], "remove-error.tentative.https.html": [ - "e85ffd74a78d52a156f1fba88bba61a384a20cc7", + "917c3b4d022d446488ac14c45fff114e34a95c5d", [ null, {} ] ], "remove-success.tentative.https.html": [ - "ca73cbea8886aa5eb93249b97264df0c4ac1e875", + "6fd4305b4340a036ddba6084d9f6c5b929254f2e", [ null, {} @@ -609426,6 +609877,15 @@ ] ] }, + "embedded": { + "image-crossorigin.sub.html": [ + "531512ec168003a55bd687b1b8db010e161f1b0e", + [ + null, + {} + ] + ] + }, "extensibility": { "foreignObject": { "containing-block.html": [ @@ -624859,6 +625319,40 @@ } ] ], + "public-key-credential-to-json.https.window.js": [ + "339f16df838b156760711e40c0f0574452cbfb70", + [ + "webauthn/public-key-credential-to-json.https.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testharness.js" + ], + [ + "script", + "/resources/testharnessreport.js" + ], + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/resources/testdriver-vendor.js" + ], + [ + "script", + "/resources/utils.js" + ], + [ + "script", + "helpers.js" + ] + ] + } + ] + ], "remote-desktop-client-override.tentative.https.html": [ "888dca2e9c4bdc98c002107a6899f0b884690555", [
diff --git a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_basic_async.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_basic_async.tentative.https.window.js index 3a9a32de..a70ffa9 100644 --- a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_basic_async.tentative.https.window.js +++ b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_basic_async.tentative.https.window.js
@@ -18,7 +18,7 @@ const changes = await new Promise(resolve => { const observer = new PressureObserver(resolve); observer.observe('cpu'); - mockPressureService.setPressureUpdate('critical'); + mockPressureService.setPressureUpdate('cpu', 'critical'); mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); }); assert_true(changes.length === 1); @@ -34,7 +34,7 @@ const promise = observer.observe('cpu'); observer.unobserve('cpu'); - mockPressureService.setPressureUpdate('critical'); + mockPressureService.setPressureUpdate('cpu', 'critical'); mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); return promise_rejects_dom(t, 'NotSupportedError', promise); @@ -53,7 +53,7 @@ await Promise.all(observePromises); - mockPressureService.setPressureUpdate('critical'); + mockPressureService.setPressureUpdate('cpu', 'critical'); mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); return Promise.all(callbackPromises); @@ -68,10 +68,11 @@ }); t.add_cleanup(() => observer1.disconnect()); observer1.observe('cpu'); - mockPressureService.setPressureUpdate('critical'); + mockPressureService.setPressureUpdate('cpu', 'critical'); mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); }); assert_true(observer1_changes.length === 1); + assert_equals(observer1_changes[0][0].source, 'cpu'); assert_equals(observer1_changes[0][0].state, 'critical'); const observer2_changes = []; @@ -84,5 +85,6 @@ observer2.observe('cpu'); }); assert_true(observer2_changes.length === 1); + assert_equals(observer2_changes[0][0].source, 'cpu'); assert_equals(observer2_changes[0][0].state, 'critical'); }, 'Starting a new observer after an observer has started works');
diff --git a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_duplicate_updates.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_duplicate_updates.tentative.https.window.js index 3c312ca..6318c0e8 100644 --- a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_duplicate_updates.tentative.https.window.js +++ b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_duplicate_updates.tentative.https.window.js
@@ -14,13 +14,13 @@ }, {sampleRate: 5.0}); observer.observe('cpu'); const updatesDelivered = mockPressureService.updatesDelivered(); - mockPressureService.setPressureUpdate('critical'); + mockPressureService.setPressureUpdate('cpu', 'critical'); mockPressureService.startPlatformCollector(/*sampleRate*/ 5.0); // Deliver 2 updates. await t.step_wait( () => mockPressureService.updatesDelivered() >= (updatesDelivered + 2), 'Wait for more than one update to be delivered to the observer'); - mockPressureService.setPressureUpdate('nominal'); + mockPressureService.setPressureUpdate('cpu', 'nominal'); // Deliver more updates, |resolve()| will be called when the new pressure // state reaches PressureObserver and its callback is invoked // for the second time. @@ -41,14 +41,14 @@ }, {sampleRate: 5.0}); observer.observe('cpu'); const updatesDelivered = mockPressureService.updatesDelivered(); - mockPressureService.setPressureUpdate('critical', ['thermal']); + mockPressureService.setPressureUpdate('cpu', 'critical', ['thermal']); mockPressureService.startPlatformCollector(/*sampleRate*/ 5.0); // Deliver 2 updates. await t.step_wait( () => mockPressureService.updatesDelivered() >= (updatesDelivered + 2), 'Wait for more than one update to be delivered to the observer'); - mockPressureService.setPressureUpdate('critical', ['power-supply']); + mockPressureService.setPressureUpdate('cpu', 'critical', ['power-supply']); // Deliver more updates, |resolve()| will be called when the new pressure // state reaches PressureObserver and its callback is invoked // for the second time.
diff --git a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_factors.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_factors.tentative.https.window.js index 6d8d220..fc27755 100644 --- a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_factors.tentative.https.window.js +++ b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_factors.tentative.https.window.js
@@ -7,7 +7,7 @@ const changes = await new Promise(resolve => { const observer = new PressureObserver(resolve, {sampleRate: 1.0}); observer.observe('cpu'); - mockPressureService.setPressureUpdate('critical', ['thermal']); + mockPressureService.setPressureUpdate('cpu', 'critical', ['thermal']); mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); }); assert_true(changes.length === 1);
diff --git a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_timestamp.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_timestamp.tentative.https.window.js index b9b932e..aae56180 100644 --- a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_timestamp.tentative.https.window.js +++ b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_timestamp.tentative.https.window.js
@@ -21,7 +21,8 @@ // cause the actual timer used by mockPressureService to deliver readings // to be a bit slower or faster than requested. while (observerChanges.length < 4) { - mockPressureService.setPressureUpdate(readings[i++ % readings.length]); + mockPressureService.setPressureUpdate( + 'cpu', readings[i++ % readings.length]); await t.step_wait( () => mockPressureService.updatesDelivered() >= i, `At least ${i} readings have been delivered`); @@ -51,7 +52,7 @@ await new Promise(async resolve => { observer.observe('cpu'); - mockPressureService.setPressureUpdate('critical'); + mockPressureService.setPressureUpdate('cpu', 'critical'); mockPressureService.startPlatformCollector(sampleRate); await t.step_wait(() => pressureChanges.length == 1); observer.disconnect(); @@ -60,7 +61,7 @@ await new Promise(async resolve => { observer.observe('cpu'); - mockPressureService.setPressureUpdate('serious'); + mockPressureService.setPressureUpdate('cpu', 'serious'); mockPressureService.startPlatformCollector(sampleRate * 4); await t.step_wait(() => pressureChanges.length == 2); observer.disconnect();
diff --git a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_update_toJSON.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_update_toJSON.tentative.https.window.js index 7f3acf3e..f21cd464 100644 --- a/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_update_toJSON.tentative.https.window.js +++ b/third_party/blink/web_tests/external/wpt/compute-pressure/compute_pressure_update_toJSON.tentative.https.window.js
@@ -5,7 +5,7 @@ const changes = await new Promise(resolve => { const observer = new PressureObserver(resolve); observer.observe('cpu'); - mockPressureService.setPressureUpdate('critical', ['thermal']); + mockPressureService.setPressureUpdate('cpu', 'critical', ['thermal']); mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); }); assert_true(changes.length === 1);
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/clear-003.xht.ini b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/clear-003.xht.ini new file mode 100644 index 0000000..313d7a8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/clear-003.xht.ini
@@ -0,0 +1,3 @@ +[clear-003.xht] + expected: + if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-001-ref.html b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-001-ref.html new file mode 100644 index 0000000..742b306 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-001-ref.html
@@ -0,0 +1,7 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="author" name="Delan Azabani" href="mailto:dazabani@igalia.com"> +<p>Test passes if there is a green square containing a smaller black square below. +<div style="width: 2em; height: 2em; background: green;"> + <div style="width: 1em; height: 1em; background: black;"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-001.html b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-001.html new file mode 100644 index 0000000..4b208c5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-001.html
@@ -0,0 +1,12 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: ‘max-width’ and ‘max-height’ affect percentage sizes in descendants</title> +<link rel="author" name="Delan Azabani" href="mailto:dazabani@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css2/#min-max-widths"> +<link rel="help" href="https://drafts.csswg.org/css2/#min-max-heights"> +<link rel="match" href="absolute-non-replaced-max-001-ref.html"> +<meta name="assert" value="This test verifies that when the used ‘width’ and ‘height’ are affected by ‘max-width’ and ‘max-height’, the descendants are laid out with a containing block of the new size, so any percentage sizes are resolved against that new size."> +<p>Test passes if there is a green square containing a smaller black square below. +<div style="position: absolute; width: 4em; height: 4em; max-width: 2em; max-height: 2em; background: green;"> + <div style="width: 50%; height: 50%; background: black;"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-min-001.html b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-min-001.html new file mode 100644 index 0000000..0e6d1766 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-min-001.html
@@ -0,0 +1,12 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: ‘min-width’ and ‘min-height’ affect percentage sizes in descendants</title> +<link rel="author" name="Delan Azabani" href="mailto:dazabani@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css2/#min-max-widths"> +<link rel="help" href="https://drafts.csswg.org/css2/#min-max-heights"> +<link rel="match" href="absolute-non-replaced-min-max-001-ref.html"> +<meta name="assert" value="This test verifies that when the used ‘width’ and ‘height’ are affected by ‘min-width’ and ‘min-height’, the descendants are laid out with a containing block of the new size, so any percentage sizes are resolved against that new size."> +<p>Test passes if there is a green square below. +<div style="position: absolute; width: 0; height: 0; min-width: 1em; min-height: 1em; background: black;"> + <div style="width: 100%; height: 100%; background: green;"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-min-max-001-ref.html b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-min-max-001-ref.html new file mode 100644 index 0000000..3bbba2b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-min-max-001-ref.html
@@ -0,0 +1,5 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="author" name="Delan Azabani" href="mailto:dazabani@igalia.com"> +<p>Test passes if there is a green square below. +<div style="width: 1em; height: 1em; background: green;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-min-max-001.html b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-min-max-001.html new file mode 100644 index 0000000..2e240b75 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/positioning/absolute-non-replaced-min-max-001.html
@@ -0,0 +1,10 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: ‘min-width’ and ‘min-height’ take precedence over ‘max-width’ and ‘max-height’ when contradictory</title> +<link rel="author" name="Delan Azabani" href="mailto:dazabani@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css2/#min-max-widths"> +<link rel="help" href="https://drafts.csswg.org/css2/#min-max-heights"> +<link rel="match" href="absolute-non-replaced-min-max-001-ref.html"> +<meta name="assert" value="This test verifies that when ‘min-width’ is greater than ‘max-width’, or ‘min-height’ is greater than ‘max-height’, the minimums take precedence, because the steps that recalculate sizes and margins for the minimums (step 3) come after the steps for the maximums (step 2)."> +<p>Test passes if there is a green square below. +<div style="position: absolute; width: 0; height: 0; min-width: 1em; min-height: 1em; max-width: 0; max-height: 0; background: green;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-animation.html.ini b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-animation.html.ini index 31409686..b11b88b 100644 --- a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-animation.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-animation.html.ini
@@ -1,3 +1,4 @@ [mix-blend-mode-animation.html] expected: + if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/display-none-dont-cancel.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/display-none-dont-cancel.tentative.html new file mode 100644 index 0000000..6ae1158 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/display-none-dont-cancel.tentative.html
@@ -0,0 +1,146 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://drafts.csswg.org/css-display-4/#display-animation"> +<link rel=help href="https://github.com/w3c/csswg-drafts/issues/6429"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/css-animations/support/testcommon.js"></script> + +<div id=target1>hello</div> +<style> +@keyframes display1 { + 0% { display: none; } + 100% { display: inline; } +} +.animate1 { + animation: display1 1s infinite; +} +</style> +<script> +promise_test(async () => { + let numAnimationstartFired = 0; + target1.addEventListener('animationstart', () => numAnimationstartFired++); + + await waitForAnimationFrames(1); + target1.classList.add('animate1'); + await waitForAnimationFrames(2); + + assert_equals(getComputedStyle(target1).display, 'inline', + 'The display should be inline during the animation.'); + assert_equals(numAnimationstartFired, 1, + 'Only one animation should start.'); +}, 'display:none animating to display:inline should be inline for the whole animation.'); +</script> + +<div id=target2>hello</div> +<style> +@keyframes display2 { + 0% { display: var(--none-value); } + 100% { display: inline; } +} +.animate2 { + animation: display2 1s infinite; +} +#target2 { + --none-value: none; +} +</style> +<script> +promise_test(async () => { + let numAnimationstartFired = 0; + target2.addEventListener('animationstart', () => numAnimationstartFired++); + + await waitForAnimationFrames(1); + target2.classList.add('animate2'); + await waitForAnimationFrames(2); + + assert_equals(getComputedStyle(target2).display, 'inline', + 'The display should be inline during the animation.'); + assert_equals(numAnimationstartFired, 1, + 'Only one animation should start.'); +}, 'A CSS variable of display:none animating to display:inline should be inline for the whole animation.'); +</script> + +<div id=target3>hello</div> +<style> +@keyframes display3 { + 0% { display: none; } + 100% { display: none; } +} +.animate3 { + animation: display3 1s infinite; +} +</style> +<script> +promise_test(async () => { + let numAnimationstartFired = 0; + target3.addEventListener('animationstart', () => numAnimationstartFired++); + + await waitForAnimationFrames(1); + target3.classList.add('animate3'); + await waitForAnimationFrames(2); + + assert_equals(getComputedStyle(target3).display, 'none', + 'The display should be none and the animation should keep running.'); + assert_equals(numAnimationstartFired, 1, + 'Only one animation should start.'); +}, 'Animating from display:none to display:none should not cancel the animation.'); +</script> + +<div id=target4>hello</div> +<style> +@keyframes display4 { + 0% { display: var(--none-value); } + 100% { display: var(--none-value); } +} +.animate4 { + animation: display4 1s infinite; +} +#target4 { + --none-value: none; +} +</style> +<script> +promise_test(async () => { + let numAnimationstartFired = 0; + target4.addEventListener('animationstart', () => numAnimationstartFired++); + + await waitForAnimationFrames(1); + target4.classList.add('animate4'); + await waitForAnimationFrames(2); + + assert_equals(getComputedStyle(target4).display, 'none', + 'The display should be none and the animation should keep running.'); + assert_equals(numAnimationstartFired, 1, + 'Only one animation should start.'); +}, 'Animating from display:none to display:none with an intermediate variable should not cancel the animation.'); +</script> + +<div id=target5>hello</div> +<style> +@keyframes display5 { + 0% { --display: none; } + 100% { --display: none; } +} +.animate5 { + animation: display5 1s infinite; +} +#target5 { + display: var(--display, block); +} +</style> +<script> +promise_test(async () => { + let numAnimationstartFired = 0; + target5.addEventListener('animationstart', () => numAnimationstartFired++); + + await waitForAnimationFrames(1); + target5.classList.add('animate5'); + await waitForAnimationFrames(2); + + assert_equals(getComputedStyle(target5).display, 'none', + 'The display should be none and the animation should keep running.'); + assert_equals(numAnimationstartFired, 1, + 'Only one animation should start.'); +}, 'Animating a variable of "none" which gets set to display elsewhere should not cancel the animation.'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-multi-line.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-multi-line.html index e85a4f9..88ad111 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-multi-line.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-multi-line.html
@@ -21,7 +21,7 @@ <link rel="help" href="https://drafts.csswg.org/css-backgrounds-4/#valdef-background-clip-text"> <link rel="match" href="clip-text-multi-line-ref.html"> <link rel="stylesheet" href="/fonts/ahem.css"> - + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-5846" /> <style> div {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-gradient-subpixel-fills-area.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-gradient-subpixel-fills-area.html index 2a30506..78d4c99 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-gradient-subpixel-fills-area.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-gradient-subpixel-fills-area.html
@@ -5,7 +5,7 @@ <link rel="author" title="schenney" href="mailto:schenney@chromium.org"> <link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-background-origin"> <link rel="match" href="reference/background-gradient-subpixel-fills-area-ref.html"> - <meta name="fuzzy" content="maxDifference=0-1;totalPixels=6800"> + <meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-6800"> <style> ul { width: 396.875px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-image-none-gradient-repaint.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-image-none-gradient-repaint.html index 3f39fb8..1ddca5e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-image-none-gradient-repaint.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-image-none-gradient-repaint.html
@@ -5,6 +5,7 @@ <link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org"> <link rel="match" href="background-clip-color-repaint-ref.html"> <link rel="help" href="https://drafts.csswg.org/css-backgrounds/#layering"> +<meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-9693" /> <style> #box { width: 150px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1b.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1b.html index b3e1e968..831666ef 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1b.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1b.html
@@ -8,6 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-round-1-ref.html"> <meta name="assert" content="Test checks whether background-repeat: 'round round' works correctly or not."> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-12" /> <style type="text/css"> .outer { width: 72px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1d.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1d.html index 69045cf..7b7d426 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1d.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1d.html
@@ -8,6 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-round-1-ref.html"> <meta name="assert" content="Test checks whether background-repeat: 'round repeat' works correctly or not."> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-12" /> <style type="text/css"> .outer { width: 72px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1e.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1e.html index 5fd4973..9fbf786 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1e.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-1e.html
@@ -8,6 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-round-1-ref.html"> <meta name="assert" content="Test checks whether background-repeat: 'repeat round' works correctly or not."> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-12" /> <style type="text/css"> .outer { width: 72px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-2.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-2.html index 702931a..a49224cc 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-2.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-2.html
@@ -8,6 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-round-2-ref.html"> <meta name="assert" content="Test checks whether background-repeat: 'round no-repeat' works correctly or not."> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-9" /> <style type="text/css"> .outer { width: 72px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-3.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-3.html index c3b5e2b..e7d6f45 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-3.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-round-3.html
@@ -8,6 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-round-3-ref.html"> <meta name="assert" content="Test checks whether background-repeat: 'no-repeat round' works correctly or not."> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-9" /> <style type="text/css"> .outer { width: 72px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-4.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-4.html index 36f92c0..c3b35d6a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-4.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-4.html
@@ -8,7 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-space-4-ref.html"> <meta name="assert" content="Test checks whether background-repeat: 'repeat space' works correctly or not."> - <meta name="fuzzy" content="maxDifference=0-52; totalPixels=0-7905"> + <meta name="fuzzy" content="maxDifference=0-52; totalPixels=0-7908"> <style type="text/css"> .outer { width: 96px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-5.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-5.html index 7b499a7..5594efb3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-5.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-5.html
@@ -8,7 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-space-5-ref.html"> <meta name="assert" content="Test checks whether background-repeat: 'space repeat' works correctly or not."> - <meta name="fuzzy" content="maxDifference=0-52; totalPixels=0-7950"> + <meta name="fuzzy" content="maxDifference=0-52; totalPixels=0-7960"> <style type="text/css"> .outer { width: 106px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-6.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-6.html index 80728ca4..8d372dd 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-6.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-6.html
@@ -8,7 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-space-6-ref.html"> <meta name="assert" content="Test checks whether background-repeat: 'round space' works correctly or not."> - <meta name="fuzzy" content="maxDifference=0-48; totalPixels=0-15780"> + <meta name="fuzzy" content="maxDifference=0-64; totalPixels=0-15894"> <style type="text/css"> .outer { width: 192px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-7.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-7.html index c8b8731..d52f76fe 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-7.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-7.html
@@ -8,7 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-space-7-ref.html"> <meta name="assert" content="Test checks whether background-repeat: 'space round' works correctly or not."> - <meta name="fuzzy" content="maxDifference=0-48; totalPixels=0-15878"> + <meta name="fuzzy" content="maxDifference=0-64; totalPixels=0-15878"> <style type="text/css"> .outer { width: 106px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-8.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-8.html index 97a2d654..17beb1c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-8.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat-space-8.html
@@ -7,7 +7,7 @@ <link rel="author" title="Mozilla" href="https://www.mozilla.org"> <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="background-repeat-space-8-ref.html"> - <meta name="fuzzy" content="maxDifference=0-48; totalPixels=0-15880" /> + <meta name="fuzzy" content="maxDifference=0-80; totalPixels=0-15880" /> <meta name="assert" content="Test checks whether background-repeat: 'space' works correctly or not."> <style type="text/css"> .outer {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-repeat.xht b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-repeat.xht index 00d428f6..d102e80 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-repeat.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-repeat.xht
@@ -8,6 +8,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/colors.html#propdef-background-repeat" /> <link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-repeat" /> <meta name="flags" content="image" /> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-5" /> <meta name="assert" content="The image is placed once in the background positioning area and not repeated in any direction." /> <style type="text/css"> <![CDATA[
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-rounded-image-clip.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-rounded-image-clip.html index f492b2b..e6222190 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-rounded-image-clip.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-rounded-image-clip.html
@@ -1,7 +1,7 @@ <!DOCTYPE html> <meta charset="utf-8"> <title>Background Clip Follows Rounded Corner</title> -<meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-18461"> +<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-22547"> <link rel="match" href="reference/background-rounded-image-clip.html"> <link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#corner-clipping"> <style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-025.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-025.html index 8b6fed3f..fb5437f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-025.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-025.html
@@ -11,6 +11,7 @@ <meta name="flags" content="image"> <meta name="assert" content="Check if 'background-size' is 'auto 61px' and 'background-repeat' is 'round', then the height of the corresponding background image is rounded (70px in this test) so that it fits a whole number of times (3 in this test) in the background positioning area, and the width of the background image is rescaled (70px in this test) to keep the original aspect ratio."> + <meta name="fuzzy" content="maxDifference=0-70; totalPixels=0-7294"> <style> div { background-color: red;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-028.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-028.html index 0326506f..20efb4e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-028.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-028.html
@@ -10,7 +10,7 @@ <meta name="flags" content="image"> <meta name="assert" content="Check if 'background-size' is '50px' and 'background-repeat' is 'repeat', then the background image is shown with a width of 50px and its height is resolved by using the image's intrinsic ratio (in this test, the image's intrinsic ratio is 1:1) and (multiplied by) the size of the other dimension, and then it is repeated in both directions."> - <meta name="fuzzy" content="maxDifference=1; totalPixels=0-5056"> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-5056"> <style> div { background-color: red;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-029.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-029.html index 0d4c5bc..29df689 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-029.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-029.html
@@ -11,7 +11,7 @@ <meta name="flags" content="image"> <meta name="assert" content="Check if 'background-size' is '52px auto' and 'background-repeat' is 'round repeat', then the width is first rescaled to from 100px to 52px and then rescaled to 60px due to 'round' and the height of the corresponding background image is rescaled from 100px to 60px (to keep the original image aspect ratio) and then repeated vertically."> - <meta name="fuzzy" content="maxDifference=0-91; totalPixels=0-5283"> + <meta name="fuzzy" content="maxDifference=0-91; totalPixels=0-5292"> <style> div { background-color: red;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size/background-size-cover-svg.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size/background-size-cover-svg.html index 091600a..67f3bca 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size/background-size-cover-svg.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size/background-size-cover-svg.html
@@ -1,11 +1,11 @@ -<!DOCTYPE html> +<!DOCTYPE html> <html> <head> <title>CSS Background Test: A SVG background should fully cover the positioning area</title> <link rel="author" title="schenney" href="mailto:schenney@chromium.org"> <link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-background-size"> <link rel="match" href="reference/background-size-cover-svg-ref.html"> - <meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-1200"> + <meta name="fuzzy" content="maxDifference=0-2;totalPixels=0-1200"> <style> div { height: 400px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size/vector/diagonal-percentage-vector-background.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size/vector/diagonal-percentage-vector-background.html index a794e46..75c8fd46 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size/vector/diagonal-percentage-vector-background.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size/vector/diagonal-percentage-vector-background.html
@@ -23,6 +23,7 @@ <link rel="match" href="reference/diagonal-percentage-vector-background-ref.html"> <meta name="flags" content="svg"> + <meta name="fuzzy" content="maxDifference=0-5; totalPixels=0-360" /> <style type="text/css"> div
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/bg-color-with-gradient.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/bg-color-with-gradient.html index 7ef5d61..be08fa5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/bg-color-with-gradient.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/bg-color-with-gradient.html
@@ -1,4 +1,5 @@ <!DOCTYPE html> <link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#background-color"> <link rel="match" href="bg-color-with-gradient-ref.html"> +<meta name="fuzzy" content="maxDifference=0-3; totalPixels=0-6909" /> <div style="width: 100px; height: 100px; background: linear-gradient(red, black); background-color: green;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-left-radius-005.xht b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-left-radius-005.xht index cc9fee1..bceaa3d9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-left-radius-005.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-left-radius-005.xht
@@ -3,6 +3,7 @@ <title>border-bottom-left-radius using two percentages</title> <link rel="match" href="border-bottom-left-radius-005-ref.xht" /> <link rel="help" href="https://drafts.csswg.org/css-backgrounds/#border-radius" /> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-1" /> <style type="text/css"> div {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-right-radius-004.xht b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-right-radius-004.xht index 24b7cd9..2af4de7b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-right-radius-004.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-right-radius-004.xht
@@ -3,7 +3,7 @@ <title>border-bottom-right-radius using one percentage</title> <link rel="match" href="border-bottom-right-radius-004-ref.xht" /> <link rel="help" href="https://drafts.csswg.org/css-backgrounds/#border-radius" /> - <meta name="fuzzy" content="maxDifference=1; totalPixels=0-1" /> + <meta name="fuzzy" content="maxDifference=0-73; totalPixels=0-127" /> <style type="text/css"> div {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-right-radius-005.xht b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-right-radius-005.xht index 89912542..f53ae0d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-right-radius-005.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-bottom-right-radius-005.xht
@@ -3,6 +3,7 @@ <title>border-bottom-right-radius using two percentages</title> <link rel="match" href="border-bottom-right-radius-005-ref.xht" /> <link rel="help" href="https://drafts.csswg.org/css-backgrounds/#border-radius" /> + <meta name="fuzzy" content="maxDifference=0-36; totalPixels=0-131" /> <style type="text/css"> div {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round-2.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round-2.html index 8e5ae553..89f8dc0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round-2.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round-2.html
@@ -8,7 +8,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#background-repeat"> <link rel="match" href="border-image-repeat-round-2-ref.html"> <meta name="assert" content="The test checks whether border-image-repeat: 'round' uses the correct rounding formula."> - <meta name="fuzzy" content="maxDifference=0-55; totalPixels=0-376"> + <meta name="fuzzy" content="maxDifference=0-55; totalPixels=0-380"> <style type="text/css"> .outer { position: absolute;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round.html index 5171eef..cf87e8d1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-round.html
@@ -6,7 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/css3-background/#border-images"> <link rel="match" href="reference/border-image-repeat-round-ref.html"> <meta name="assert" content="diamonds in corners should be red, and other diamonds should be orange, it should be 4 orange diamonds on each side."> - <meta name="fuzzy" content="maxDifference=0-92;totalPixels=0-3435"> + <meta name="fuzzy" content="maxDifference=0-111;totalPixels=0-3435"> <style type="text/css"> .container { border: double red 1em;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-space-10.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-space-10.html index 306a913..73423ef 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-space-10.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-space-10.html
@@ -4,7 +4,7 @@ <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="help" href="https://www.w3.org/TR/css3-background/#the-border-image-repeat"> <link rel="match" href="border-image-repeat-space-10-ref.html"> -<meta name="fuzzy" content="maxDifference=0-80;totalPixels=0-1472"> +<meta name="fuzzy" content="maxDifference=0-163;totalPixels=0-2400"> <meta name="assert" content="Check that 'border-image-repeat:space' renders as expected by comparing to something not using 'border-image-repeat:space'."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-space-8.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-space-8.html index 6f577e8..0edfba9e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-space-8.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-repeat-space-8.html
@@ -5,6 +5,7 @@ <link rel="help" href="https://www.w3.org/TR/css3-background/#the-border-image-repeat"> <link rel="match" href="border-image-repeat-space-8-ref.html"> <meta name="assert" content="An explicit 'border-image-width' which is exactly the same size as 'border-width' should render the same as 'border-image-width:1' (the initial value)."> +<meta name="fuzzy" content="maxDifference=0-110; totalPixels=0-10540" /> <style> div {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-round-and-stretch.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-round-and-stretch.html index 73909c1..a9b4da70 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-round-and-stretch.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-round-and-stretch.html
@@ -6,7 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/css3-background/#border-images"> <link rel="match" href="reference/border-image-round-and-stretch-ref.html"> <meta name="assert" content="orange diamonds on top and bottom border should be repeated 12 times, and orange diamonds on left and right border should be stretched, diamonds in corners should be red, and other diamonds should be orange."> - <meta name="fuzzy" content="maxDifference=0-66;totalPixels=0-4781"> + <meta name="fuzzy" content="maxDifference=0-163;totalPixels=0-6375"> <style type="text/css"> .container { border: double red 1em;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-001.html index 4a2c3e9..b6eb589 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-001.html
@@ -18,6 +18,7 @@ <meta content="" name="flags"> <meta content="This test checks the rendering process of selecting the middle part of the border-image to be preserved. Since 'border-image-slice' is '50', then the 8 surrounding areas of the border-image area are selecting the white areas of the border-image. The middle part must be filled with red and green area. In which case, only the horizontal center and the vertical center of the border-image must fill the middle area. Therefore, only the green 100x100 area of the border-image must be painted into the middle area." name="assert"> + <meta name="fuzzy" content="maxDifference=0-112; totalPixels=0-199" /> <style> div#test
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-002.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-002.html index bc194e40..26e4047 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-002.html
@@ -18,6 +18,7 @@ <meta content="" name="flags"> <meta content="This test checks the rendering process of selecting the middle part of the border-image to be preserved. Since 'border-image-slice' is '0', then the whole border-image is its own middle part. In which case, the horizontal center and the vertical center of the border-image must fill the middle area. The 8 other areas of the border belt in this test are not painted and must become transparent." name="assert"> + <meta name="fuzzy" content="maxDifference=0-112; totalPixels=0-199" /> <style> div#test
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-003.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-003.html index fd0833f..05e37c1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-fill-003.html
@@ -18,6 +18,7 @@ <meta content="" name="flags"> <meta content="This test checks the rendering process of selecting the middle part of the border-image to be preserved. Since 'border-image-slice' is '100', then the 8 surrounding areas of the border-image area are selecting the white areas of the border-image and 50px of (and into) the red area. The middle part must be filled with red and green area. In which case, only the horizontal center and the vertical center of the border-image must fill the middle area. Therefore, only the green 100x100 area of the border-image must be painted into the middle area. This test also checks that since the border-style is 'none', then the computed value of 'border-width' must be 0px. Therefore the border belt of the div can not be painted with the 8 sliced border-image areas. So, we should see no red in this test." name="assert"> + <meta name="fuzzy" content="maxDifference=0-112; totalPixels=0-199" /> <style> div
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-percentage.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-percentage.html index d4d2bdb..f53501c9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-percentage.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-slice-percentage.html
@@ -6,7 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/css3-background/#border-images"> <link rel="match" href="reference/border-image-repeat-round-ref.html"> <meta name="assert" content="diamonds in corners should be red, and other diamonds should be orange, it should be 4 orange diamonds on each side."> - <meta name="fuzzy" content="maxDifference=0-92;totalPixels=0-3435"> + <meta name="fuzzy" content="maxDifference=0-164; totalPixels=0-3716"> <style type="text/css"> .container { border: double red 1em;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-space-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-space-001.html index 8e04127..720f0df 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-space-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-space-001.html
@@ -6,7 +6,7 @@ <link rel="author" title="Levi Weintraub" href="mailto:leviw@chromium.org"> <link rel="help" href="http://www.w3.org/TR/css3-background/#the-border-image-repeat"> <meta name="assert" content="border-image-repeat: space property spaces out background image that doesn't fit an even number of times."> - <meta name="fuzzy" content="maxDifference=0-80;totalPixels=0-1728"> + <meta name="fuzzy" content="maxDifference=0-80; totalPixels=0-1728"> <link rel="match" href="reference/border-image-space-001-ref.html"> <style> .borderContainer {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-width-008.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-width-008.html index 3158cdb..20775ae 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-width-008.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-width-008.html
@@ -3,6 +3,7 @@ <title>border-image-width has the same effect as a border-width and the image is displayed even if border-width is zero</title> <link rel="match" href="border-image-width-008-ref.html"> <link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#propdef-border-image-width"> +<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-74" /> <style> #test { width: 400px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001.html index e7d173b..b2187cf0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-radius-clipping-with-transform-001.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#corner-clipping"> <link rel="match" href="border-radius-clipping-with-transform-001-ref.html"> <meta name="assert" content="The content should be clipped correctly, despite the interesting transforms."> +<meta name="fuzzy" content="maxDifference=0-48; totalPixels=0-6783" /> <style> #outer {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-left-radius-005.xht b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-left-radius-005.xht index 37af580..68fd36d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-left-radius-005.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-left-radius-005.xht
@@ -3,6 +3,7 @@ <title>border-top-left-radius using two percentages</title> <link rel="match" href="border-top-left-radius-005-ref.xht" /> <link rel="help" href="https://drafts.csswg.org/css-backgrounds/#border-radius" /> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-1" /> <style type="text/css"> div {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-right-radius-004.xht b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-right-radius-004.xht index 2d1f95c..3068a24 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-right-radius-004.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-right-radius-004.xht
@@ -3,7 +3,7 @@ <title>border-top-right-radius using one percentage</title> <link rel="match" href="border-top-right-radius-004-ref.xht" /> <link rel="help" href="https://drafts.csswg.org/css-backgrounds/#border-radius" /> - <meta name="fuzzy" content="maxDifference=1; totalPixels=0-1" /> + <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-2" /> <style type="text/css"> div {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-right-radius-005.xht b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-right-radius-005.xht index 8bd3965..46004d6f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-right-radius-005.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-top-right-radius-005.xht
@@ -3,6 +3,7 @@ <title>border-top-right-radius using two percentages</title> <link rel="match" href="border-top-right-radius-005-ref.xht" /> <link rel="help" href="https://drafts.csswg.org/css-backgrounds/#border-radius" /> + <meta name="fuzzy" content="maxDifference=0-36; totalPixels=0-131" /> <style type="text/css"> div {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/css-border-radius-001.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/css-border-radius-001.html index 023f7d18..8b0e2e9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/css-border-radius-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/css-border-radius-001.html
@@ -6,7 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/css3-background/#the-border-radius"> <link rel="match" href="reference/css-border-radius-001-ref.html"> <!-- Allow differences of antialised pixels along rounded edges --> - <meta name="fuzzy" content="maxDifference=0-63; totalPixels=0-400"> + <meta name="fuzzy" content="maxDifference=0-116; totalPixels=0-8035"> <style type="text/css"> .blueSquare{ position: absolute;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/linear-gradient-currentcolor-first-line.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/linear-gradient-currentcolor-first-line.html index 737618f..7c8f8a8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/linear-gradient-currentcolor-first-line.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/linear-gradient-currentcolor-first-line.html
@@ -3,7 +3,7 @@ <link rel="help" href="https://drafts.csswg.org/css-backgrounds/#first-line-background"> <link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-line-inheritance"> <link rel="match" href="linear-gradient-currentcolor-first-line-ref.html"> -<meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-244"> +<meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-265"> <style> div { color: red; } div::first-line { color: green; }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/reference/system-color-hightlights-vs-getSelection-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-color/reference/system-color-hightlights-vs-getSelection-001-ref.html new file mode 100644 index 0000000..1792869 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color/reference/system-color-hightlights-vs-getSelection-001-ref.html
@@ -0,0 +1,52 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Reference Test</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + + <style> + div , table + { + font-size: 40px; + line-height: 1; + } + + /* + https://www.w3.org/TR/css-pseudo-4/#highlight-bounds + For text, the corresponding overlay must cover at least + the entire em box and may extend further above/below the + em box to the line box edges. + */ + + span + { + background-color: Highlight; + color: HighlightText; + } + + table + { + border-spacing: 0px; + margin: 0px; + width: 100%; + } + + td + { + padding: 0px; + } + </style> + + <div><span>With system-color-highlight</span></div> + + <div><span>With getSelection()</span><br></div> + + <div><span>With getSelection()</span></div> + + <table> + <tr> + <td><span style="white-space: nowrap;">With system-color-highlight</span></td><td style="background-color: yellow; width: 100%;"></td> + </tr> + </table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/system-color-hightlights-vs-getSelection-001.html b/third_party/blink/web_tests/external/wpt/css/css-color/system-color-hightlights-vs-getSelection-001.html new file mode 100644 index 0000000..7223ecdc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color/system-color-hightlights-vs-getSelection-001.html
@@ -0,0 +1,91 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Color Test: system color highlights values versus getSelection().addRange(targetRange)</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-color-4/#css-system-colors"> + <link rel="help" href="https://www.w3.org/TR/css-pseudo-4/#highlight-styling"> + <link rel="match" href="reference/system-color-hightlights-vs-getSelection-001-ref.html"> + + <!-- + + Created: March 29th 2023 + + Last modified: April 9th 2023 + + Chromium bug report 932343 comment #c20: Issue 932343: Support text decoration properties in ::selection + https://bugs.chromium.org/p/chromium/issues/detail?id=932343#c20 + + Chromium bug report 1429019: Issue 1429019: [CSS4 Color] [CSS4 Pseudo] getSelection() color and background color should match system color highlights + https://bugs.chromium.org/p/chromium/issues/detail?id=1429019 + + WebKit Bug report 254691: [CSS4 Color] [CSS4 Pseudo] getSelection() color and background color should match system color highlights + https://bugs.webkit.org/show_bug.cgi?id=254691 + + --> + + <meta content="" name="flags"> + <meta content="This test checks that color and background color generated by window.getSelection().addRange(targetRange) correspond to system color highlights values. This must be true even if there is a non-transparent background color behind the tested range of text." name="assert"> + + <style> + div + { + font-size: 40px; + line-height: 1; + } + + /* + https://www.w3.org/TR/css-pseudo-4/#highlight-bounds + For text, the corresponding overlay must cover at least + the entire em box and may extend further above/below the + em box to the line box edges. + */ + + span.system-color-highlight + { + background-color: Highlight; + color: HighlightText; + } + + /* + + Highlight + Background of item(s) selected in a control. + https://www.w3.org/TR/css-color-4/#valdef-system-color-highlight + + HighlightText + Text of item(s) selected in a control. + https://www.w3.org/TR/css-color-4/#valdef-system-color-highlighttext + + CSS4 Color Module + 5.2 System Colors + https://www.w3.org/TR/css-color-4/#css-system-colors + + */ + </style> + + <script type="text/javascript"> + function startTest() + { + /* We first create an empty range */ + var targetRange = document.createRange(); + + /* Then we select the node */ + targetRange.selectNode(document.getElementById("getSelection")); + + /* Finally, we now select such range of content */ + window.getSelection().addRange(targetRange); + } + + </script> + + <body onload="startTest();"> + + <div><span class="system-color-highlight">With system-color-highlight</span></div> + + <div id="getSelection">With getSelection()<br> + <span style="background-color: yellow;">With getSelection()</span></div> + + <div style="background-color: yellow;"><span class="system-color-highlight">With system-color-highlight</span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/system-color-hightlights-vs-getSelection-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-color/system-color-hightlights-vs-getSelection-001.html.ini new file mode 100644 index 0000000..be504915 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color/system-color-hightlights-vs-getSelection-001.html.ini
@@ -0,0 +1,2 @@ +[system-color-hightlights-vs-getSelection-001.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-font-loading/fontfaceset-worker-fontface-crash.html b/third_party/blink/web_tests/external/wpt/css/css-font-loading/fontfaceset-worker-fontface-crash.html new file mode 100644 index 0000000..11f7e1fa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-font-loading/fontfaceset-worker-fontface-crash.html
@@ -0,0 +1,32 @@ +<!doctype html> +<html class="test-wait"> +<iframe id="frame" srcdoc=""></iframe> +<script id="worker1" type="javascript/worker"> +self.onmessage = async function(e) { + let a = new MessageEvent('message') + for (let e = 0; e < 255; e++) { + new Uint8ClampedArray(2048).fill(e) + } + try { self.dispatchEvent(a) } catch (e) {} + let x = new FontFace('foo', 'x') +} +</script> +<script> +function tick() { + return new Promise(r => { + requestAnimationFrame(() => requestAnimationFrame(r)); + }); +} +onload = async () => { + let win = document.querySelector("#frame").contentWindow; + const blob = new win.Blob([document.querySelector('#worker1').textContent], { type: "text/javascript" }) + let worker = new win.Worker(win.URL.createObjectURL(blob)) + worker.postMessage([], []) + await tick(); + await tick(); + win.location.reload(true) + await tick(); + document.documentElement.className = ""; +}; +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/object-view-box-fit-cover-canvas.html.ini b/third_party/blink/web_tests/external/wpt/css/css-images/object-view-box-fit-cover-canvas.html.ini new file mode 100644 index 0000000..699d95d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-images/object-view-box-fit-cover-canvas.html.ini
@@ -0,0 +1,3 @@ +[object-view-box-fit-cover-canvas.html] + expected: + if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/object-view-box-fit-fill-canvas.html.ini b/third_party/blink/web_tests/external/wpt/css/css-images/object-view-box-fit-fill-canvas.html.ini new file mode 100644 index 0000000..2f9f1a53c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-images/object-view-box-fit-fill-canvas.html.ini
@@ -0,0 +1,3 @@ +[object-view-box-fit-fill-canvas.html] + expected: + if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-reset-border-block-end-color-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-reset-border-block-end-color-001.html.ini index 439a2323..552d58c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-reset-border-block-end-color-001.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-reset-border-block-end-color-001.html.ini
@@ -1,3 +1,5 @@ [kind-of-widget-fallback-input-reset-border-block-end-color-001.html] expected: - if (product == "content_shell") and (os == "mac"): FAIL + if (product == "content_shell") and (os == "linux"): PASS + if (product == "content_shell") and (os == "win"): PASS + FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-end-start-radius-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-end-start-radius-001.html.ini index b6cb6a74..0705c9db 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-end-start-radius-001.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-end-start-radius-001.html.ini
@@ -1,3 +1,4 @@ [kind-of-widget-fallback-input-search-text-border-end-start-radius-001.html] expected: + if (product == "content_shell") and (os == "win") and (port == "win11"): FAIL if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html.ini new file mode 100644 index 0000000..6f8eb451 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html.ini
@@ -0,0 +1,3 @@ +[kind-of-widget-fallback-input-search-text-border-start-end-radius-001.html] + expected: + if (product == "content_shell") and (os == "linux"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-textarea-border-right-style-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-textarea-border-right-style-001.html.ini new file mode 100644 index 0000000..fb3cbd1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-textarea-border-right-style-001.html.ini
@@ -0,0 +1,3 @@ +[kind-of-widget-fallback-textarea-border-right-style-001.html] + expected: + if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/client-props-inline-list-item.html.ini b/third_party/blink/web_tests/external/wpt/css/cssom-view/client-props-inline-list-item.html.ini new file mode 100644 index 0000000..162c187 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/client-props-inline-list-item.html.ini
@@ -0,0 +1,3 @@ +[client-props-inline-list-item.html] + [client* returns the same for non-replaced inlines regardless of list-item-ness] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/inverted-colors-expected.txt b/third_party/blink/web_tests/external/wpt/css/mediaqueries/inverted-colors-expected.txt new file mode 100644 index 0000000..907ecd3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/inverted-colors-expected.txt
@@ -0,0 +1,18 @@ +This is a testharness.js-based test. +FAIL Should be known: '(inverted-colors)' assert_true: expected true got false +FAIL Should be known: '(inverted-colors: none)' assert_true: expected true got false +FAIL Should be known: '(inverted-colors: inverted)' assert_true: expected true got false +PASS Should be parseable: '(inverted-colors: 0)' +PASS Should be unknown: '(inverted-colors: 0)' +PASS Should be parseable: '(inverted-colors: no-preference)' +PASS Should be unknown: '(inverted-colors: no-preference)' +PASS Should be parseable: '(inverted-colors: 10px)' +PASS Should be unknown: '(inverted-colors: 10px)' +PASS Should be parseable: '(inverted-colors: none inverted)' +PASS Should be unknown: '(inverted-colors: none inverted)' +PASS Should be parseable: '(inverted-colors: none/inverted)' +PASS Should be unknown: '(inverted-colors: none/inverted)' +FAIL Check that none evaluates to false in the boolean context assert_equals: expected true but got false +PASS Check that invalid evaluates to false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/inverted-colors.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/inverted-colors.html new file mode 100644 index 0000000..69672f7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/inverted-colors.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#inverted" /> +<script type="text/javascript" src="/resources/testharness.js"></script> +<script type="text/javascript" src="/resources/testharnessreport.js"></script> + +<script type="text/javascript" src="resources/matchmedia-utils.js"></script> +<script> +query_should_be_known("(inverted-colors)"); +query_should_be_known("(inverted-colors: none)"); +query_should_be_known("(inverted-colors: inverted)"); + +query_should_be_unknown("(inverted-colors: 0)"); +query_should_be_unknown("(inverted-colors: no-preference)"); +query_should_be_unknown("(inverted-colors: 10px)"); +query_should_be_unknown("(inverted-colors: none inverted)"); +query_should_be_unknown("(inverted-colors: none/inverted)"); + +test(() => { + // https://drafts.csswg.org/mediaqueries-5/#boolean-context + let booleanContext = window.matchMedia("(inverted-colors)"); + let none = window.matchMedia("(inverted-colors: none)"); + assert_equals(booleanContext.matches, !none.matches); +}, "Check that none evaluates to false in the boolean context"); + +test(() => { + let invalid = window.matchMedia("(inverted-colors: 10px)"); + assert_equals(invalid.matches, false); +}, "Check that invalid evaluates to false"); +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/inverted-colors.html.ini b/third_party/blink/web_tests/external/wpt/css/mediaqueries/inverted-colors.html.ini new file mode 100644 index 0000000..c7adba8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/inverted-colors.html.ini
@@ -0,0 +1,12 @@ +[inverted-colors.html] + [Check that none evaluates to false in the boolean context] + expected: FAIL + + [Should be known: '(inverted-colors)'] + expected: FAIL + + [Should be known: '(inverted-colors: inverted)'] + expected: FAIL + + [Should be known: '(inverted-colors: none)'] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-noscript-ref.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-noscript-ref.html deleted file mode 100644 index d0bf78f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-noscript-ref.html +++ /dev/null
@@ -1,4 +0,0 @@ -<!DOCTYPE html> -<noscript> - Script is disabled -</noscript> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-noscript.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-noscript.html deleted file mode 100644 index 701013b..0000000 --- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-noscript.html +++ /dev/null
@@ -1,13 +0,0 @@ -<!DOCTYPE html> -<link rel="help" href="https://drafts.csswg.org/mediaqueries/#scripting"> -<link rel="match" href="scripting-print-noscript-ref.html"> -<style> - @media (scripting) { - #noscript { - display: none; - } - } -</style> -<div id="noscript"> - Script is disabled -</div> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-noscript.html.ini b/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-noscript.html.ini deleted file mode 100644 index f8256a3..0000000 --- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-noscript.html.ini +++ /dev/null
@@ -1,2 +0,0 @@ -[scripting-print-noscript.html] - expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-script-ref.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-script-ref.html deleted file mode 100644 index 0e3b6fc3..0000000 --- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-script-ref.html +++ /dev/null
@@ -1,4 +0,0 @@ -<!DOCTYPE html> -<div> - Script is enabled -</div> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-script.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-script.html deleted file mode 100644 index 25f064ba..0000000 --- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-script.html +++ /dev/null
@@ -1,17 +0,0 @@ -<!DOCTYPE html> -<link rel="help" href="https://drafts.csswg.org/mediaqueries/#scripting"> -<link rel="match" href="scripting-print-script-ref.html"> -<style> - #script { - display: none; - } - - @media (scripting) { - #script { - display: block; - } - } -</style> -<div id="script"> - Script is enabled -</div> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-script.html.ini b/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-script.html.ini deleted file mode 100644 index 2143b97f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting-print-script.html.ini +++ /dev/null
@@ -1,2 +0,0 @@ -[scripting-print-script.html] - expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting.html deleted file mode 100644 index 5606b9f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting.html +++ /dev/null
@@ -1,26 +0,0 @@ -<!DOCTYPE html> -<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#scripting"> -<script type="text/javascript" src="/resources/testharness.js"></script> -<script type="text/javascript" src="/resources/testharnessreport.js"></script> -<script type="text/javascript" src="resources/matchmedia-utils.js"></script> - -<script> -query_should_be_known("(scripting)"); -query_should_be_known("(scripting: enabled)"); -query_should_be_known("(scripting: initial-only)"); -query_should_be_known("(scripting: none)"); - -query_should_be_unknown("(scripting: 0)"); -query_should_be_unknown("(scripting: 10px)"); -query_should_be_unknown("(scripting: invalid)"); - -test(() => { - let match_enabled = window.matchMedia("(scripting: enabled)"); - assert_true(match_enabled.matches); -}, "Check that scripting currently matches 'enabled'"); - -test(() => { - let booleanContext = window.matchMedia("(scripting)"); - assert_true(booleanContext.matches); -}, "Check that scripting currently evaluates to true in the boolean context"); -</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting.html.ini b/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting.html.ini deleted file mode 100644 index cfe3783..0000000 --- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/scripting.html.ini +++ /dev/null
@@ -1,18 +0,0 @@ -[scripting.html] - [Check that scripting currently evaluates to true in the boolean context] - expected: FAIL - - [Check that scripting currently matches 'enabled'] - expected: FAIL - - [Should be known: '(scripting)'] - expected: FAIL - - [Should be known: '(scripting: enabled)'] - expected: FAIL - - [Should be known: '(scripting: initial-only)'] - expected: FAIL - - [Should be known: '(scripting: none)'] - expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/popup-same-origin-unsafe-allow-outgoing-with-same-site.https.html.ini b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/popup-same-origin-unsafe-allow-outgoing-with-same-site.https.html.ini new file mode 100644 index 0000000..8eb49f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/popup-same-origin-unsafe-allow-outgoing-with-same-site.https.html.ini
@@ -0,0 +1,3 @@ +[popup-same-origin-unsafe-allow-outgoing-with-same-site.https.html] + expected: + if product == "chrome": ERROR
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02-expected.txt b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02-expected.txt index 062089f..c3f914d 100644 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02-expected.txt
@@ -1,4 +1,5 @@ This is a testharness.js-based test. +FAIL html5lib_innerHTML_webkit02.html cac5528d0cbea4d15babba38304646e3903324a6 assert_equals: expected "#document\n| <b>\n| <em>\n| <dcell>\n| <postfield>\n| <postfield>\n| <postfield>\n| <postfield>\n| <missing_glyph>\n| <missing_glyph>\n| <missing_glyph>\n| <missing_glyph>\n| <hkern>\n| <aside>\n| <b>" but got "#document\n| <b>\n| <em>\n| <dcell>\n| <postfield>\n| <postfield>\n| <postfield>\n| <postfield>\n| <missing_glyph>\n| <missing_glyph>\n| <missing_glyph>\n| <missing_glyph>\n| <hkern>\n| <aside>\n| <em>\n| <b>" FAIL html5lib_innerHTML_webkit02.html bafeef55f21b568ab89a91082464614e4ebe7c2f assert_equals: expected "#document\n| <b>\n| <em>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <aside>\n| <b>" but got "#document\n| <b>\n| <em>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <foo>\n| <aside>\n| <em>\n| <b>" FAIL html5lib_innerHTML_webkit02.html 9461cfc6d9d4f08b05b3a95bbe5baa264f868a44 assert_equals: expected "#document\n| <b>\n| <em>\n| <foo>\n| <foob>\n| <foob>\n| <foob>\n| <foob>\n| <fooc>\n| <fooc>\n| <fooc>\n| <fooc>\n| <food>\n| <aside>\n| <b>" but got "#document\n| <b>\n| <em>\n| <foo>\n| <foob>\n| <foob>\n| <foob>\n| <foob>\n| <fooc>\n| <fooc>\n| <fooc>\n| <fooc>\n| <food>\n| <aside>\n| <em>\n| <b>" PASS html5lib_innerHTML_webkit02.html c2c4647447354abc154f1917a7fbefa4a679d5fb
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02.html b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02.html index b321c41..ae78d7bd 100644 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02.html +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02.html
@@ -15,9 +15,9 @@ <script src="/resources/testharnessreport.js"></script> <script> var num_iframes = 8; - var order = ['bafeef55f21b568ab89a91082464614e4ebe7c2f','9461cfc6d9d4f08b05b3a95bbe5baa264f868a44','c2c4647447354abc154f1917a7fbefa4a679d5fb',]; + var order = ['cac5528d0cbea4d15babba38304646e3903324a6','bafeef55f21b568ab89a91082464614e4ebe7c2f','9461cfc6d9d4f08b05b3a95bbe5baa264f868a44','c2c4647447354abc154f1917a7fbefa4a679d5fb',]; var tests = { - "bafeef55f21b568ab89a91082464614e4ebe7c2f":[async_test('html5lib_innerHTML_webkit02.html bafeef55f21b568ab89a91082464614e4ebe7c2f'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E%3C/em%3E", "%23document%0A%7C%20%3Cb%3E%0A%7C%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%3Caside%3E%0A%7C%20%20%20%3Cb%3E", 'div'],"9461cfc6d9d4f08b05b3a95bbe5baa264f868a44":[async_test('html5lib_innerHTML_webkit02.html 9461cfc6d9d4f08b05b3a95bbe5baa264f868a44'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoob%3E%3Cfoob%3E%3Cfoob%3E%3Cfoob%3E%3Cfooc%3E%3Cfooc%3E%3Cfooc%3E%3Cfooc%3E%3Cfood%3E%3Caside%3E%3C/b%3E%3C/em%3E", "%23document%0A%7C%20%3Cb%3E%0A%7C%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%3Cfoob%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoob%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoob%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoob%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfooc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfooc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfooc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfooc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfood%3E%0A%7C%20%3Caside%3E%0A%7C%20%20%20%3Cb%3E", 'div'],"c2c4647447354abc154f1917a7fbefa4a679d5fb":[async_test('html5lib_innerHTML_webkit02.html c2c4647447354abc154f1917a7fbefa4a679d5fb'), "%3Coption%3E%3CXH%3Coptgroup%3E%3C/optgroup%3E", "%23document%0A%7C%20%3Coption%3E", 'select'], + "cac5528d0cbea4d15babba38304646e3903324a6":[async_test('html5lib_innerHTML_webkit02.html cac5528d0cbea4d15babba38304646e3903324a6'), "%3Cb%3E%3Cem%3E%3Cdcell%3E%3Cpostfield%3E%3Cpostfield%3E%3Cpostfield%3E%3Cpostfield%3E%3Cmissing_glyph%3E%3Cmissing_glyph%3E%3Cmissing_glyph%3E%3Cmissing_glyph%3E%3Chkern%3E%3Caside%3E%3C/b%3E%3C/em%3E", "%23document%0A%7C%20%3Cb%3E%0A%7C%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%3Cdcell%3E%0A%7C%20%20%20%20%20%20%20%3Cpostfield%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cpostfield%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cpostfield%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpostfield%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cmissing_glyph%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cmissing_glyph%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cmissing_glyph%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cmissing_glyph%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Chkern%3E%0A%7C%20%3Caside%3E%0A%7C%20%20%20%3Cb%3E", 'div'],"bafeef55f21b568ab89a91082464614e4ebe7c2f":[async_test('html5lib_innerHTML_webkit02.html bafeef55f21b568ab89a91082464614e4ebe7c2f'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E%3C/em%3E", "%23document%0A%7C%20%3Cb%3E%0A%7C%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%3Caside%3E%0A%7C%20%20%20%3Cb%3E", 'div'],"9461cfc6d9d4f08b05b3a95bbe5baa264f868a44":[async_test('html5lib_innerHTML_webkit02.html 9461cfc6d9d4f08b05b3a95bbe5baa264f868a44'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoob%3E%3Cfoob%3E%3Cfoob%3E%3Cfoob%3E%3Cfooc%3E%3Cfooc%3E%3Cfooc%3E%3Cfooc%3E%3Cfood%3E%3Caside%3E%3C/b%3E%3C/em%3E", "%23document%0A%7C%20%3Cb%3E%0A%7C%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%3Cfoob%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoob%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoob%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoob%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfooc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfooc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfooc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfooc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfood%3E%0A%7C%20%3Caside%3E%0A%7C%20%20%20%3Cb%3E", 'div'],"c2c4647447354abc154f1917a7fbefa4a679d5fb":[async_test('html5lib_innerHTML_webkit02.html c2c4647447354abc154f1917a7fbefa4a679d5fb'), "%3Coption%3E%3CXH%3Coptgroup%3E%3C/optgroup%3E", "%23document%0A%7C%20%3Coption%3E", 'select'], } init_tests("innerHTML"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02.html.ini b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02.html.ini index e4f12f0..4d14f9ca 100644 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02.html.ini +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_innerHTML_webkit02.html.ini
@@ -4,3 +4,6 @@ [html5lib_innerHTML_webkit02.html bafeef55f21b568ab89a91082464614e4ebe7c2f] expected: FAIL + + [html5lib_innerHTML_webkit02.html cac5528d0cbea4d15babba38304646e3903324a6] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_template.html b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_template.html index 5d6f4fc..90e0779f 100644 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_template.html +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_template.html
@@ -18,9 +18,9 @@ <script src="/resources/testharnessreport.js"></script> <script> var num_iframes = 8; - var order = ['010950d55f4eccf16e9c4af1d263bb747294c646','a838bd54410cef059a42eea9606356488e16535b','27fb9111f6675a7e033b867480c0afddcda161a6','aee883a65775489399a003b2371d58248a6aff6f','89b17b54ab343191bf74ef5434f4d2cfac40ea97','c4433556c7414cfd71f27b420f1ffc4348774f5e','3dcce7d97108b3e9ea7fa96f240ac62bf280e74b','a1f587f7ea85ccfe294bd45bfb501e850cb979e0','cd26a7832f13bdc135697321ca6c2fecdca6ef5d','e30571d90b0e56864499961eb7be955994cf72e2','01cbe9f6a25f286b08d8dc4f7b65421e8eb3500c','96cbbcdffe02c86a8b929604c2fd5f3571a18dbe','d51676f55550e960dd0f5fa7fd0bdfa20bdde046','f9dfd9acfd494489c899604649a01d864741f50f','ea00361c265d3ffb47ce636d919c94ca10d58911','d8ebfcf7694c9d04457e796ac73049210313602e','b4d5e6fe9b92e2c8f54199d7cab3da383c42add0','07724ef8f7a4fa61c77ffcd5180d3101c4781502','e90f8aae8fc690540b42b3ffa3e741e7c1dfbf43','687bdf4adda88a316ec69fe20e84720acc5d1fe6','5b232642f472c2b4c0c7511fed464eebe686b427','dc1ac1830a881d1532a1e6fd6d0cfa56d6571da2','c58747a85e8b4f44d7ae63c04cdad783a903c25e','ca59bfdaec7451f704973176fab46e582bd691b2','cf807d6391a58c172b6c15c3b01d2a99ec0e6cf8','350b7ac850e46de79615308fc923649264406104','a31ff44edf7f377543dabdda8141cda9bb6de134','533c5c1b5f0d0cbb1ede2cc5ae927095c5b21f0b','61f79e083005007853c4f8e431559ac8d3845cfd','e802e85f36792b176b73c102c0e8761d9478621d','51d0797ff7653cd7be34458d689146e08a666c7f','d60e4079a18bd6266740cc61d1ca736e9d5098ce','308709292677b4d74c108a811ad7b7acd0bdfc9c','8965cdf9c4e9936262e25c90c7a7f8673840a445','7dccda789764beb489e09be10188af9347335d05','e15be51c77e1a6de35568a099ed339440ce9426d','503d3782e45940c19f096f360a092282b46ab1ea','b4ab56fd9e9cebf479d14adfa523c06d16483a5e','cd8bc9521f9683086a9e8529dd97314a6869daeb','f915e7b3407c24b28c3aad318e5693cc774020f4','3c5eb261787b3d15aff86fa61de773fd7e439b0e','2b57775750c198d4b98b23aed74ff80a866a01f5','dc3d016610f3ab532525a6c2871f03d6b62b0168','6a184d71d00580a26a8b6bd97aafe5503339f3f6','ce570a6c4bcee8b72a03e25508c6dd72e3cc6c35','e0c3d922f7b1f1654f02f716c3d9b31198ce3385','87e67242bf6debcf3b7dca852d10aa0f7b625b28','35ac4d4c972a01d368ed0cacb41370efef0a644d','5226c39dfc2d624ad4191b4eacb7e40c7ae528eb','aa90cd4db6b12e0a47341914a90cc536eec32d64','48af1faf5fcf48a0854af5a5c33656d9ccf6736b','ed3a029ba5e7f59969d65a4fc490a8f13b098cb9','6c8880d54475ad9574e203dcf2e55820b123cc64','275060925a844cb51b29bae660301de9780d68c8','9f82f6ec4c0a48c1d4dfbe6803b94abd553aea88','f094bf7e94a88b86c80a0643e70c8e5ff3354698','35a07ec3b4bf26ea407dc1ddf52f14195a714059','24faa53b271f994a4ff31d5796c8ff47d6f2c3e6','0f1c491b58c2dd3c402a62e37f833bc1f1db8d21','868d918a7b5d8b5c065c15229492bc2022bfbcba','0538efa44e857596c556033a3821d424378aea3f','e7d7bf3973c70d3cf9b0adad2ebed9f25be48d66','c69d0ac542d477b7312bb24981127b8aa8fdb1df','b496a8c13a7bd75b778bb0de489726aee952ae0c','5d6ee61de40274c9626ca78ee208d51276d5662d','9bd9687a65f258adc24450fc5cbd781fff6c038a','db1baeb846d718c773324746524fbd68f2e9436e','4b0ce46c611dbcc016db272ef007f302bee0c897','1a735e1c7f28f8701f3c7fd5e9404b8911916086','0686eedec06b2db1dc283fac92c1ef1a33114c71','d4dfb87ce626f12923056a6cd77448eaf4660ac2','1f295920f2937b2c8023b3761c43a0d4d9e5353c','3b91fa08fad923d387d924cff37fbf6b4c3a5712','45a1c1ad5d99ad67c573096a79253996a664e01b','0fe3a66773c6048c8f6f2c92f2611f65be972ec1','be40897ca411e1507197c31ab2a9f9752a05f769','dcfb1048ed5c40e406b4fbf0cde24c826713907f','78263aeea68ac97903598682013bae9c0c21d547','5aa177ef1a35bf4502dcb867d8e666288982ba99','5d303375907dc4d4380b477e0317c17b660613e9','d822f726927c34b92fe102b13e63920850878f6a','07acdcaeb4fa639296d46673cf28823ddf2a6ca7','58bd846ce1be0caf7560fba2ef19e2c2070ab123','8eeee377e5ab324731cc592f1fa8abe1045ad610','b30690019090149132fc228a7261c5cf2fd149fc','67a209d928804f90fdb66d070201b23f3d0c8a42','12104886b8f87daa937eac30b5ff0e1e074eaa6f','483cc9957a7225fe435112642be59abb4c459a1e','72d8ac431a154c40ab75d53a258d9d80d47689eb','1125967cbbcd404f4cb14d48270b8ec778970d77','32c963e164b9ec82c60e490bb141c1ccc70b992f','574a95fc9c9f2de3aeaa0c9ee1e6967fc3d4770d','332863a7f9e61bff32bd3427ede7a088b790d453','2121db07146781773df9e53b94fa921a805175ce','8675de267cd7e34f2febdee3feb665614d1562fe','c5d26ad923a2b1e988ddd378ca4fb26eb48353e1','eec1542e2fa0e9eafb7f8d4a51eae56b5a31b3c8','b79387a54c3b136db0f28ed96555ff683b3947fe','c477a29a4deb32d072a415fa809a84a4f2beee0c','26e4480c08e1f5f7b6ac8b8c1832ab0312e3b7c5','24b3b50fdd0bf8d5cf2ebaa6bf502d7bcfde1da4','d3704c68528357189eb5826ab66eea071d6137a5','d958f7d44faf772d1fb60f1a8f186f837ca735d9','3fc4d97fa68fc2658356bdbd4e051c867de8de53','94820107bbf3fab3f82de1f717e8413aead7d3a6','657c00ebdda37ae060cc69633ed98482ccc29e18','649fc955a4b60ab2a5b881d94c9493eb4a545002','977041956eb9c7b9db73935168aba92f77c079f6','fafee395fea124791df59bafeb1136342b64d3c6','d5a8beecf5d3c53e947772ad887808d132334aa1',]; + var order = ['010950d55f4eccf16e9c4af1d263bb747294c646','a838bd54410cef059a42eea9606356488e16535b','27fb9111f6675a7e033b867480c0afddcda161a6','aee883a65775489399a003b2371d58248a6aff6f','89b17b54ab343191bf74ef5434f4d2cfac40ea97','c4433556c7414cfd71f27b420f1ffc4348774f5e','3dcce7d97108b3e9ea7fa96f240ac62bf280e74b','a1f587f7ea85ccfe294bd45bfb501e850cb979e0','cd26a7832f13bdc135697321ca6c2fecdca6ef5d','e30571d90b0e56864499961eb7be955994cf72e2','01cbe9f6a25f286b08d8dc4f7b65421e8eb3500c','96cbbcdffe02c86a8b929604c2fd5f3571a18dbe','d51676f55550e960dd0f5fa7fd0bdfa20bdde046','f9dfd9acfd494489c899604649a01d864741f50f','ea00361c265d3ffb47ce636d919c94ca10d58911','d8ebfcf7694c9d04457e796ac73049210313602e','b4d5e6fe9b92e2c8f54199d7cab3da383c42add0','07724ef8f7a4fa61c77ffcd5180d3101c4781502','e90f8aae8fc690540b42b3ffa3e741e7c1dfbf43','687bdf4adda88a316ec69fe20e84720acc5d1fe6','5b232642f472c2b4c0c7511fed464eebe686b427','dc1ac1830a881d1532a1e6fd6d0cfa56d6571da2','c58747a85e8b4f44d7ae63c04cdad783a903c25e','ca59bfdaec7451f704973176fab46e582bd691b2','cf807d6391a58c172b6c15c3b01d2a99ec0e6cf8','350b7ac850e46de79615308fc923649264406104','a31ff44edf7f377543dabdda8141cda9bb6de134','533c5c1b5f0d0cbb1ede2cc5ae927095c5b21f0b','61f79e083005007853c4f8e431559ac8d3845cfd','e802e85f36792b176b73c102c0e8761d9478621d','51d0797ff7653cd7be34458d689146e08a666c7f','d60e4079a18bd6266740cc61d1ca736e9d5098ce','308709292677b4d74c108a811ad7b7acd0bdfc9c','8965cdf9c4e9936262e25c90c7a7f8673840a445','7dccda789764beb489e09be10188af9347335d05','e15be51c77e1a6de35568a099ed339440ce9426d','503d3782e45940c19f096f360a092282b46ab1ea','b4ab56fd9e9cebf479d14adfa523c06d16483a5e','cd8bc9521f9683086a9e8529dd97314a6869daeb','f915e7b3407c24b28c3aad318e5693cc774020f4','3c5eb261787b3d15aff86fa61de773fd7e439b0e','2b57775750c198d4b98b23aed74ff80a866a01f5','dc3d016610f3ab532525a6c2871f03d6b62b0168','6a184d71d00580a26a8b6bd97aafe5503339f3f6','ce570a6c4bcee8b72a03e25508c6dd72e3cc6c35','e0c3d922f7b1f1654f02f716c3d9b31198ce3385','87e67242bf6debcf3b7dca852d10aa0f7b625b28','35ac4d4c972a01d368ed0cacb41370efef0a644d','5226c39dfc2d624ad4191b4eacb7e40c7ae528eb','aa90cd4db6b12e0a47341914a90cc536eec32d64','48af1faf5fcf48a0854af5a5c33656d9ccf6736b','ed3a029ba5e7f59969d65a4fc490a8f13b098cb9','6c8880d54475ad9574e203dcf2e55820b123cc64','275060925a844cb51b29bae660301de9780d68c8','9f82f6ec4c0a48c1d4dfbe6803b94abd553aea88','f094bf7e94a88b86c80a0643e70c8e5ff3354698','35a07ec3b4bf26ea407dc1ddf52f14195a714059','24faa53b271f994a4ff31d5796c8ff47d6f2c3e6','0f1c491b58c2dd3c402a62e37f833bc1f1db8d21','868d918a7b5d8b5c065c15229492bc2022bfbcba','0538efa44e857596c556033a3821d424378aea3f','e7d7bf3973c70d3cf9b0adad2ebed9f25be48d66','c69d0ac542d477b7312bb24981127b8aa8fdb1df','b496a8c13a7bd75b778bb0de489726aee952ae0c','5d6ee61de40274c9626ca78ee208d51276d5662d','9bd9687a65f258adc24450fc5cbd781fff6c038a','db1baeb846d718c773324746524fbd68f2e9436e','4b0ce46c611dbcc016db272ef007f302bee0c897','1a735e1c7f28f8701f3c7fd5e9404b8911916086','0686eedec06b2db1dc283fac92c1ef1a33114c71','d4dfb87ce626f12923056a6cd77448eaf4660ac2','1f295920f2937b2c8023b3761c43a0d4d9e5353c','3b91fa08fad923d387d924cff37fbf6b4c3a5712','45a1c1ad5d99ad67c573096a79253996a664e01b','0fe3a66773c6048c8f6f2c92f2611f65be972ec1','be40897ca411e1507197c31ab2a9f9752a05f769','dcfb1048ed5c40e406b4fbf0cde24c826713907f','78263aeea68ac97903598682013bae9c0c21d547','5aa177ef1a35bf4502dcb867d8e666288982ba99','5d303375907dc4d4380b477e0317c17b660613e9','d822f726927c34b92fe102b13e63920850878f6a','07acdcaeb4fa639296d46673cf28823ddf2a6ca7','58bd846ce1be0caf7560fba2ef19e2c2070ab123','8eeee377e5ab324731cc592f1fa8abe1045ad610','b30690019090149132fc228a7261c5cf2fd149fc','67a209d928804f90fdb66d070201b23f3d0c8a42','12104886b8f87daa937eac30b5ff0e1e074eaa6f','483cc9957a7225fe435112642be59abb4c459a1e','72d8ac431a154c40ab75d53a258d9d80d47689eb','1125967cbbcd404f4cb14d48270b8ec778970d77','32c963e164b9ec82c60e490bb141c1ccc70b992f','574a95fc9c9f2de3aeaa0c9ee1e6967fc3d4770d','332863a7f9e61bff32bd3427ede7a088b790d453','2121db07146781773df9e53b94fa921a805175ce','8675de267cd7e34f2febdee3feb665614d1562fe','c5d26ad923a2b1e988ddd378ca4fb26eb48353e1','eec1542e2fa0e9eafb7f8d4a51eae56b5a31b3c8','b79387a54c3b136db0f28ed96555ff683b3947fe','c477a29a4deb32d072a415fa809a84a4f2beee0c','26e4480c08e1f5f7b6ac8b8c1832ab0312e3b7c5','24b3b50fdd0bf8d5cf2ebaa6bf502d7bcfde1da4','d3704c68528357189eb5826ab66eea071d6137a5','d958f7d44faf772d1fb60f1a8f186f837ca735d9','3fc4d97fa68fc2658356bdbd4e051c867de8de53','94820107bbf3fab3f82de1f717e8413aead7d3a6','ed920bca1fe1f5ad471bbd81adf8a41f3e2d9b06','657c00ebdda37ae060cc69633ed98482ccc29e18','649fc955a4b60ab2a5b881d94c9493eb4a545002','977041956eb9c7b9db73935168aba92f77c079f6','fafee395fea124791df59bafeb1136342b64d3c6','d5a8beecf5d3c53e947772ad887808d132334aa1',]; var tests = { - "010950d55f4eccf16e9c4af1d263bb747294c646":[async_test('html5lib_template.html 010950d55f4eccf16e9c4af1d263bb747294c646'), "%3Cbody%3E%3Ctemplate%3EHello%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22Hello%22"],"a838bd54410cef059a42eea9606356488e16535b":[async_test('html5lib_template.html a838bd54410cef059a42eea9606356488e16535b'), "%3Ctemplate%3EHello%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22Hello%22%0A%7C%20%20%20%3Cbody%3E"],"27fb9111f6675a7e033b867480c0afddcda161a6":[async_test('html5lib_template.html 27fb9111f6675a7e033b867480c0afddcda161a6'), "%3Ctemplate%3E%3C/template%3E%3Cdiv%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E"],"aee883a65775489399a003b2371d58248a6aff6f":[async_test('html5lib_template.html aee883a65775489399a003b2371d58248a6aff6f'), "%3Chtml%3E%3Ctemplate%3EHello%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22Hello%22%0A%7C%20%20%20%3Cbody%3E"],"89b17b54ab343191bf74ef5434f4d2cfac40ea97":[async_test('html5lib_template.html 89b17b54ab343191bf74ef5434f4d2cfac40ea97'), "%3Chead%3E%3Ctemplate%3E%3Cdiv%3E%3C/div%3E%3C/template%3E%3C/head%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%3Cbody%3E"],"c4433556c7414cfd71f27b420f1ffc4348774f5e":[async_test('html5lib_template.html c4433556c7414cfd71f27b420f1ffc4348774f5e'), "%3Cdiv%3E%3Ctemplate%3E%3Cdiv%3E%3Cspan%3E%3C/template%3E%3Cb%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E"],"3dcce7d97108b3e9ea7fa96f240ac62bf280e74b":[async_test('html5lib_template.html 3dcce7d97108b3e9ea7fa96f240ac62bf280e74b'), "%3Cdiv%3E%3Ctemplate%3E%3C/div%3EHello", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22Hello%22"],"a1f587f7ea85ccfe294bd45bfb501e850cb979e0":[async_test('html5lib_template.html a1f587f7ea85ccfe294bd45bfb501e850cb979e0'), "%3Cdiv%3E%3C/template%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E"],"cd26a7832f13bdc135697321ca6c2fecdca6ef5d":[async_test('html5lib_template.html cd26a7832f13bdc135697321ca6c2fecdca6ef5d'), "%3Ctable%3E%3Ctemplate%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"e30571d90b0e56864499961eb7be955994cf72e2":[async_test('html5lib_template.html e30571d90b0e56864499961eb7be955994cf72e2'), "%3Ctable%3E%3Ctemplate%3E%3C/template%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"01cbe9f6a25f286b08d8dc4f7b65421e8eb3500c":[async_test('html5lib_template.html 01cbe9f6a25f286b08d8dc4f7b65421e8eb3500c'), "%3Ctable%3E%3Cdiv%3E%3Ctemplate%3E%3C/template%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%3Ctable%3E"],"96cbbcdffe02c86a8b929604c2fd5f3571a18dbe":[async_test('html5lib_template.html 96cbbcdffe02c86a8b929604c2fd5f3571a18dbe'), "%3Ctable%3E%3Ctemplate%3E%3C/template%3E%3Cdiv%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"d51676f55550e960dd0f5fa7fd0bdfa20bdde046":[async_test('html5lib_template.html d51676f55550e960dd0f5fa7fd0bdfa20bdde046'), "%3Ctable%3E%20%20%20%3Ctemplate%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%22%20%20%20%22%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"f9dfd9acfd494489c899604649a01d864741f50f":[async_test('html5lib_template.html f9dfd9acfd494489c899604649a01d864741f50f'), "%3Ctable%3E%3Ctbody%3E%3Ctemplate%3E%3C/template%3E%3C/tbody%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"ea00361c265d3ffb47ce636d919c94ca10d58911":[async_test('html5lib_template.html ea00361c265d3ffb47ce636d919c94ca10d58911'), "%3Ctable%3E%3Ctbody%3E%3Ctemplate%3E%3C/tbody%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"d8ebfcf7694c9d04457e796ac73049210313602e":[async_test('html5lib_template.html d8ebfcf7694c9d04457e796ac73049210313602e'), "%3Ctable%3E%3Ctbody%3E%3Ctemplate%3E%3C/template%3E%3C/tbody%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"b4d5e6fe9b92e2c8f54199d7cab3da383c42add0":[async_test('html5lib_template.html b4d5e6fe9b92e2c8f54199d7cab3da383c42add0'), "%3Ctable%3E%3Cthead%3E%3Ctemplate%3E%3C/template%3E%3C/thead%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"07724ef8f7a4fa61c77ffcd5180d3101c4781502":[async_test('html5lib_template.html 07724ef8f7a4fa61c77ffcd5180d3101c4781502'), "%3Ctable%3E%3Ctfoot%3E%3Ctemplate%3E%3C/template%3E%3C/tfoot%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctfoot%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"e90f8aae8fc690540b42b3ffa3e741e7c1dfbf43":[async_test('html5lib_template.html e90f8aae8fc690540b42b3ffa3e741e7c1dfbf43'), "%3Cselect%3E%3Ctemplate%3E%3C/template%3E%3C/select%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"687bdf4adda88a316ec69fe20e84720acc5d1fe6":[async_test('html5lib_template.html 687bdf4adda88a316ec69fe20e84720acc5d1fe6'), "%3Cselect%3E%3Ctemplate%3E%3Coption%3E%3C/option%3E%3C/template%3E%3C/select%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Coption%3E"],"5b232642f472c2b4c0c7511fed464eebe686b427":[async_test('html5lib_template.html 5b232642f472c2b4c0c7511fed464eebe686b427'), "%3Ctemplate%3E%3Coption%3E%3C/option%3E%3C/select%3E%3Coption%3E%3C/option%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%3Cbody%3E"],"dc1ac1830a881d1532a1e6fd6d0cfa56d6571da2":[async_test('html5lib_template.html dc1ac1830a881d1532a1e6fd6d0cfa56d6571da2'), "%3Cselect%3E%3Ctemplate%3E%3C/template%3E%3Coption%3E%3C/select%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%3Coption%3E"],"c58747a85e8b4f44d7ae63c04cdad783a903c25e":[async_test('html5lib_template.html c58747a85e8b4f44d7ae63c04cdad783a903c25e'), "%3Cselect%3E%3Coption%3E%3Ctemplate%3E%3C/template%3E%3C/select%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"ca59bfdaec7451f704973176fab46e582bd691b2":[async_test('html5lib_template.html ca59bfdaec7451f704973176fab46e582bd691b2'), "%3Cselect%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"cf807d6391a58c172b6c15c3b01d2a99ec0e6cf8":[async_test('html5lib_template.html cf807d6391a58c172b6c15c3b01d2a99ec0e6cf8'), "%3Cselect%3E%3Coption%3E%3C/option%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"350b7ac850e46de79615308fc923649264406104":[async_test('html5lib_template.html 350b7ac850e46de79615308fc923649264406104'), "%3Cselect%3E%3Coption%3E%3C/option%3E%3Ctemplate%3E%3Coption%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Coption%3E"],"a31ff44edf7f377543dabdda8141cda9bb6de134":[async_test('html5lib_template.html a31ff44edf7f377543dabdda8141cda9bb6de134'), "%3Ctable%3E%3Cthead%3E%3Ctemplate%3E%3Ctd%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"533c5c1b5f0d0cbb1ede2cc5ae927095c5b21f0b":[async_test('html5lib_template.html 533c5c1b5f0d0cbb1ede2cc5ae927095c5b21f0b'), "%3Ctable%3E%3Ctemplate%3E%3Cthead%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cthead%3E"],"61f79e083005007853c4f8e431559ac8d3845cfd":[async_test('html5lib_template.html 61f79e083005007853c4f8e431559ac8d3845cfd'), "%3Cbody%3E%3Ctable%3E%3Ctemplate%3E%3Ctd%3E%3C/tr%3E%3Cdiv%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"e802e85f36792b176b73c102c0e8761d9478621d":[async_test('html5lib_template.html e802e85f36792b176b73c102c0e8761d9478621d'), "%3Ctable%3E%3Ctemplate%3E%3Cthead%3E%3C/template%3E%3C/thead%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cthead%3E"],"51d0797ff7653cd7be34458d689146e08a666c7f":[async_test('html5lib_template.html 51d0797ff7653cd7be34458d689146e08a666c7f'), "%3Ctable%3E%3Cthead%3E%3Ctemplate%3E%3Ctr%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"d60e4079a18bd6266740cc61d1ca736e9d5098ce":[async_test('html5lib_template.html d60e4079a18bd6266740cc61d1ca736e9d5098ce'), "%3Ctable%3E%3Ctemplate%3E%3Ctr%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"308709292677b4d74c108a811ad7b7acd0bdfc9c":[async_test('html5lib_template.html 308709292677b4d74c108a811ad7b7acd0bdfc9c'), "%3Ctable%3E%3Ctr%3E%3Ctemplate%3E%3Ctd%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"8965cdf9c4e9936262e25c90c7a7f8673840a445":[async_test('html5lib_template.html 8965cdf9c4e9936262e25c90c7a7f8673840a445'), "%3Ctable%3E%3Ctemplate%3E%3Ctr%3E%3Ctemplate%3E%3Ctd%3E%3C/template%3E%3C/tr%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"7dccda789764beb489e09be10188af9347335d05":[async_test('html5lib_template.html 7dccda789764beb489e09be10188af9347335d05'), "%3Ctable%3E%3Ctemplate%3E%3Ctr%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3C/template%3E%3C/tr%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"e15be51c77e1a6de35568a099ed339440ce9426d":[async_test('html5lib_template.html e15be51c77e1a6de35568a099ed339440ce9426d'), "%3Ctable%3E%3Ctemplate%3E%3Ctd%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"503d3782e45940c19f096f360a092282b46ab1ea":[async_test('html5lib_template.html 503d3782e45940c19f096f360a092282b46ab1ea'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"b4ab56fd9e9cebf479d14adfa523c06d16483a5e":[async_test('html5lib_template.html b4ab56fd9e9cebf479d14adfa523c06d16483a5e'), "%3Cbody%3E%3Ctemplate%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3C/template%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"cd8bc9521f9683086a9e8529dd97314a6869daeb":[async_test('html5lib_template.html cd8bc9521f9683086a9e8529dd97314a6869daeb'), "%3Ctable%3E%3Ccolgroup%3E%3Ctemplate%3E%3Ccol%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"f915e7b3407c24b28c3aad318e5693cc774020f4":[async_test('html5lib_template.html f915e7b3407c24b28c3aad318e5693cc774020f4'), "%3Cframeset%3E%3Ctemplate%3E%3Cframe%3E%3C/frame%3E%3C/template%3E%3C/frameset%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cframeset%3E%0A%7C%20%20%20%20%20%3Cframe%3E"],"3c5eb261787b3d15aff86fa61de773fd7e439b0e":[async_test('html5lib_template.html 3c5eb261787b3d15aff86fa61de773fd7e439b0e'), "%3Ctemplate%3E%3Cframe%3E%3C/frame%3E%3C/frameset%3E%3Cframe%3E%3C/frame%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"2b57775750c198d4b98b23aed74ff80a866a01f5":[async_test('html5lib_template.html 2b57775750c198d4b98b23aed74ff80a866a01f5'), "%3Ctemplate%3E%3Cdiv%3E%3Cframeset%3E%3Cspan%3E%3C/span%3E%3C/div%3E%3Cspan%3E%3C/span%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%3Cbody%3E"],"dc3d016610f3ab532525a6c2871f03d6b62b0168":[async_test('html5lib_template.html dc3d016610f3ab532525a6c2871f03d6b62b0168'), "%3Cbody%3E%3Ctemplate%3E%3Cdiv%3E%3Cframeset%3E%3Cspan%3E%3C/span%3E%3C/div%3E%3Cspan%3E%3C/span%3E%3C/template%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cspan%3E"],"6a184d71d00580a26a8b6bd97aafe5503339f3f6":[async_test('html5lib_template.html 6a184d71d00580a26a8b6bd97aafe5503339f3f6'), "%3Cbody%3E%3Ctemplate%3E%3Cscript%3Evar%20i%20%3D%201%3B%3C/script%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cscript%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22var%20i%20%3D%201%3B%22%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"ce570a6c4bcee8b72a03e25508c6dd72e3cc6c35":[async_test('html5lib_template.html ce570a6c4bcee8b72a03e25508c6dd72e3cc6c35'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3Cdiv%3E%3C/div%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"e0c3d922f7b1f1654f02f716c3d9b31198ce3385":[async_test('html5lib_template.html e0c3d922f7b1f1654f02f716c3d9b31198ce3385'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"87e67242bf6debcf3b7dca852d10aa0f7b625b28":[async_test('html5lib_template.html 87e67242bf6debcf3b7dca852d10aa0f7b625b28'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3C/tr%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"35ac4d4c972a01d368ed0cacb41370efef0a644d":[async_test('html5lib_template.html 35ac4d4c972a01d368ed0cacb41370efef0a644d'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3Ctbody%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"5226c39dfc2d624ad4191b4eacb7e40c7ae528eb":[async_test('html5lib_template.html 5226c39dfc2d624ad4191b4eacb7e40c7ae528eb'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3Ccaption%3E%3C/caption%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"aa90cd4db6b12e0a47341914a90cc536eec32d64":[async_test('html5lib_template.html aa90cd4db6b12e0a47341914a90cc536eec32d64'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3Ccolgroup%3E%3C/caption%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"48af1faf5fcf48a0854af5a5c33656d9ccf6736b":[async_test('html5lib_template.html 48af1faf5fcf48a0854af5a5c33656d9ccf6736b'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3C/table%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"ed3a029ba5e7f59969d65a4fc490a8f13b098cb9":[async_test('html5lib_template.html ed3a029ba5e7f59969d65a4fc490a8f13b098cb9'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3Ctbody%3E%3Ctr%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"6c8880d54475ad9574e203dcf2e55820b123cc64":[async_test('html5lib_template.html 6c8880d54475ad9574e203dcf2e55820b123cc64'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3Ccaption%3E%3Ctr%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"275060925a844cb51b29bae660301de9780d68c8":[async_test('html5lib_template.html 275060925a844cb51b29bae660301de9780d68c8'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3C/table%3E%3Ctr%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"9f82f6ec4c0a48c1d4dfbe6803b94abd553aea88":[async_test('html5lib_template.html 9f82f6ec4c0a48c1d4dfbe6803b94abd553aea88'), "%3Cbody%3E%3Ctemplate%3E%3Cthead%3E%3C/thead%3E%3Ccaption%3E%3C/caption%3E%3Ctbody%3E%3C/tbody%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ccaption%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E"],"f094bf7e94a88b86c80a0643e70c8e5ff3354698":[async_test('html5lib_template.html f094bf7e94a88b86c80a0643e70c8e5ff3354698'), "%3Cbody%3E%3Ctemplate%3E%3Cthead%3E%3C/thead%3E%3C/table%3E%3Ctbody%3E%3C/tbody%3E%3C/template%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E"],"35a07ec3b4bf26ea407dc1ddf52f14195a714059":[async_test('html5lib_template.html 35a07ec3b4bf26ea407dc1ddf52f14195a714059'), "%3Cbody%3E%3Ctemplate%3E%3Cdiv%3E%3Ctr%3E%3C/tr%3E%3C/div%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"24faa53b271f994a4ff31d5796c8ff47d6f2c3e6":[async_test('html5lib_template.html 24faa53b271f994a4ff31d5796c8ff47d6f2c3e6'), "%3Cbody%3E%3Ctemplate%3E%3Cem%3EHello%3C/em%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22Hello%22"],"0f1c491b58c2dd3c402a62e37f833bc1f1db8d21":[async_test('html5lib_template.html 0f1c491b58c2dd3c402a62e37f833bc1f1db8d21'), "%3Cbody%3E%3Ctemplate%3E%3C%21--comment--%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3C%21--%20comment%20--%3E"],"868d918a7b5d8b5c065c15229492bc2022bfbcba":[async_test('html5lib_template.html 868d918a7b5d8b5c065c15229492bc2022bfbcba'), "%3Cbody%3E%3Ctemplate%3E%3Cstyle%3E%3C/style%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cstyle%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"0538efa44e857596c556033a3821d424378aea3f":[async_test('html5lib_template.html 0538efa44e857596c556033a3821d424378aea3f'), "%3Cbody%3E%3Ctemplate%3E%3Cmeta%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cmeta%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"e7d7bf3973c70d3cf9b0adad2ebed9f25be48d66":[async_test('html5lib_template.html e7d7bf3973c70d3cf9b0adad2ebed9f25be48d66'), "%3Cbody%3E%3Ctemplate%3E%3Clink%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Clink%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"c69d0ac542d477b7312bb24981127b8aa8fdb1df":[async_test('html5lib_template.html c69d0ac542d477b7312bb24981127b8aa8fdb1df'), "%3Cbody%3E%3Ctable%3E%3Ccolgroup%3E%3Ctemplate%3E%3Ccol%3E%3C/col%3E%3C/template%3E%3C/colgroup%3E%3C/table%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"b496a8c13a7bd75b778bb0de489726aee952ae0c":[async_test('html5lib_template.html b496a8c13a7bd75b778bb0de489726aee952ae0c'), "%3Cbody%20a%3Db%3E%3Ctemplate%3E%3Cdiv%3E%3C/div%3E%3Cbody%20c%3Dd%3E%3Cdiv%3E%3C/div%3E%3C/body%3E%3C/template%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20a%3D%22b%22%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"5d6ee61de40274c9626ca78ee208d51276d5662d":[async_test('html5lib_template.html 5d6ee61de40274c9626ca78ee208d51276d5662d'), "%3Chtml%20a%3Db%3E%3Ctemplate%3E%3Cdiv%3E%3Chtml%20b%3Dc%3E%3Cspan%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20a%3D%22b%22%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%3Cbody%3E"],"9bd9687a65f258adc24450fc5cbd781fff6c038a":[async_test('html5lib_template.html 9bd9687a65f258adc24450fc5cbd781fff6c038a'), "%3Chtml%20a%3Db%3E%3Ctemplate%3E%3Ccol%3E%3C/col%3E%3Chtml%20b%3Dc%3E%3Ccol%3E%3C/col%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20a%3D%22b%22%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%3Cbody%3E"],"db1baeb846d718c773324746524fbd68f2e9436e":[async_test('html5lib_template.html db1baeb846d718c773324746524fbd68f2e9436e'), "%3Chtml%20a%3Db%3E%3Ctemplate%3E%3Cframe%3E%3C/frame%3E%3Chtml%20b%3Dc%3E%3Cframe%3E%3C/frame%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20a%3D%22b%22%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"4b0ce46c611dbcc016db272ef007f302bee0c897":[async_test('html5lib_template.html 4b0ce46c611dbcc016db272ef007f302bee0c897'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3Ctemplate%3E%3C/template%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"1a735e1c7f28f8701f3c7fd5e9404b8911916086":[async_test('html5lib_template.html 1a735e1c7f28f8701f3c7fd5e9404b8911916086'), "%3Cbody%3E%3Ctemplate%3E%3Cthead%3E%3C/thead%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3C/template%3E%3Ctr%3E%3C/tr%3E%3Ctfoot%3E%3C/tfoot%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctfoot%3E"],"0686eedec06b2db1dc283fac92c1ef1a33114c71":[async_test('html5lib_template.html 0686eedec06b2db1dc283fac92c1ef1a33114c71'), "%3Cbody%3E%3Ctemplate%3E%3Ctemplate%3E%3Cb%3E%3Ctemplate%3E%3C/template%3E%3C/template%3Etext%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22text%22"],"d4dfb87ce626f12923056a6cd77448eaf4660ac2":[async_test('html5lib_template.html d4dfb87ce626f12923056a6cd77448eaf4660ac2'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3Ccolgroup%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"1f295920f2937b2c8023b3761c43a0d4d9e5353c":[async_test('html5lib_template.html 1f295920f2937b2c8023b3761c43a0d4d9e5353c'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3C/colgroup%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"3b91fa08fad923d387d924cff37fbf6b4c3a5712":[async_test('html5lib_template.html 3b91fa08fad923d387d924cff37fbf6b4c3a5712'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3Ccolgroup%3E%3C/template%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"45a1c1ad5d99ad67c573096a79253996a664e01b":[async_test('html5lib_template.html 45a1c1ad5d99ad67c573096a79253996a664e01b'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"0fe3a66773c6048c8f6f2c92f2611f65be972ec1":[async_test('html5lib_template.html 0fe3a66773c6048c8f6f2c92f2611f65be972ec1'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"be40897ca411e1507197c31ab2a9f9752a05f769":[async_test('html5lib_template.html be40897ca411e1507197c31ab2a9f9752a05f769'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3EHello", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"dcfb1048ed5c40e406b4fbf0cde24c826713907f":[async_test('html5lib_template.html dcfb1048ed5c40e406b4fbf0cde24c826713907f'), "%3Cbody%3E%3Ctemplate%3E%3Ci%3E%3Cmenu%3EFoo%3C/i%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ci%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cmenu%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ci%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22Foo%22"],"78263aeea68ac97903598682013bae9c0c21d547":[async_test('html5lib_template.html 78263aeea68ac97903598682013bae9c0c21d547'), "%3Cbody%3E%3Ctemplate%3E%3C/div%3E%3Cdiv%3EFoo%3C/div%3E%3Ctemplate%3E%3C/template%3E%3Ctr%3E%3C/tr%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22Foo%22%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"5aa177ef1a35bf4502dcb867d8e666288982ba99":[async_test('html5lib_template.html 5aa177ef1a35bf4502dcb867d8e666288982ba99'), "%3Cbody%3E%3Cdiv%3E%3Ctemplate%3E%3C/div%3E%3Ctr%3E%3Ctd%3EFoo%3C/td%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Foo%22"],"5d303375907dc4d4380b477e0317c17b660613e9":[async_test('html5lib_template.html 5d303375907dc4d4380b477e0317c17b660613e9'), "%3Ctemplate%3E%3C/figcaption%3E%3Csub%3E%3Ctable%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Csub%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E"],"d822f726927c34b92fe102b13e63920850878f6a":[async_test('html5lib_template.html d822f726927c34b92fe102b13e63920850878f6a'), "%3Ctemplate%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"07acdcaeb4fa639296d46673cf28823ddf2a6ca7":[async_test('html5lib_template.html 07acdcaeb4fa639296d46673cf28823ddf2a6ca7'), "%3Ctemplate%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%3Cbody%3E"],"58bd846ce1be0caf7560fba2ef19e2c2070ab123":[async_test('html5lib_template.html 58bd846ce1be0caf7560fba2ef19e2c2070ab123'), "%3Ctemplate%3E%3Ctemplate%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%3Cbody%3E"],"8eeee377e5ab324731cc592f1fa8abe1045ad610":[async_test('html5lib_template.html 8eeee377e5ab324731cc592f1fa8abe1045ad610'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctable%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E"],"b30690019090149132fc228a7261c5cf2fd149fc":[async_test('html5lib_template.html b30690019090149132fc228a7261c5cf2fd149fc'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctbody%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%3Cbody%3E"],"67a209d928804f90fdb66d070201b23f3d0c8a42":[async_test('html5lib_template.html 67a209d928804f90fdb66d070201b23f3d0c8a42'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctr%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%3Cbody%3E"],"12104886b8f87daa937eac30b5ff0e1e074eaa6f":[async_test('html5lib_template.html 12104886b8f87daa937eac30b5ff0e1e074eaa6f'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctd%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%3Cbody%3E"],"483cc9957a7225fe435112642be59abb4c459a1e":[async_test('html5lib_template.html 483cc9957a7225fe435112642be59abb4c459a1e'), "%3Ctemplate%3E%3Ctemplate%3E%3Ccaption%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccaption%3E%0A%7C%20%20%20%3Cbody%3E"],"72d8ac431a154c40ab75d53a258d9d80d47689eb":[async_test('html5lib_template.html 72d8ac431a154c40ab75d53a258d9d80d47689eb'), "%3Ctemplate%3E%3Ctemplate%3E%3Ccolgroup%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%3Cbody%3E"],"1125967cbbcd404f4cb14d48270b8ec778970d77":[async_test('html5lib_template.html 1125967cbbcd404f4cb14d48270b8ec778970d77'), "%3Ctemplate%3E%3Ctemplate%3E%3Ccol%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%3Cbody%3E"],"32c963e164b9ec82c60e490bb141c1ccc70b992f":[async_test('html5lib_template.html 32c963e164b9ec82c60e490bb141c1ccc70b992f'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctbody%3E%3Cselect%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%3Cbody%3E"],"574a95fc9c9f2de3aeaa0c9ee1e6967fc3d4770d":[async_test('html5lib_template.html 574a95fc9c9f2de3aeaa0c9ee1e6967fc3d4770d'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctable%3EFoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22Foo%22%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E"],"332863a7f9e61bff32bd3427ede7a088b790d453":[async_test('html5lib_template.html 332863a7f9e61bff32bd3427ede7a088b790d453'), "%3Ctemplate%3E%3Ctemplate%3E%3Cframe%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"2121db07146781773df9e53b94fa921a805175ce":[async_test('html5lib_template.html 2121db07146781773df9e53b94fa921a805175ce'), "%3Ctemplate%3E%3Ctemplate%3E%3Cscript%3Evar%20i", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cscript%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22var%20i%22%0A%7C%20%20%20%3Cbody%3E"],"8675de267cd7e34f2febdee3feb665614d1562fe":[async_test('html5lib_template.html 8675de267cd7e34f2febdee3feb665614d1562fe'), "%3Ctemplate%3E%3Ctemplate%3E%3Cstyle%3Evar%20i", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cstyle%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22var%20i%22%0A%7C%20%20%20%3Cbody%3E"],"c5d26ad923a2b1e988ddd378ca4fb26eb48353e1":[async_test('html5lib_template.html c5d26ad923a2b1e988ddd378ca4fb26eb48353e1'), "%3Ctemplate%3E%3Ctable%3E%3C/template%3E%3Cbody%3E%3Cspan%3EFoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%22Foo%22"],"eec1542e2fa0e9eafb7f8d4a51eae56b5a31b3c8":[async_test('html5lib_template.html eec1542e2fa0e9eafb7f8d4a51eae56b5a31b3c8'), "%3Ctemplate%3E%3Ctd%3E%3C/template%3E%3Cbody%3E%3Cspan%3EFoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%22Foo%22"],"b79387a54c3b136db0f28ed96555ff683b3947fe":[async_test('html5lib_template.html b79387a54c3b136db0f28ed96555ff683b3947fe'), "%3Ctemplate%3E%3Cobject%3E%3C/template%3E%3Cbody%3E%3Cspan%3EFoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cobject%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%22Foo%22"],"c477a29a4deb32d072a415fa809a84a4f2beee0c":[async_test('html5lib_template.html c477a29a4deb32d072a415fa809a84a4f2beee0c'), "%3Ctemplate%3E%3Csvg%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20template%3E%0A%7C%20%20%20%3Cbody%3E"],"26e4480c08e1f5f7b6ac8b8c1832ab0312e3b7c5":[async_test('html5lib_template.html 26e4480c08e1f5f7b6ac8b8c1832ab0312e3b7c5'), "%3Ctemplate%3E%3Csvg%3E%3Cfoo%3E%3Ctemplate%3E%3CforeignObject%3E%3Cdiv%3E%3C/template%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20foo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20template%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20foreignObject%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E"],"24b3b50fdd0bf8d5cf2ebaa6bf502d7bcfde1da4":[async_test('html5lib_template.html 24b3b50fdd0bf8d5cf2ebaa6bf502d7bcfde1da4'), "%3Cdummy%3E%3Ctemplate%3E%3Cspan%3E%3C/dummy%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdummy%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E"],"d3704c68528357189eb5826ab66eea071d6137a5":[async_test('html5lib_template.html d3704c68528357189eb5826ab66eea071d6137a5'), "%3Cbody%3E%3Ctable%3E%3Ctr%3E%3Ctd%3E%3Cselect%3E%3Ctemplate%3EFoo%3C/template%3E%3Ccaption%3EA%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Foo%22%0A%7C%20%20%20%20%20%20%20%3Ccaption%3E%0A%7C%20%20%20%20%20%20%20%20%20%22A%22"],"d958f7d44faf772d1fb60f1a8f186f837ca735d9":[async_test('html5lib_template.html d958f7d44faf772d1fb60f1a8f186f837ca735d9'), "%3Cbody%3E%3C/body%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content"],"3fc4d97fa68fc2658356bdbd4e051c867de8de53":[async_test('html5lib_template.html 3fc4d97fa68fc2658356bdbd4e051c867de8de53'), "%3Chead%3E%3C/head%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"94820107bbf3fab3f82de1f717e8413aead7d3a6":[async_test('html5lib_template.html 94820107bbf3fab3f82de1f717e8413aead7d3a6'), "%3Chead%3E%3C/head%3E%3Ctemplate%3EFoo%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22Foo%22%0A%7C%20%20%20%3Cbody%3E"],"657c00ebdda37ae060cc69633ed98482ccc29e18":[async_test('html5lib_template.html 657c00ebdda37ae060cc69633ed98482ccc29e18'), "%3C%21DOCTYPE%20HTML%3E%3Cdummy%3E%3Ctable%3E%3Ctemplate%3E%3Ctable%3E%3Ctemplate%3E%3Ctable%3E%3Cscript%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdummy%3E%0A%7C%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cscript%3E"],"649fc955a4b60ab2a5b881d94c9493eb4a545002":[async_test('html5lib_template.html 649fc955a4b60ab2a5b881d94c9493eb4a545002'), "%3Ctemplate%3E%3Ca%3E%3Ctable%3E%3Ca%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E"],"977041956eb9c7b9db73935168aba92f77c079f6":[async_test('html5lib_template.html 977041956eb9c7b9db73935168aba92f77c079f6'), "%3C%21DOCTYPE%20HTML%3E%3Ctemplate%3E%3Ctr%3E%3Ctd%3Ecell%3C/td%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22cell%22%0A%7C%20%20%20%3Cbody%3E"],"fafee395fea124791df59bafeb1136342b64d3c6":[async_test('html5lib_template.html fafee395fea124791df59bafeb1136342b64d3c6'), "%3C%21DOCTYPE%20HTML%3E%3Ctemplate%3E%20%3Ctr%3E%20%3Ctd%3Ecell%3C/td%3E%20%3C/tr%3E%20%3C/template%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22%20%22%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22%20%22%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22cell%22%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22%20%22%0A%7C%20%20%20%20%20%20%20%20%20%22%20%22%0A%7C%20%20%20%3Cbody%3E"],"d5a8beecf5d3c53e947772ad887808d132334aa1":[async_test('html5lib_template.html d5a8beecf5d3c53e947772ad887808d132334aa1'), "%3C%21DOCTYPE%20HTML%3E%3Ctemplate%3E%3Ctr%3E%3Ctd%3Ecell%3C/td%3E%3C/tr%3Ea%3C/template%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22cell%22%0A%7C%20%20%20%20%20%20%20%20%20%22a%22%0A%7C%20%20%20%3Cbody%3E"], + "010950d55f4eccf16e9c4af1d263bb747294c646":[async_test('html5lib_template.html 010950d55f4eccf16e9c4af1d263bb747294c646'), "%3Cbody%3E%3Ctemplate%3EHello%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22Hello%22"],"a838bd54410cef059a42eea9606356488e16535b":[async_test('html5lib_template.html a838bd54410cef059a42eea9606356488e16535b'), "%3Ctemplate%3EHello%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22Hello%22%0A%7C%20%20%20%3Cbody%3E"],"27fb9111f6675a7e033b867480c0afddcda161a6":[async_test('html5lib_template.html 27fb9111f6675a7e033b867480c0afddcda161a6'), "%3Ctemplate%3E%3C/template%3E%3Cdiv%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E"],"aee883a65775489399a003b2371d58248a6aff6f":[async_test('html5lib_template.html aee883a65775489399a003b2371d58248a6aff6f'), "%3Chtml%3E%3Ctemplate%3EHello%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22Hello%22%0A%7C%20%20%20%3Cbody%3E"],"89b17b54ab343191bf74ef5434f4d2cfac40ea97":[async_test('html5lib_template.html 89b17b54ab343191bf74ef5434f4d2cfac40ea97'), "%3Chead%3E%3Ctemplate%3E%3Cdiv%3E%3C/div%3E%3C/template%3E%3C/head%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%3Cbody%3E"],"c4433556c7414cfd71f27b420f1ffc4348774f5e":[async_test('html5lib_template.html c4433556c7414cfd71f27b420f1ffc4348774f5e'), "%3Cdiv%3E%3Ctemplate%3E%3Cdiv%3E%3Cspan%3E%3C/template%3E%3Cb%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E"],"3dcce7d97108b3e9ea7fa96f240ac62bf280e74b":[async_test('html5lib_template.html 3dcce7d97108b3e9ea7fa96f240ac62bf280e74b'), "%3Cdiv%3E%3Ctemplate%3E%3C/div%3EHello", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22Hello%22"],"a1f587f7ea85ccfe294bd45bfb501e850cb979e0":[async_test('html5lib_template.html a1f587f7ea85ccfe294bd45bfb501e850cb979e0'), "%3Cdiv%3E%3C/template%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E"],"cd26a7832f13bdc135697321ca6c2fecdca6ef5d":[async_test('html5lib_template.html cd26a7832f13bdc135697321ca6c2fecdca6ef5d'), "%3Ctable%3E%3Ctemplate%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"e30571d90b0e56864499961eb7be955994cf72e2":[async_test('html5lib_template.html e30571d90b0e56864499961eb7be955994cf72e2'), "%3Ctable%3E%3Ctemplate%3E%3C/template%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"01cbe9f6a25f286b08d8dc4f7b65421e8eb3500c":[async_test('html5lib_template.html 01cbe9f6a25f286b08d8dc4f7b65421e8eb3500c'), "%3Ctable%3E%3Cdiv%3E%3Ctemplate%3E%3C/template%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%3Ctable%3E"],"96cbbcdffe02c86a8b929604c2fd5f3571a18dbe":[async_test('html5lib_template.html 96cbbcdffe02c86a8b929604c2fd5f3571a18dbe'), "%3Ctable%3E%3Ctemplate%3E%3C/template%3E%3Cdiv%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"d51676f55550e960dd0f5fa7fd0bdfa20bdde046":[async_test('html5lib_template.html d51676f55550e960dd0f5fa7fd0bdfa20bdde046'), "%3Ctable%3E%20%20%20%3Ctemplate%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%22%20%20%20%22%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"f9dfd9acfd494489c899604649a01d864741f50f":[async_test('html5lib_template.html f9dfd9acfd494489c899604649a01d864741f50f'), "%3Ctable%3E%3Ctbody%3E%3Ctemplate%3E%3C/template%3E%3C/tbody%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"ea00361c265d3ffb47ce636d919c94ca10d58911":[async_test('html5lib_template.html ea00361c265d3ffb47ce636d919c94ca10d58911'), "%3Ctable%3E%3Ctbody%3E%3Ctemplate%3E%3C/tbody%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"d8ebfcf7694c9d04457e796ac73049210313602e":[async_test('html5lib_template.html d8ebfcf7694c9d04457e796ac73049210313602e'), "%3Ctable%3E%3Ctbody%3E%3Ctemplate%3E%3C/template%3E%3C/tbody%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"b4d5e6fe9b92e2c8f54199d7cab3da383c42add0":[async_test('html5lib_template.html b4d5e6fe9b92e2c8f54199d7cab3da383c42add0'), "%3Ctable%3E%3Cthead%3E%3Ctemplate%3E%3C/template%3E%3C/thead%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"07724ef8f7a4fa61c77ffcd5180d3101c4781502":[async_test('html5lib_template.html 07724ef8f7a4fa61c77ffcd5180d3101c4781502'), "%3Ctable%3E%3Ctfoot%3E%3Ctemplate%3E%3C/template%3E%3C/tfoot%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctfoot%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"e90f8aae8fc690540b42b3ffa3e741e7c1dfbf43":[async_test('html5lib_template.html e90f8aae8fc690540b42b3ffa3e741e7c1dfbf43'), "%3Cselect%3E%3Ctemplate%3E%3C/template%3E%3C/select%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"687bdf4adda88a316ec69fe20e84720acc5d1fe6":[async_test('html5lib_template.html 687bdf4adda88a316ec69fe20e84720acc5d1fe6'), "%3Cselect%3E%3Ctemplate%3E%3Coption%3E%3C/option%3E%3C/template%3E%3C/select%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Coption%3E"],"5b232642f472c2b4c0c7511fed464eebe686b427":[async_test('html5lib_template.html 5b232642f472c2b4c0c7511fed464eebe686b427'), "%3Ctemplate%3E%3Coption%3E%3C/option%3E%3C/select%3E%3Coption%3E%3C/option%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%3Cbody%3E"],"dc1ac1830a881d1532a1e6fd6d0cfa56d6571da2":[async_test('html5lib_template.html dc1ac1830a881d1532a1e6fd6d0cfa56d6571da2'), "%3Cselect%3E%3Ctemplate%3E%3C/template%3E%3Coption%3E%3C/select%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%3Coption%3E"],"c58747a85e8b4f44d7ae63c04cdad783a903c25e":[async_test('html5lib_template.html c58747a85e8b4f44d7ae63c04cdad783a903c25e'), "%3Cselect%3E%3Coption%3E%3Ctemplate%3E%3C/template%3E%3C/select%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"ca59bfdaec7451f704973176fab46e582bd691b2":[async_test('html5lib_template.html ca59bfdaec7451f704973176fab46e582bd691b2'), "%3Cselect%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"cf807d6391a58c172b6c15c3b01d2a99ec0e6cf8":[async_test('html5lib_template.html cf807d6391a58c172b6c15c3b01d2a99ec0e6cf8'), "%3Cselect%3E%3Coption%3E%3C/option%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content"],"350b7ac850e46de79615308fc923649264406104":[async_test('html5lib_template.html 350b7ac850e46de79615308fc923649264406104'), "%3Cselect%3E%3Coption%3E%3C/option%3E%3Ctemplate%3E%3Coption%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Coption%3E"],"a31ff44edf7f377543dabdda8141cda9bb6de134":[async_test('html5lib_template.html a31ff44edf7f377543dabdda8141cda9bb6de134'), "%3Ctable%3E%3Cthead%3E%3Ctemplate%3E%3Ctd%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"533c5c1b5f0d0cbb1ede2cc5ae927095c5b21f0b":[async_test('html5lib_template.html 533c5c1b5f0d0cbb1ede2cc5ae927095c5b21f0b'), "%3Ctable%3E%3Ctemplate%3E%3Cthead%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cthead%3E"],"61f79e083005007853c4f8e431559ac8d3845cfd":[async_test('html5lib_template.html 61f79e083005007853c4f8e431559ac8d3845cfd'), "%3Cbody%3E%3Ctable%3E%3Ctemplate%3E%3Ctd%3E%3C/tr%3E%3Cdiv%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"e802e85f36792b176b73c102c0e8761d9478621d":[async_test('html5lib_template.html e802e85f36792b176b73c102c0e8761d9478621d'), "%3Ctable%3E%3Ctemplate%3E%3Cthead%3E%3C/template%3E%3C/thead%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cthead%3E"],"51d0797ff7653cd7be34458d689146e08a666c7f":[async_test('html5lib_template.html 51d0797ff7653cd7be34458d689146e08a666c7f'), "%3Ctable%3E%3Cthead%3E%3Ctemplate%3E%3Ctr%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"d60e4079a18bd6266740cc61d1ca736e9d5098ce":[async_test('html5lib_template.html d60e4079a18bd6266740cc61d1ca736e9d5098ce'), "%3Ctable%3E%3Ctemplate%3E%3Ctr%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"308709292677b4d74c108a811ad7b7acd0bdfc9c":[async_test('html5lib_template.html 308709292677b4d74c108a811ad7b7acd0bdfc9c'), "%3Ctable%3E%3Ctr%3E%3Ctemplate%3E%3Ctd%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"8965cdf9c4e9936262e25c90c7a7f8673840a445":[async_test('html5lib_template.html 8965cdf9c4e9936262e25c90c7a7f8673840a445'), "%3Ctable%3E%3Ctemplate%3E%3Ctr%3E%3Ctemplate%3E%3Ctd%3E%3C/template%3E%3C/tr%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"7dccda789764beb489e09be10188af9347335d05":[async_test('html5lib_template.html 7dccda789764beb489e09be10188af9347335d05'), "%3Ctable%3E%3Ctemplate%3E%3Ctr%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3C/template%3E%3C/tr%3E%3C/template%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"e15be51c77e1a6de35568a099ed339440ce9426d":[async_test('html5lib_template.html e15be51c77e1a6de35568a099ed339440ce9426d'), "%3Ctable%3E%3Ctemplate%3E%3Ctd%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"503d3782e45940c19f096f360a092282b46ab1ea":[async_test('html5lib_template.html 503d3782e45940c19f096f360a092282b46ab1ea'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"b4ab56fd9e9cebf479d14adfa523c06d16483a5e":[async_test('html5lib_template.html b4ab56fd9e9cebf479d14adfa523c06d16483a5e'), "%3Cbody%3E%3Ctemplate%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3C/template%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"cd8bc9521f9683086a9e8529dd97314a6869daeb":[async_test('html5lib_template.html cd8bc9521f9683086a9e8529dd97314a6869daeb'), "%3Ctable%3E%3Ccolgroup%3E%3Ctemplate%3E%3Ccol%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"f915e7b3407c24b28c3aad318e5693cc774020f4":[async_test('html5lib_template.html f915e7b3407c24b28c3aad318e5693cc774020f4'), "%3Cframeset%3E%3Ctemplate%3E%3Cframe%3E%3C/frame%3E%3C/template%3E%3C/frameset%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cframeset%3E%0A%7C%20%20%20%20%20%3Cframe%3E"],"3c5eb261787b3d15aff86fa61de773fd7e439b0e":[async_test('html5lib_template.html 3c5eb261787b3d15aff86fa61de773fd7e439b0e'), "%3Ctemplate%3E%3Cframe%3E%3C/frame%3E%3C/frameset%3E%3Cframe%3E%3C/frame%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"2b57775750c198d4b98b23aed74ff80a866a01f5":[async_test('html5lib_template.html 2b57775750c198d4b98b23aed74ff80a866a01f5'), "%3Ctemplate%3E%3Cdiv%3E%3Cframeset%3E%3Cspan%3E%3C/span%3E%3C/div%3E%3Cspan%3E%3C/span%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%3Cbody%3E"],"dc3d016610f3ab532525a6c2871f03d6b62b0168":[async_test('html5lib_template.html dc3d016610f3ab532525a6c2871f03d6b62b0168'), "%3Cbody%3E%3Ctemplate%3E%3Cdiv%3E%3Cframeset%3E%3Cspan%3E%3C/span%3E%3C/div%3E%3Cspan%3E%3C/span%3E%3C/template%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cspan%3E"],"6a184d71d00580a26a8b6bd97aafe5503339f3f6":[async_test('html5lib_template.html 6a184d71d00580a26a8b6bd97aafe5503339f3f6'), "%3Cbody%3E%3Ctemplate%3E%3Cscript%3Evar%20i%20%3D%201%3B%3C/script%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cscript%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22var%20i%20%3D%201%3B%22%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"ce570a6c4bcee8b72a03e25508c6dd72e3cc6c35":[async_test('html5lib_template.html ce570a6c4bcee8b72a03e25508c6dd72e3cc6c35'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3Cdiv%3E%3C/div%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"e0c3d922f7b1f1654f02f716c3d9b31198ce3385":[async_test('html5lib_template.html e0c3d922f7b1f1654f02f716c3d9b31198ce3385'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"87e67242bf6debcf3b7dca852d10aa0f7b625b28":[async_test('html5lib_template.html 87e67242bf6debcf3b7dca852d10aa0f7b625b28'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3C/tr%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"35ac4d4c972a01d368ed0cacb41370efef0a644d":[async_test('html5lib_template.html 35ac4d4c972a01d368ed0cacb41370efef0a644d'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3Ctbody%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"5226c39dfc2d624ad4191b4eacb7e40c7ae528eb":[async_test('html5lib_template.html 5226c39dfc2d624ad4191b4eacb7e40c7ae528eb'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3Ccaption%3E%3C/caption%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"aa90cd4db6b12e0a47341914a90cc536eec32d64":[async_test('html5lib_template.html aa90cd4db6b12e0a47341914a90cc536eec32d64'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3Ccolgroup%3E%3C/caption%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"48af1faf5fcf48a0854af5a5c33656d9ccf6736b":[async_test('html5lib_template.html 48af1faf5fcf48a0854af5a5c33656d9ccf6736b'), "%3Cbody%3E%3Ctemplate%3E%3Ctd%3E%3C/td%3E%3C/table%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"ed3a029ba5e7f59969d65a4fc490a8f13b098cb9":[async_test('html5lib_template.html ed3a029ba5e7f59969d65a4fc490a8f13b098cb9'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3Ctbody%3E%3Ctr%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"6c8880d54475ad9574e203dcf2e55820b123cc64":[async_test('html5lib_template.html 6c8880d54475ad9574e203dcf2e55820b123cc64'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3Ccaption%3E%3Ctr%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"275060925a844cb51b29bae660301de9780d68c8":[async_test('html5lib_template.html 275060925a844cb51b29bae660301de9780d68c8'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3C/table%3E%3Ctr%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"9f82f6ec4c0a48c1d4dfbe6803b94abd553aea88":[async_test('html5lib_template.html 9f82f6ec4c0a48c1d4dfbe6803b94abd553aea88'), "%3Cbody%3E%3Ctemplate%3E%3Cthead%3E%3C/thead%3E%3Ccaption%3E%3C/caption%3E%3Ctbody%3E%3C/tbody%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ccaption%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E"],"f094bf7e94a88b86c80a0643e70c8e5ff3354698":[async_test('html5lib_template.html f094bf7e94a88b86c80a0643e70c8e5ff3354698'), "%3Cbody%3E%3Ctemplate%3E%3Cthead%3E%3C/thead%3E%3C/table%3E%3Ctbody%3E%3C/tbody%3E%3C/template%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E"],"35a07ec3b4bf26ea407dc1ddf52f14195a714059":[async_test('html5lib_template.html 35a07ec3b4bf26ea407dc1ddf52f14195a714059'), "%3Cbody%3E%3Ctemplate%3E%3Cdiv%3E%3Ctr%3E%3C/tr%3E%3C/div%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"24faa53b271f994a4ff31d5796c8ff47d6f2c3e6":[async_test('html5lib_template.html 24faa53b271f994a4ff31d5796c8ff47d6f2c3e6'), "%3Cbody%3E%3Ctemplate%3E%3Cem%3EHello%3C/em%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22Hello%22"],"0f1c491b58c2dd3c402a62e37f833bc1f1db8d21":[async_test('html5lib_template.html 0f1c491b58c2dd3c402a62e37f833bc1f1db8d21'), "%3Cbody%3E%3Ctemplate%3E%3C%21--comment--%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3C%21--%20comment%20--%3E"],"868d918a7b5d8b5c065c15229492bc2022bfbcba":[async_test('html5lib_template.html 868d918a7b5d8b5c065c15229492bc2022bfbcba'), "%3Cbody%3E%3Ctemplate%3E%3Cstyle%3E%3C/style%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cstyle%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"0538efa44e857596c556033a3821d424378aea3f":[async_test('html5lib_template.html 0538efa44e857596c556033a3821d424378aea3f'), "%3Cbody%3E%3Ctemplate%3E%3Cmeta%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cmeta%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"e7d7bf3973c70d3cf9b0adad2ebed9f25be48d66":[async_test('html5lib_template.html e7d7bf3973c70d3cf9b0adad2ebed9f25be48d66'), "%3Cbody%3E%3Ctemplate%3E%3Clink%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Clink%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"c69d0ac542d477b7312bb24981127b8aa8fdb1df":[async_test('html5lib_template.html c69d0ac542d477b7312bb24981127b8aa8fdb1df'), "%3Cbody%3E%3Ctable%3E%3Ccolgroup%3E%3Ctemplate%3E%3Ccol%3E%3C/col%3E%3C/template%3E%3C/colgroup%3E%3C/table%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"b496a8c13a7bd75b778bb0de489726aee952ae0c":[async_test('html5lib_template.html b496a8c13a7bd75b778bb0de489726aee952ae0c'), "%3Cbody%20a%3Db%3E%3Ctemplate%3E%3Cdiv%3E%3C/div%3E%3Cbody%20c%3Dd%3E%3Cdiv%3E%3C/div%3E%3C/body%3E%3C/template%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20a%3D%22b%22%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"5d6ee61de40274c9626ca78ee208d51276d5662d":[async_test('html5lib_template.html 5d6ee61de40274c9626ca78ee208d51276d5662d'), "%3Chtml%20a%3Db%3E%3Ctemplate%3E%3Cdiv%3E%3Chtml%20b%3Dc%3E%3Cspan%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20a%3D%22b%22%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%3Cbody%3E"],"9bd9687a65f258adc24450fc5cbd781fff6c038a":[async_test('html5lib_template.html 9bd9687a65f258adc24450fc5cbd781fff6c038a'), "%3Chtml%20a%3Db%3E%3Ctemplate%3E%3Ccol%3E%3C/col%3E%3Chtml%20b%3Dc%3E%3Ccol%3E%3C/col%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20a%3D%22b%22%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%3Cbody%3E"],"db1baeb846d718c773324746524fbd68f2e9436e":[async_test('html5lib_template.html db1baeb846d718c773324746524fbd68f2e9436e'), "%3Chtml%20a%3Db%3E%3Ctemplate%3E%3Cframe%3E%3C/frame%3E%3Chtml%20b%3Dc%3E%3Cframe%3E%3C/frame%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20a%3D%22b%22%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"4b0ce46c611dbcc016db272ef007f302bee0c897":[async_test('html5lib_template.html 4b0ce46c611dbcc016db272ef007f302bee0c897'), "%3Cbody%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3Ctemplate%3E%3C/template%3E%3Ctd%3E%3C/td%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"1a735e1c7f28f8701f3c7fd5e9404b8911916086":[async_test('html5lib_template.html 1a735e1c7f28f8701f3c7fd5e9404b8911916086'), "%3Cbody%3E%3Ctemplate%3E%3Cthead%3E%3C/thead%3E%3Ctemplate%3E%3Ctr%3E%3C/tr%3E%3C/template%3E%3Ctr%3E%3C/tr%3E%3Ctfoot%3E%3C/tfoot%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctfoot%3E"],"0686eedec06b2db1dc283fac92c1ef1a33114c71":[async_test('html5lib_template.html 0686eedec06b2db1dc283fac92c1ef1a33114c71'), "%3Cbody%3E%3Ctemplate%3E%3Ctemplate%3E%3Cb%3E%3Ctemplate%3E%3C/template%3E%3C/template%3Etext%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22text%22"],"d4dfb87ce626f12923056a6cd77448eaf4660ac2":[async_test('html5lib_template.html d4dfb87ce626f12923056a6cd77448eaf4660ac2'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3Ccolgroup%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"1f295920f2937b2c8023b3761c43a0d4d9e5353c":[async_test('html5lib_template.html 1f295920f2937b2c8023b3761c43a0d4d9e5353c'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3C/colgroup%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"3b91fa08fad923d387d924cff37fbf6b4c3a5712":[async_test('html5lib_template.html 3b91fa08fad923d387d924cff37fbf6b4c3a5712'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3Ccolgroup%3E%3C/template%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"45a1c1ad5d99ad67c573096a79253996a664e01b":[async_test('html5lib_template.html 45a1c1ad5d99ad67c573096a79253996a664e01b'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"0fe3a66773c6048c8f6f2c92f2611f65be972ec1":[async_test('html5lib_template.html 0fe3a66773c6048c8f6f2c92f2611f65be972ec1'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"be40897ca411e1507197c31ab2a9f9752a05f769":[async_test('html5lib_template.html be40897ca411e1507197c31ab2a9f9752a05f769'), "%3Cbody%3E%3Ctemplate%3E%3Ccol%3EHello", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ccol%3E"],"dcfb1048ed5c40e406b4fbf0cde24c826713907f":[async_test('html5lib_template.html dcfb1048ed5c40e406b4fbf0cde24c826713907f'), "%3Cbody%3E%3Ctemplate%3E%3Ci%3E%3Cmenu%3EFoo%3C/i%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ci%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cmenu%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ci%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22Foo%22"],"78263aeea68ac97903598682013bae9c0c21d547":[async_test('html5lib_template.html 78263aeea68ac97903598682013bae9c0c21d547'), "%3Cbody%3E%3Ctemplate%3E%3C/div%3E%3Cdiv%3EFoo%3C/div%3E%3Ctemplate%3E%3C/template%3E%3Ctr%3E%3C/tr%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22Foo%22%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content"],"5aa177ef1a35bf4502dcb867d8e666288982ba99":[async_test('html5lib_template.html 5aa177ef1a35bf4502dcb867d8e666288982ba99'), "%3Cbody%3E%3Cdiv%3E%3Ctemplate%3E%3C/div%3E%3Ctr%3E%3Ctd%3EFoo%3C/td%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Foo%22"],"5d303375907dc4d4380b477e0317c17b660613e9":[async_test('html5lib_template.html 5d303375907dc4d4380b477e0317c17b660613e9'), "%3Ctemplate%3E%3C/figcaption%3E%3Csub%3E%3Ctable%3E%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Csub%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E"],"d822f726927c34b92fe102b13e63920850878f6a":[async_test('html5lib_template.html d822f726927c34b92fe102b13e63920850878f6a'), "%3Ctemplate%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"07acdcaeb4fa639296d46673cf28823ddf2a6ca7":[async_test('html5lib_template.html 07acdcaeb4fa639296d46673cf28823ddf2a6ca7'), "%3Ctemplate%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%3Cbody%3E"],"58bd846ce1be0caf7560fba2ef19e2c2070ab123":[async_test('html5lib_template.html 58bd846ce1be0caf7560fba2ef19e2c2070ab123'), "%3Ctemplate%3E%3Ctemplate%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%3Cbody%3E"],"8eeee377e5ab324731cc592f1fa8abe1045ad610":[async_test('html5lib_template.html 8eeee377e5ab324731cc592f1fa8abe1045ad610'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctable%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E"],"b30690019090149132fc228a7261c5cf2fd149fc":[async_test('html5lib_template.html b30690019090149132fc228a7261c5cf2fd149fc'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctbody%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%3Cbody%3E"],"67a209d928804f90fdb66d070201b23f3d0c8a42":[async_test('html5lib_template.html 67a209d928804f90fdb66d070201b23f3d0c8a42'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctr%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%3Cbody%3E"],"12104886b8f87daa937eac30b5ff0e1e074eaa6f":[async_test('html5lib_template.html 12104886b8f87daa937eac30b5ff0e1e074eaa6f'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctd%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%3Cbody%3E"],"483cc9957a7225fe435112642be59abb4c459a1e":[async_test('html5lib_template.html 483cc9957a7225fe435112642be59abb4c459a1e'), "%3Ctemplate%3E%3Ctemplate%3E%3Ccaption%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccaption%3E%0A%7C%20%20%20%3Cbody%3E"],"72d8ac431a154c40ab75d53a258d9d80d47689eb":[async_test('html5lib_template.html 72d8ac431a154c40ab75d53a258d9d80d47689eb'), "%3Ctemplate%3E%3Ctemplate%3E%3Ccolgroup%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%3Cbody%3E"],"1125967cbbcd404f4cb14d48270b8ec778970d77":[async_test('html5lib_template.html 1125967cbbcd404f4cb14d48270b8ec778970d77'), "%3Ctemplate%3E%3Ctemplate%3E%3Ccol%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%3Cbody%3E"],"32c963e164b9ec82c60e490bb141c1ccc70b992f":[async_test('html5lib_template.html 32c963e164b9ec82c60e490bb141c1ccc70b992f'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctbody%3E%3Cselect%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%3Cbody%3E"],"574a95fc9c9f2de3aeaa0c9ee1e6967fc3d4770d":[async_test('html5lib_template.html 574a95fc9c9f2de3aeaa0c9ee1e6967fc3d4770d'), "%3Ctemplate%3E%3Ctemplate%3E%3Ctable%3EFoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22Foo%22%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E"],"332863a7f9e61bff32bd3427ede7a088b790d453":[async_test('html5lib_template.html 332863a7f9e61bff32bd3427ede7a088b790d453'), "%3Ctemplate%3E%3Ctemplate%3E%3Cframe%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"2121db07146781773df9e53b94fa921a805175ce":[async_test('html5lib_template.html 2121db07146781773df9e53b94fa921a805175ce'), "%3Ctemplate%3E%3Ctemplate%3E%3Cscript%3Evar%20i", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cscript%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22var%20i%22%0A%7C%20%20%20%3Cbody%3E"],"8675de267cd7e34f2febdee3feb665614d1562fe":[async_test('html5lib_template.html 8675de267cd7e34f2febdee3feb665614d1562fe'), "%3Ctemplate%3E%3Ctemplate%3E%3Cstyle%3Evar%20i", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cstyle%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22var%20i%22%0A%7C%20%20%20%3Cbody%3E"],"c5d26ad923a2b1e988ddd378ca4fb26eb48353e1":[async_test('html5lib_template.html c5d26ad923a2b1e988ddd378ca4fb26eb48353e1'), "%3Ctemplate%3E%3Ctable%3E%3C/template%3E%3Cbody%3E%3Cspan%3EFoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%22Foo%22"],"eec1542e2fa0e9eafb7f8d4a51eae56b5a31b3c8":[async_test('html5lib_template.html eec1542e2fa0e9eafb7f8d4a51eae56b5a31b3c8'), "%3Ctemplate%3E%3Ctd%3E%3C/template%3E%3Cbody%3E%3Cspan%3EFoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%22Foo%22"],"b79387a54c3b136db0f28ed96555ff683b3947fe":[async_test('html5lib_template.html b79387a54c3b136db0f28ed96555ff683b3947fe'), "%3Ctemplate%3E%3Cobject%3E%3C/template%3E%3Cbody%3E%3Cspan%3EFoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Cobject%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%22Foo%22"],"c477a29a4deb32d072a415fa809a84a4f2beee0c":[async_test('html5lib_template.html c477a29a4deb32d072a415fa809a84a4f2beee0c'), "%3Ctemplate%3E%3Csvg%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20template%3E%0A%7C%20%20%20%3Cbody%3E"],"26e4480c08e1f5f7b6ac8b8c1832ab0312e3b7c5":[async_test('html5lib_template.html 26e4480c08e1f5f7b6ac8b8c1832ab0312e3b7c5'), "%3Ctemplate%3E%3Csvg%3E%3Cfoo%3E%3Ctemplate%3E%3CforeignObject%3E%3Cdiv%3E%3C/template%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20foo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20template%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20foreignObject%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E"],"24b3b50fdd0bf8d5cf2ebaa6bf502d7bcfde1da4":[async_test('html5lib_template.html 24b3b50fdd0bf8d5cf2ebaa6bf502d7bcfde1da4'), "%3Cdummy%3E%3Ctemplate%3E%3Cspan%3E%3C/dummy%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdummy%3E%0A%7C%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3E"],"d3704c68528357189eb5826ab66eea071d6137a5":[async_test('html5lib_template.html d3704c68528357189eb5826ab66eea071d6137a5'), "%3Cbody%3E%3Ctable%3E%3Ctr%3E%3Ctd%3E%3Cselect%3E%3Ctemplate%3EFoo%3C/template%3E%3Ccaption%3EA%3C/table%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Foo%22%0A%7C%20%20%20%20%20%20%20%3Ccaption%3E%0A%7C%20%20%20%20%20%20%20%20%20%22A%22"],"d958f7d44faf772d1fb60f1a8f186f837ca735d9":[async_test('html5lib_template.html d958f7d44faf772d1fb60f1a8f186f837ca735d9'), "%3Cbody%3E%3C/body%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content"],"3fc4d97fa68fc2658356bdbd4e051c867de8de53":[async_test('html5lib_template.html 3fc4d97fa68fc2658356bdbd4e051c867de8de53'), "%3Chead%3E%3C/head%3E%3Ctemplate%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"94820107bbf3fab3f82de1f717e8413aead7d3a6":[async_test('html5lib_template.html 94820107bbf3fab3f82de1f717e8413aead7d3a6'), "%3Chead%3E%3C/head%3E%3Ctemplate%3EFoo%3C/template%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22Foo%22%0A%7C%20%20%20%3Cbody%3E"],"ed920bca1fe1f5ad471bbd81adf8a41f3e2d9b06":[async_test('html5lib_template.html ed920bca1fe1f5ad471bbd81adf8a41f3e2d9b06'), "%3Chtml%3E%3Chead%3E%3C/head%3E%3Ctemplate%3E%3C/template%3E%3Chead%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%3Cbody%3E"],"657c00ebdda37ae060cc69633ed98482ccc29e18":[async_test('html5lib_template.html 657c00ebdda37ae060cc69633ed98482ccc29e18'), "%3C%21DOCTYPE%20HTML%3E%3Cdummy%3E%3Ctable%3E%3Ctemplate%3E%3Ctable%3E%3Ctemplate%3E%3Ctable%3E%3Cscript%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdummy%3E%0A%7C%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cscript%3E"],"649fc955a4b60ab2a5b881d94c9493eb4a545002":[async_test('html5lib_template.html 649fc955a4b60ab2a5b881d94c9493eb4a545002'), "%3Ctemplate%3E%3Ca%3E%3Ctable%3E%3Ca%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%3Cbody%3E"],"977041956eb9c7b9db73935168aba92f77c079f6":[async_test('html5lib_template.html 977041956eb9c7b9db73935168aba92f77c079f6'), "%3C%21DOCTYPE%20HTML%3E%3Ctemplate%3E%3Ctr%3E%3Ctd%3Ecell%3C/td%3E%3C/tr%3E%3C/template%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22cell%22%0A%7C%20%20%20%3Cbody%3E"],"fafee395fea124791df59bafeb1136342b64d3c6":[async_test('html5lib_template.html fafee395fea124791df59bafeb1136342b64d3c6'), "%3C%21DOCTYPE%20HTML%3E%3Ctemplate%3E%20%3Ctr%3E%20%3Ctd%3Ecell%3C/td%3E%20%3C/tr%3E%20%3C/template%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%22%20%22%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22%20%22%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22cell%22%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22%20%22%0A%7C%20%20%20%20%20%20%20%20%20%22%20%22%0A%7C%20%20%20%3Cbody%3E"],"d5a8beecf5d3c53e947772ad887808d132334aa1":[async_test('html5lib_template.html d5a8beecf5d3c53e947772ad887808d132334aa1'), "%3C%21DOCTYPE%20HTML%3E%3Ctemplate%3E%3Ctr%3E%3Ctd%3Ecell%3C/td%3E%3C/tr%3Ea%3C/template%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Ctemplate%3E%0A%7C%20%20%20%20%20%20%20content%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22cell%22%0A%7C%20%20%20%20%20%20%20%20%20%22a%22%0A%7C%20%20%20%3Cbody%3E"], } init_tests(get_type()); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit01.html b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit01.html index 4fd9f01..a94cdc7 100644 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit01.html +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit01.html
@@ -18,9 +18,9 @@ <script src="/resources/testharnessreport.js"></script> <script> var num_iframes = 8; - var order = ['4235382bf15f93f7dd1096832ae74cc71edef4d7','9906bb30ae08654f4c67bf6d97040abbca91082d','97974a9c541d97c7bb5bd8ba97c2ccbe0c6e55bd','f30960ce7d5b25adc846e47823f977616d38b296','f3ed3ec3a14058fd97c9aad83299bc8836d21283','f073fda1df7d917e37a207c326bdc4db0b4b3481','5533bf52e328c5748a203be1bb245848de592783','5b753a783c228a1b423152d9707cf900e57bc5da','eea9ac89544ec31fb78f7629ea0e065bd7422c98','03a99ca235d60b3191a3c5671ff7df5ffca5372d','c37bc2e44b2765025f58c9680a560c1a3dc3ab93','c6b4dc9c0041dd5a069741dbf228f03439115b8d','d4613a2b82f5d4ec251149508096f8071a8714d5','0f78a3fae382185ef9ac8f767efafb401249c1e1','375260e547e078df727a3669f5c8dcef7ccf71a7','3bea2bf663be5de2bbcdad57ac95c5933e266d42','19944775fd9dd871fbc4cf813eb105c29bc5d834','25b53e528a0ad0b002c8a26b7260213a24981860','ce59a8ae9cf138cb81fd017711097d1643c6f227','913071287591cc570d512c824b419d9a172d4339','2669743ff272e43978ac0f8a2f2c602ec9036c26','a9e759bf3ce415ad6216c58ee906639c03ffa03f','1274e8cdad6a8957fa9b02708ee58b73de41ae02','bbbea9a3752a36a64f2b62f15383406b16113fe7','e0910f26aac678f50612da8d05d20aa29e140655','f30a9e97cdf3c54ffccaa7b9c2067ff109317530','0d99b69e40dbb898cd4a188aa4920042c30815b4','a20991a86f6d34fd67ddb4002e3972d82230d879','006dbf89bfa3df51d837e7557c3e32dfbc6f0f4c','7e8f1399f9c87dbd103303c6051873079b265360','5081f4afe652b92f23e80d275f67dec9139df8e3','f904db0ad0c00794f8a2ca238b4c36084993c741','d56fcf271bf902fc4739f055f031f0d11620057c','a897ca0ad0492945709d0772c91e33d485ddf9c7','7274654c671e2e1715a017a239a98399496b7ba6','346ed4219453716e3fee23ccddf283fde408d349','4d1b6f58e6bb11d27e2097f656abdd1122a45a67','bb7bc3a43938aef67cffb49084f27cc678cd9b7a','992947d22821e1eb7b9116a99420b6c7f5ad46f2','88eca99701e0ad1fda391722e5f0cdcf1e2b667d','4b36a9545e5d8df93c447eaa8b1dc42d704d9c61','dc2437252e38b998fec43311653af309a65ef35f','ec499b1124d241faaa28e2f985ecf5f3fa00fcf8','cd236e537fa5d967d11efea30d96cd6ef6c9f46b','2ee90ed930fca8db8278161af28adde1e0c3907b','9804e9659cd045f199d9f58ef85c2639724359aa','a785e349a36349db19df18c06032315c6356486c','401c8625b8574b46d03b8e95acd29358c82b53d3','1390b296dc6152683e9de9820194bca39e18cbd6','7dc7e88fa9eba71234bdb4037a15a4f70183a466',]; + var order = ['4235382bf15f93f7dd1096832ae74cc71edef4d7','9906bb30ae08654f4c67bf6d97040abbca91082d','97974a9c541d97c7bb5bd8ba97c2ccbe0c6e55bd','f30960ce7d5b25adc846e47823f977616d38b296','f3ed3ec3a14058fd97c9aad83299bc8836d21283','f073fda1df7d917e37a207c326bdc4db0b4b3481','5533bf52e328c5748a203be1bb245848de592783','5b753a783c228a1b423152d9707cf900e57bc5da','eea9ac89544ec31fb78f7629ea0e065bd7422c98','03a99ca235d60b3191a3c5671ff7df5ffca5372d','c37bc2e44b2765025f58c9680a560c1a3dc3ab93','c6b4dc9c0041dd5a069741dbf228f03439115b8d','d4613a2b82f5d4ec251149508096f8071a8714d5','0f78a3fae382185ef9ac8f767efafb401249c1e1','375260e547e078df727a3669f5c8dcef7ccf71a7','3bea2bf663be5de2bbcdad57ac95c5933e266d42','19944775fd9dd871fbc4cf813eb105c29bc5d834','25b53e528a0ad0b002c8a26b7260213a24981860','ce59a8ae9cf138cb81fd017711097d1643c6f227','913071287591cc570d512c824b419d9a172d4339','2669743ff272e43978ac0f8a2f2c602ec9036c26','a9e759bf3ce415ad6216c58ee906639c03ffa03f','1274e8cdad6a8957fa9b02708ee58b73de41ae02','bbbea9a3752a36a64f2b62f15383406b16113fe7','e0910f26aac678f50612da8d05d20aa29e140655','f30a9e97cdf3c54ffccaa7b9c2067ff109317530','f71e076cf210f54ee646d71fca7a8de5322149ff','1b6a0afa648100ebd5f8b6719b4d8c5887f3f732','0d99b69e40dbb898cd4a188aa4920042c30815b4','a20991a86f6d34fd67ddb4002e3972d82230d879','006dbf89bfa3df51d837e7557c3e32dfbc6f0f4c','7e8f1399f9c87dbd103303c6051873079b265360','5081f4afe652b92f23e80d275f67dec9139df8e3','f904db0ad0c00794f8a2ca238b4c36084993c741','d56fcf271bf902fc4739f055f031f0d11620057c','a897ca0ad0492945709d0772c91e33d485ddf9c7','7274654c671e2e1715a017a239a98399496b7ba6','346ed4219453716e3fee23ccddf283fde408d349','4d1b6f58e6bb11d27e2097f656abdd1122a45a67','bb7bc3a43938aef67cffb49084f27cc678cd9b7a','992947d22821e1eb7b9116a99420b6c7f5ad46f2','88eca99701e0ad1fda391722e5f0cdcf1e2b667d','4b36a9545e5d8df93c447eaa8b1dc42d704d9c61','dc2437252e38b998fec43311653af309a65ef35f','ec499b1124d241faaa28e2f985ecf5f3fa00fcf8','cd236e537fa5d967d11efea30d96cd6ef6c9f46b','2ee90ed930fca8db8278161af28adde1e0c3907b','9804e9659cd045f199d9f58ef85c2639724359aa','a785e349a36349db19df18c06032315c6356486c','401c8625b8574b46d03b8e95acd29358c82b53d3','1390b296dc6152683e9de9820194bca39e18cbd6','7dc7e88fa9eba71234bdb4037a15a4f70183a466',]; var tests = { - "4235382bf15f93f7dd1096832ae74cc71edef4d7":[async_test('html5lib_webkit01.html 4235382bf15f93f7dd1096832ae74cc71edef4d7'), "Test", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22Test%22"],"9906bb30ae08654f4c67bf6d97040abbca91082d":[async_test('html5lib_webkit01.html 9906bb30ae08654f4c67bf6d97040abbca91082d'), "%3Cdiv%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E"],"97974a9c541d97c7bb5bd8ba97c2ccbe0c6e55bd":[async_test('html5lib_webkit01.html 97974a9c541d97c7bb5bd8ba97c2ccbe0c6e55bd'), "%3Cdiv%3ETest%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Test%22"],"f30960ce7d5b25adc846e47823f977616d38b296":[async_test('html5lib_webkit01.html f30960ce7d5b25adc846e47823f977616d38b296'), "%3Cdi", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E"],"f3ed3ec3a14058fd97c9aad83299bc8836d21283":[async_test('html5lib_webkit01.html f3ed3ec3a14058fd97c9aad83299bc8836d21283'), "%3Cdiv%3EHello%3C/div%3E%0A%3Cscript%3E%0Aconsole.log%28%22PASS%22%29%3B%0A%3C/script%3E%0A%3Cdiv%3EBye%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Hello%22%0A%7C%20%20%20%20%20%22%0A%22%0A%7C%20%20%20%20%20%3Cscript%3E%0A%7C%20%20%20%20%20%20%20%22%0Aconsole.log%28%22PASS%22%29%3B%0A%22%0A%7C%20%20%20%20%20%22%0A%22%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Bye%22"],"f073fda1df7d917e37a207c326bdc4db0b4b3481":[async_test('html5lib_webkit01.html f073fda1df7d917e37a207c326bdc4db0b4b3481'), "%3Cdiv%20foo%3D%22bar%22%3EHello%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20foo%3D%22bar%22%0A%7C%20%20%20%20%20%20%20%22Hello%22"],"5533bf52e328c5748a203be1bb245848de592783":[async_test('html5lib_webkit01.html 5533bf52e328c5748a203be1bb245848de592783'), "%3Cdiv%3EHello%3C/div%3E%0A%3Cscript%3E%0Aconsole.log%28%22FOO%3Cspan%3EBAR%3C/span%3EBAZ%22%29%3B%0A%3C/script%3E%0A%3Cdiv%3EBye%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Hello%22%0A%7C%20%20%20%20%20%22%0A%22%0A%7C%20%20%20%20%20%3Cscript%3E%0A%7C%20%20%20%20%20%20%20%22%0Aconsole.log%28%22FOO%3Cspan%3EBAR%3C/span%3EBAZ%22%29%3B%0A%22%0A%7C%20%20%20%20%20%22%0A%22%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Bye%22"],"5b753a783c228a1b423152d9707cf900e57bc5da":[async_test('html5lib_webkit01.html 5b753a783c228a1b423152d9707cf900e57bc5da'), "%3Cfoo%20bar%3D%22baz%22%3E%3C/foo%3E%3Cpotato%20quack%3D%22duck%22%3E%3C/potato%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20bar%3D%22baz%22%0A%7C%20%20%20%20%20%3Cpotato%3E%0A%7C%20%20%20%20%20%20%20quack%3D%22duck%22"],"eea9ac89544ec31fb78f7629ea0e065bd7422c98":[async_test('html5lib_webkit01.html eea9ac89544ec31fb78f7629ea0e065bd7422c98'), "%3Cfoo%20bar%3D%22baz%22%3E%3Cpotato%20quack%3D%22duck%22%3E%3C/potato%3E%3C/foo%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20bar%3D%22baz%22%0A%7C%20%20%20%20%20%20%20%3Cpotato%3E%0A%7C%20%20%20%20%20%20%20%20%20quack%3D%22duck%22"],"03a99ca235d60b3191a3c5671ff7df5ffca5372d":[async_test('html5lib_webkit01.html 03a99ca235d60b3191a3c5671ff7df5ffca5372d'), "%3Cfoo%3E%3C/foo%20bar%3D%22baz%22%3E%3Cpotato%3E%3C/potato%20quack%3D%22duck%22%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Cpotato%3E"],"c37bc2e44b2765025f58c9680a560c1a3dc3ab93":[async_test('html5lib_webkit01.html c37bc2e44b2765025f58c9680a560c1a3dc3ab93'), "%3C/%20tttt%3E", "%23document%0A%7C%20%3C%21--%20%20tttt%20--%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E"],"c6b4dc9c0041dd5a069741dbf228f03439115b8d":[async_test('html5lib_webkit01.html c6b4dc9c0041dd5a069741dbf228f03439115b8d'), "%3Cdiv%20FOO%20%3E%3Cimg%3E%3Cimg%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20foo%3D%22%22%0A%7C%20%20%20%20%20%20%20%3Cimg%3E%0A%7C%20%20%20%20%20%20%20%3Cimg%3E"],"d4613a2b82f5d4ec251149508096f8071a8714d5":[async_test('html5lib_webkit01.html d4613a2b82f5d4ec251149508096f8071a8714d5'), "%3Cp%3ETest%3C/p%3Cp%3ETest2%3C/p%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cp%3E%0A%7C%20%20%20%20%20%20%20%22TestTest2%22"],"0f78a3fae382185ef9ac8f767efafb401249c1e1":[async_test('html5lib_webkit01.html 0f78a3fae382185ef9ac8f767efafb401249c1e1'), "%3Crdar%3A//problem/6869687%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Crdar%3A%3E%0A%7C%20%20%20%20%20%20%206869687%3D%22%22%0A%7C%20%20%20%20%20%20%20problem%3D%22%22"],"375260e547e078df727a3669f5c8dcef7ccf71a7":[async_test('html5lib_webkit01.html 375260e547e078df727a3669f5c8dcef7ccf71a7'), "%3CA%3Etest%3C%20/A%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%22test%3C%20/A%3E%22"],"3bea2bf663be5de2bbcdad57ac95c5933e266d42":[async_test('html5lib_webkit01.html 3bea2bf663be5de2bbcdad57ac95c5933e266d42'), "%26lt%3B", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22%3C%22"],"19944775fd9dd871fbc4cf813eb105c29bc5d834":[async_test('html5lib_webkit01.html 19944775fd9dd871fbc4cf813eb105c29bc5d834'), "%3Cbody%20foo%3D%27bar%27%3E%3Cbody%20foo%3D%27baz%27%20yo%3D%27mama%27%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20foo%3D%22bar%22%0A%7C%20%20%20%20%20yo%3D%22mama%22"],"25b53e528a0ad0b002c8a26b7260213a24981860":[async_test('html5lib_webkit01.html 25b53e528a0ad0b002c8a26b7260213a24981860'), "%3Cbody%3E%3C/br%20foo%3D%22bar%22%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cbr%3E"],"ce59a8ae9cf138cb81fd017711097d1643c6f227":[async_test('html5lib_webkit01.html ce59a8ae9cf138cb81fd017711097d1643c6f227'), "%3Cbdy%3E%3Cbr%20foo%3D%22bar%22%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cbdy%3E%0A%7C%20%20%20%20%20%20%20%3Cbr%3E%0A%7C%20%20%20%20%20%20%20%20%20foo%3D%22bar%22"],"913071287591cc570d512c824b419d9a172d4339":[async_test('html5lib_webkit01.html 913071287591cc570d512c824b419d9a172d4339'), "%3Cbody%3E%3C/body%3E%3C/br%20foo%3D%22bar%22%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cbr%3E"],"2669743ff272e43978ac0f8a2f2c602ec9036c26":[async_test('html5lib_webkit01.html 2669743ff272e43978ac0f8a2f2c602ec9036c26'), "%3Cbdy%3E%3C/body%3E%3Cbr%20foo%3D%22bar%22%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cbdy%3E%0A%7C%20%20%20%20%20%20%20%3Cbr%3E%0A%7C%20%20%20%20%20%20%20%20%20foo%3D%22bar%22"],"a9e759bf3ce415ad6216c58ee906639c03ffa03f":[async_test('html5lib_webkit01.html a9e759bf3ce415ad6216c58ee906639c03ffa03f'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3E%3C%21--%20Hi%20there%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%3C%21--%20%20Hi%20there%20%20--%3E"],"1274e8cdad6a8957fa9b02708ee58b73de41ae02":[async_test('html5lib_webkit01.html 1274e8cdad6a8957fa9b02708ee58b73de41ae02'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3E%3C%21--%20Comment%20A%20--%3E%3C%21--%20Comment%20B%20--%3E%3C%21--%20Comment%20C%20--%3E%3C%21--%20Comment%20D%20--%3E%3C%21--%20Comment%20E%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%3C%21--%20%20Comment%20A%20%20--%3E%0A%7C%20%3C%21--%20%20Comment%20B%20%20--%3E%0A%7C%20%3C%21--%20%20Comment%20C%20%20--%3E%0A%7C%20%3C%21--%20%20Comment%20D%20%20--%3E%0A%7C%20%3C%21--%20%20Comment%20E%20%20--%3E"],"bbbea9a3752a36a64f2b62f15383406b16113fe7":[async_test('html5lib_webkit01.html bbbea9a3752a36a64f2b62f15383406b16113fe7'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3Ex%3C%21--%20Hi%20there%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22x%22%0A%7C%20%20%20%20%20%3C%21--%20%20Hi%20there%20%20--%3E"],"e0910f26aac678f50612da8d05d20aa29e140655":[async_test('html5lib_webkit01.html e0910f26aac678f50612da8d05d20aa29e140655'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3Ex%3C%21--%20Hi%20there%20--%3E%3C/html%3E%3C%21--%20Again%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22x%22%0A%7C%20%20%20%20%20%3C%21--%20%20Hi%20there%20%20--%3E%0A%7C%20%3C%21--%20%20Again%20%20--%3E"],"f30a9e97cdf3c54ffccaa7b9c2067ff109317530":[async_test('html5lib_webkit01.html f30a9e97cdf3c54ffccaa7b9c2067ff109317530'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3Ex%3C%21--%20Hi%20there%20--%3E%3C/body%3E%3C/html%3E%3C%21--%20Again%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22x%22%0A%7C%20%20%20%20%20%3C%21--%20%20Hi%20there%20%20--%3E%0A%7C%20%3C%21--%20%20Again%20%20--%3E"],"0d99b69e40dbb898cd4a188aa4920042c30815b4":[async_test('html5lib_webkit01.html 0d99b69e40dbb898cd4a188aa4920042c30815b4'), "%3Chtml%3E%3Cbody%3E%3Cruby%3E%3Cdiv%3E%3Crp%3Exx%3C/rp%3E%3C/div%3E%3C/ruby%3E%3C/body%3E%3C/html%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cruby%3E%0A%7C%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Crp%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22xx%22"],"a20991a86f6d34fd67ddb4002e3972d82230d879":[async_test('html5lib_webkit01.html a20991a86f6d34fd67ddb4002e3972d82230d879'), "%3Chtml%3E%3Cbody%3E%3Cruby%3E%3Cdiv%3E%3Crt%3Exx%3C/rt%3E%3C/div%3E%3C/ruby%3E%3C/body%3E%3C/html%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cruby%3E%0A%7C%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Crt%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22xx%22"],"006dbf89bfa3df51d837e7557c3e32dfbc6f0f4c":[async_test('html5lib_webkit01.html 006dbf89bfa3df51d837e7557c3e32dfbc6f0f4c'), "%3Chtml%3E%3Cframeset%3E%3C%21--1--%3E%3Cnoframes%3EA%3C/noframes%3E%3C%21--2--%3E%3C/frameset%3E%3C%21--3--%3E%3Cnoframes%3EB%3C/noframes%3E%3C%21--4--%3E%3C/html%3E%3C%21--5--%3E%3Cnoframes%3EC%3C/noframes%3E%3C%21--6--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cframeset%3E%0A%7C%20%20%20%20%20%3C%21--%201%20--%3E%0A%7C%20%20%20%20%20%3Cnoframes%3E%0A%7C%20%20%20%20%20%20%20%22A%22%0A%7C%20%20%20%20%20%3C%21--%202%20--%3E%0A%7C%20%20%20%3C%21--%203%20--%3E%0A%7C%20%20%20%3Cnoframes%3E%0A%7C%20%20%20%20%20%22B%22%0A%7C%20%20%20%3C%21--%204%20--%3E%0A%7C%20%20%20%3Cnoframes%3E%0A%7C%20%20%20%20%20%22C%22%0A%7C%20%3C%21--%205%20--%3E%0A%7C%20%3C%21--%206%20--%3E"],"7e8f1399f9c87dbd103303c6051873079b265360":[async_test('html5lib_webkit01.html 7e8f1399f9c87dbd103303c6051873079b265360'), "%3Cselect%3E%3Coption%3EA%3Cselect%3E%3Coption%3EB%3Cselect%3E%3Coption%3EC%3Cselect%3E%3Coption%3ED%3Cselect%3E%3Coption%3EE%3Cselect%3E%3Coption%3EF%3Cselect%3E%3Coption%3EG%3Cselect%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%22A%22%0A%7C%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%22B%22%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22C%22%0A%7C%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%22D%22%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22E%22%0A%7C%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%22F%22%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22G%22"],"5081f4afe652b92f23e80d275f67dec9139df8e3":[async_test('html5lib_webkit01.html 5081f4afe652b92f23e80d275f67dec9139df8e3'), "%3Cdd%3E%3Cdd%3E%3Cdt%3E%3Cdt%3E%3Cdd%3E%3Cli%3E%3Cli%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdd%3E%0A%7C%20%20%20%20%20%3Cdd%3E%0A%7C%20%20%20%20%20%3Cdt%3E%0A%7C%20%20%20%20%20%3Cdt%3E%0A%7C%20%20%20%20%20%3Cdd%3E%0A%7C%20%20%20%20%20%20%20%3Cli%3E%0A%7C%20%20%20%20%20%20%20%3Cli%3E"],"f904db0ad0c00794f8a2ca238b4c36084993c741":[async_test('html5lib_webkit01.html f904db0ad0c00794f8a2ca238b4c36084993c741'), "%3Cdiv%3E%3Cb%3E%3C/div%3E%3Cdiv%3E%3Cnobr%3Ea%3Cnobr%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cnobr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22a%22%0A%7C%20%20%20%20%20%20%20%20%20%3Cnobr%3E"],"d56fcf271bf902fc4739f055f031f0d11620057c":[async_test('html5lib_webkit01.html d56fcf271bf902fc4739f055f031f0d11620057c'), "%3Chead%3E%3C/head%3E%0A%3Cbody%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%22%0A%22%0A%7C%20%20%20%3Cbody%3E"],"a897ca0ad0492945709d0772c91e33d485ddf9c7":[async_test('html5lib_webkit01.html a897ca0ad0492945709d0772c91e33d485ddf9c7'), "%3Chead%3E%3C/head%3E%20%3Cstyle%3E%3C/style%3Eddd", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Cstyle%3E%0A%7C%20%20%20%22%20%22%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22ddd%22"],"7274654c671e2e1715a017a239a98399496b7ba6":[async_test('html5lib_webkit01.html 7274654c671e2e1715a017a239a98399496b7ba6'), "%3Ckbd%3E%3Ctable%3E%3C/kbd%3E%3Ccol%3E%3Cselect%3E%3Ctr%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ckbd%3E%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"346ed4219453716e3fee23ccddf283fde408d349":[async_test('html5lib_webkit01.html 346ed4219453716e3fee23ccddf283fde408d349'), "%3Ckbd%3E%3Ctable%3E%3C/kbd%3E%3Ccol%3E%3Cselect%3E%3Ctr%3E%3C/table%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ckbd%3E%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%3Cdiv%3E"],"4d1b6f58e6bb11d27e2097f656abdd1122a45a67":[async_test('html5lib_webkit01.html 4d1b6f58e6bb11d27e2097f656abdd1122a45a67'), "%3Ca%3E%3Cli%3E%3Cstyle%3E%3C/style%3E%3Ctitle%3E%3C/title%3E%3C/a%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%3Cli%3E%0A%7C%20%20%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cstyle%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctitle%3E"],"bb7bc3a43938aef67cffb49084f27cc678cd9b7a":[async_test('html5lib_webkit01.html bb7bc3a43938aef67cffb49084f27cc678cd9b7a'), "%3Cfont%3E%3C/p%3E%3Cp%3E%3Cmeta%3E%3Ctitle%3E%3C/title%3E%3C/font%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfont%3E%0A%7C%20%20%20%20%20%20%20%3Cp%3E%0A%7C%20%20%20%20%20%3Cp%3E%0A%7C%20%20%20%20%20%20%20%3Cfont%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cmeta%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctitle%3E"],"992947d22821e1eb7b9116a99420b6c7f5ad46f2":[async_test('html5lib_webkit01.html 992947d22821e1eb7b9116a99420b6c7f5ad46f2'), "%3Ca%3E%3Ccenter%3E%3Ctitle%3E%3C/title%3E%3Ca%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%3Ccenter%3E%0A%7C%20%20%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctitle%3E%0A%7C%20%20%20%20%20%20%20%3Ca%3E"],"88eca99701e0ad1fda391722e5f0cdcf1e2b667d":[async_test('html5lib_webkit01.html 88eca99701e0ad1fda391722e5f0cdcf1e2b667d'), "%3Csvg%3E%3Ctitle%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20title%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"4b36a9545e5d8df93c447eaa8b1dc42d704d9c61":[async_test('html5lib_webkit01.html 4b36a9545e5d8df93c447eaa8b1dc42d704d9c61'), "%3Csvg%3E%3Ctitle%3E%3Crect%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20title%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Crect%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"dc2437252e38b998fec43311653af309a65ef35f":[async_test('html5lib_webkit01.html dc2437252e38b998fec43311653af309a65ef35f'), "%3Csvg%3E%3Ctitle%3E%3Csvg%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20title%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"ec499b1124d241faaa28e2f985ecf5f3fa00fcf8":[async_test('html5lib_webkit01.html ec499b1124d241faaa28e2f985ecf5f3fa00fcf8'), "%3Cimg%20%3C%3D%22%22%20FAIL%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cimg%3E%0A%7C%20%20%20%20%20%20%20%3C%3D%22%22%0A%7C%20%20%20%20%20%20%20fail%3D%22%22"],"cd236e537fa5d967d11efea30d96cd6ef6c9f46b":[async_test('html5lib_webkit01.html cd236e537fa5d967d11efea30d96cd6ef6c9f46b'), "%3Cul%3E%3Cli%3E%3Cdiv%20id%3D%27foo%27/%3EA%3C/li%3E%3Cli%3EB%3Cdiv%3EC%3C/div%3E%3C/li%3E%3C/ul%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cul%3E%0A%7C%20%20%20%20%20%20%20%3Cli%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20id%3D%22foo%22%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22A%22%0A%7C%20%20%20%20%20%20%20%3Cli%3E%0A%7C%20%20%20%20%20%20%20%20%20%22B%22%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22C%22"],"2ee90ed930fca8db8278161af28adde1e0c3907b":[async_test('html5lib_webkit01.html 2ee90ed930fca8db8278161af28adde1e0c3907b'), "%3Csvg%3E%3Cem%3E%3Cdesc%3E%3C/em%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%3Cdesc%3E"],"9804e9659cd045f199d9f58ef85c2639724359aa":[async_test('html5lib_webkit01.html 9804e9659cd045f199d9f58ef85c2639724359aa'), "%3Ctable%3E%3Ctr%3E%3Ctd%3E%3Csvg%3E%3Cdesc%3E%3Ctd%3E%3C/desc%3E%3Ccircle%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20desc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccircle%3E"],"a785e349a36349db19df18c06032315c6356486c":[async_test('html5lib_webkit01.html a785e349a36349db19df18c06032315c6356486c'), "%3Csvg%3E%3Ctfoot%3E%3C/mi%3E%3Ctd%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20tfoot%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Csvg%20td%3E"],"401c8625b8574b46d03b8e95acd29358c82b53d3":[async_test('html5lib_webkit01.html 401c8625b8574b46d03b8e95acd29358c82b53d3'), "%3Cmath%3E%3Cmrow%3E%3Cmrow%3E%3Cmn%3E1%3C/mn%3E%3C/mrow%3E%3Cmi%3Ea%3C/mi%3E%3C/mrow%3E%3C/math%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cmath%20math%3E%0A%7C%20%20%20%20%20%20%20%3Cmath%20mrow%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cmath%20mrow%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cmath%20mn%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%221%22%0A%7C%20%20%20%20%20%20%20%20%20%3Cmath%20mi%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22a%22"],"1390b296dc6152683e9de9820194bca39e18cbd6":[async_test('html5lib_webkit01.html 1390b296dc6152683e9de9820194bca39e18cbd6'), "%3C%21doctype%20html%3E%3Cinput%20type%3D%22hidden%22%3E%3Cframeset%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cframeset%3E"],"7dc7e88fa9eba71234bdb4037a15a4f70183a466":[async_test('html5lib_webkit01.html 7dc7e88fa9eba71234bdb4037a15a4f70183a466'), "%3C%21doctype%20html%3E%3Cinput%20type%3D%22button%22%3E%3Cframeset%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cinput%3E%0A%7C%20%20%20%20%20%20%20type%3D%22button%22"], + "4235382bf15f93f7dd1096832ae74cc71edef4d7":[async_test('html5lib_webkit01.html 4235382bf15f93f7dd1096832ae74cc71edef4d7'), "Test", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22Test%22"],"9906bb30ae08654f4c67bf6d97040abbca91082d":[async_test('html5lib_webkit01.html 9906bb30ae08654f4c67bf6d97040abbca91082d'), "%3Cdiv%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E"],"97974a9c541d97c7bb5bd8ba97c2ccbe0c6e55bd":[async_test('html5lib_webkit01.html 97974a9c541d97c7bb5bd8ba97c2ccbe0c6e55bd'), "%3Cdiv%3ETest%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Test%22"],"f30960ce7d5b25adc846e47823f977616d38b296":[async_test('html5lib_webkit01.html f30960ce7d5b25adc846e47823f977616d38b296'), "%3Cdi", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E"],"f3ed3ec3a14058fd97c9aad83299bc8836d21283":[async_test('html5lib_webkit01.html f3ed3ec3a14058fd97c9aad83299bc8836d21283'), "%3Cdiv%3EHello%3C/div%3E%0A%3Cscript%3E%0Aconsole.log%28%22PASS%22%29%3B%0A%3C/script%3E%0A%3Cdiv%3EBye%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Hello%22%0A%7C%20%20%20%20%20%22%0A%22%0A%7C%20%20%20%20%20%3Cscript%3E%0A%7C%20%20%20%20%20%20%20%22%0Aconsole.log%28%22PASS%22%29%3B%0A%22%0A%7C%20%20%20%20%20%22%0A%22%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Bye%22"],"f073fda1df7d917e37a207c326bdc4db0b4b3481":[async_test('html5lib_webkit01.html f073fda1df7d917e37a207c326bdc4db0b4b3481'), "%3Cdiv%20foo%3D%22bar%22%3EHello%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20foo%3D%22bar%22%0A%7C%20%20%20%20%20%20%20%22Hello%22"],"5533bf52e328c5748a203be1bb245848de592783":[async_test('html5lib_webkit01.html 5533bf52e328c5748a203be1bb245848de592783'), "%3Cdiv%3EHello%3C/div%3E%0A%3Cscript%3E%0Aconsole.log%28%22FOO%3Cspan%3EBAR%3C/span%3EBAZ%22%29%3B%0A%3C/script%3E%0A%3Cdiv%3EBye%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Hello%22%0A%7C%20%20%20%20%20%22%0A%22%0A%7C%20%20%20%20%20%3Cscript%3E%0A%7C%20%20%20%20%20%20%20%22%0Aconsole.log%28%22FOO%3Cspan%3EBAR%3C/span%3EBAZ%22%29%3B%0A%22%0A%7C%20%20%20%20%20%22%0A%22%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%22Bye%22"],"5b753a783c228a1b423152d9707cf900e57bc5da":[async_test('html5lib_webkit01.html 5b753a783c228a1b423152d9707cf900e57bc5da'), "%3Cfoo%20bar%3D%22baz%22%3E%3C/foo%3E%3Cpotato%20quack%3D%22duck%22%3E%3C/potato%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20bar%3D%22baz%22%0A%7C%20%20%20%20%20%3Cpotato%3E%0A%7C%20%20%20%20%20%20%20quack%3D%22duck%22"],"eea9ac89544ec31fb78f7629ea0e065bd7422c98":[async_test('html5lib_webkit01.html eea9ac89544ec31fb78f7629ea0e065bd7422c98'), "%3Cfoo%20bar%3D%22baz%22%3E%3Cpotato%20quack%3D%22duck%22%3E%3C/potato%3E%3C/foo%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20bar%3D%22baz%22%0A%7C%20%20%20%20%20%20%20%3Cpotato%3E%0A%7C%20%20%20%20%20%20%20%20%20quack%3D%22duck%22"],"03a99ca235d60b3191a3c5671ff7df5ffca5372d":[async_test('html5lib_webkit01.html 03a99ca235d60b3191a3c5671ff7df5ffca5372d'), "%3Cfoo%3E%3C/foo%20bar%3D%22baz%22%3E%3Cpotato%3E%3C/potato%20quack%3D%22duck%22%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Cpotato%3E"],"c37bc2e44b2765025f58c9680a560c1a3dc3ab93":[async_test('html5lib_webkit01.html c37bc2e44b2765025f58c9680a560c1a3dc3ab93'), "%3C/%20tttt%3E", "%23document%0A%7C%20%3C%21--%20%20tttt%20--%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E"],"c6b4dc9c0041dd5a069741dbf228f03439115b8d":[async_test('html5lib_webkit01.html c6b4dc9c0041dd5a069741dbf228f03439115b8d'), "%3Cdiv%20FOO%20%3E%3Cimg%3E%3Cimg%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20foo%3D%22%22%0A%7C%20%20%20%20%20%20%20%3Cimg%3E%0A%7C%20%20%20%20%20%20%20%3Cimg%3E"],"d4613a2b82f5d4ec251149508096f8071a8714d5":[async_test('html5lib_webkit01.html d4613a2b82f5d4ec251149508096f8071a8714d5'), "%3Cp%3ETest%3C/p%3Cp%3ETest2%3C/p%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cp%3E%0A%7C%20%20%20%20%20%20%20%22TestTest2%22"],"0f78a3fae382185ef9ac8f767efafb401249c1e1":[async_test('html5lib_webkit01.html 0f78a3fae382185ef9ac8f767efafb401249c1e1'), "%3Crdar%3A//problem/6869687%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Crdar%3A%3E%0A%7C%20%20%20%20%20%20%206869687%3D%22%22%0A%7C%20%20%20%20%20%20%20problem%3D%22%22"],"375260e547e078df727a3669f5c8dcef7ccf71a7":[async_test('html5lib_webkit01.html 375260e547e078df727a3669f5c8dcef7ccf71a7'), "%3CA%3Etest%3C%20/A%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%22test%3C%20/A%3E%22"],"3bea2bf663be5de2bbcdad57ac95c5933e266d42":[async_test('html5lib_webkit01.html 3bea2bf663be5de2bbcdad57ac95c5933e266d42'), "%26lt%3B", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22%3C%22"],"19944775fd9dd871fbc4cf813eb105c29bc5d834":[async_test('html5lib_webkit01.html 19944775fd9dd871fbc4cf813eb105c29bc5d834'), "%3Cbody%20foo%3D%27bar%27%3E%3Cbody%20foo%3D%27baz%27%20yo%3D%27mama%27%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20foo%3D%22bar%22%0A%7C%20%20%20%20%20yo%3D%22mama%22"],"25b53e528a0ad0b002c8a26b7260213a24981860":[async_test('html5lib_webkit01.html 25b53e528a0ad0b002c8a26b7260213a24981860'), "%3Cbody%3E%3C/br%20foo%3D%22bar%22%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cbr%3E"],"ce59a8ae9cf138cb81fd017711097d1643c6f227":[async_test('html5lib_webkit01.html ce59a8ae9cf138cb81fd017711097d1643c6f227'), "%3Cbdy%3E%3Cbr%20foo%3D%22bar%22%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cbdy%3E%0A%7C%20%20%20%20%20%20%20%3Cbr%3E%0A%7C%20%20%20%20%20%20%20%20%20foo%3D%22bar%22"],"913071287591cc570d512c824b419d9a172d4339":[async_test('html5lib_webkit01.html 913071287591cc570d512c824b419d9a172d4339'), "%3Cbody%3E%3C/body%3E%3C/br%20foo%3D%22bar%22%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cbr%3E"],"2669743ff272e43978ac0f8a2f2c602ec9036c26":[async_test('html5lib_webkit01.html 2669743ff272e43978ac0f8a2f2c602ec9036c26'), "%3Cbdy%3E%3C/body%3E%3Cbr%20foo%3D%22bar%22%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cbdy%3E%0A%7C%20%20%20%20%20%20%20%3Cbr%3E%0A%7C%20%20%20%20%20%20%20%20%20foo%3D%22bar%22"],"a9e759bf3ce415ad6216c58ee906639c03ffa03f":[async_test('html5lib_webkit01.html a9e759bf3ce415ad6216c58ee906639c03ffa03f'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3E%3C%21--%20Hi%20there%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%3C%21--%20%20Hi%20there%20%20--%3E"],"1274e8cdad6a8957fa9b02708ee58b73de41ae02":[async_test('html5lib_webkit01.html 1274e8cdad6a8957fa9b02708ee58b73de41ae02'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3E%3C%21--%20Comment%20A%20--%3E%3C%21--%20Comment%20B%20--%3E%3C%21--%20Comment%20C%20--%3E%3C%21--%20Comment%20D%20--%3E%3C%21--%20Comment%20E%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%3C%21--%20%20Comment%20A%20%20--%3E%0A%7C%20%3C%21--%20%20Comment%20B%20%20--%3E%0A%7C%20%3C%21--%20%20Comment%20C%20%20--%3E%0A%7C%20%3C%21--%20%20Comment%20D%20%20--%3E%0A%7C%20%3C%21--%20%20Comment%20E%20%20--%3E"],"bbbea9a3752a36a64f2b62f15383406b16113fe7":[async_test('html5lib_webkit01.html bbbea9a3752a36a64f2b62f15383406b16113fe7'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3Ex%3C%21--%20Hi%20there%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22x%22%0A%7C%20%20%20%20%20%3C%21--%20%20Hi%20there%20%20--%3E"],"e0910f26aac678f50612da8d05d20aa29e140655":[async_test('html5lib_webkit01.html e0910f26aac678f50612da8d05d20aa29e140655'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3Ex%3C%21--%20Hi%20there%20--%3E%3C/html%3E%3C%21--%20Again%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22x%22%0A%7C%20%20%20%20%20%3C%21--%20%20Hi%20there%20%20--%3E%0A%7C%20%3C%21--%20%20Again%20%20--%3E"],"f30a9e97cdf3c54ffccaa7b9c2067ff109317530":[async_test('html5lib_webkit01.html f30a9e97cdf3c54ffccaa7b9c2067ff109317530'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3Ex%3C%21--%20Hi%20there%20--%3E%3C/body%3E%3C/html%3E%3C%21--%20Again%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22x%22%0A%7C%20%20%20%20%20%3C%21--%20%20Hi%20there%20%20--%3E%0A%7C%20%3C%21--%20%20Again%20%20--%3E"],"f71e076cf210f54ee646d71fca7a8de5322149ff":[async_test('html5lib_webkit01.html f71e076cf210f54ee646d71fca7a8de5322149ff'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%0A%20%20%20%3C%21--%20Hi%20there%20--%3E%3C/html%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22%0A%20%20%20%22%0A%7C%20%20%20%3C%21--%20%20Hi%20there%20%20--%3E"],"1b6a0afa648100ebd5f8b6719b4d8c5887f3f732":[async_test('html5lib_webkit01.html 1b6a0afa648100ebd5f8b6719b4d8c5887f3f732'), "%3Chtml%3E%3Cbody%3E%3C/body%3E%3C/html%3E%0A%20%20%20%3C%21--%20Hi%20there%20--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22%0A%20%20%20%22%0A%7C%20%3C%21--%20%20Hi%20there%20%20--%3E"],"0d99b69e40dbb898cd4a188aa4920042c30815b4":[async_test('html5lib_webkit01.html 0d99b69e40dbb898cd4a188aa4920042c30815b4'), "%3Chtml%3E%3Cbody%3E%3Cruby%3E%3Cdiv%3E%3Crp%3Exx%3C/rp%3E%3C/div%3E%3C/ruby%3E%3C/body%3E%3C/html%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cruby%3E%0A%7C%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Crp%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22xx%22"],"a20991a86f6d34fd67ddb4002e3972d82230d879":[async_test('html5lib_webkit01.html a20991a86f6d34fd67ddb4002e3972d82230d879'), "%3Chtml%3E%3Cbody%3E%3Cruby%3E%3Cdiv%3E%3Crt%3Exx%3C/rt%3E%3C/div%3E%3C/ruby%3E%3C/body%3E%3C/html%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cruby%3E%0A%7C%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Crt%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22xx%22"],"006dbf89bfa3df51d837e7557c3e32dfbc6f0f4c":[async_test('html5lib_webkit01.html 006dbf89bfa3df51d837e7557c3e32dfbc6f0f4c'), "%3Chtml%3E%3Cframeset%3E%3C%21--1--%3E%3Cnoframes%3EA%3C/noframes%3E%3C%21--2--%3E%3C/frameset%3E%3C%21--3--%3E%3Cnoframes%3EB%3C/noframes%3E%3C%21--4--%3E%3C/html%3E%3C%21--5--%3E%3Cnoframes%3EC%3C/noframes%3E%3C%21--6--%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cframeset%3E%0A%7C%20%20%20%20%20%3C%21--%201%20--%3E%0A%7C%20%20%20%20%20%3Cnoframes%3E%0A%7C%20%20%20%20%20%20%20%22A%22%0A%7C%20%20%20%20%20%3C%21--%202%20--%3E%0A%7C%20%20%20%3C%21--%203%20--%3E%0A%7C%20%20%20%3Cnoframes%3E%0A%7C%20%20%20%20%20%22B%22%0A%7C%20%20%20%3C%21--%204%20--%3E%0A%7C%20%20%20%3Cnoframes%3E%0A%7C%20%20%20%20%20%22C%22%0A%7C%20%3C%21--%205%20--%3E%0A%7C%20%3C%21--%206%20--%3E"],"7e8f1399f9c87dbd103303c6051873079b265360":[async_test('html5lib_webkit01.html 7e8f1399f9c87dbd103303c6051873079b265360'), "%3Cselect%3E%3Coption%3EA%3Cselect%3E%3Coption%3EB%3Cselect%3E%3Coption%3EC%3Cselect%3E%3Coption%3ED%3Cselect%3E%3Coption%3EE%3Cselect%3E%3Coption%3EF%3Cselect%3E%3Coption%3EG%3Cselect%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%22A%22%0A%7C%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%22B%22%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22C%22%0A%7C%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%22D%22%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22E%22%0A%7C%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%22F%22%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Coption%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22G%22"],"5081f4afe652b92f23e80d275f67dec9139df8e3":[async_test('html5lib_webkit01.html 5081f4afe652b92f23e80d275f67dec9139df8e3'), "%3Cdd%3E%3Cdd%3E%3Cdt%3E%3Cdt%3E%3Cdd%3E%3Cli%3E%3Cli%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdd%3E%0A%7C%20%20%20%20%20%3Cdd%3E%0A%7C%20%20%20%20%20%3Cdt%3E%0A%7C%20%20%20%20%20%3Cdt%3E%0A%7C%20%20%20%20%20%3Cdd%3E%0A%7C%20%20%20%20%20%20%20%3Cli%3E%0A%7C%20%20%20%20%20%20%20%3Cli%3E"],"f904db0ad0c00794f8a2ca238b4c36084993c741":[async_test('html5lib_webkit01.html f904db0ad0c00794f8a2ca238b4c36084993c741'), "%3Cdiv%3E%3Cb%3E%3C/div%3E%3Cdiv%3E%3Cnobr%3Ea%3Cnobr%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cnobr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22a%22%0A%7C%20%20%20%20%20%20%20%20%20%3Cnobr%3E"],"d56fcf271bf902fc4739f055f031f0d11620057c":[async_test('html5lib_webkit01.html d56fcf271bf902fc4739f055f031f0d11620057c'), "%3Chead%3E%3C/head%3E%0A%3Cbody%3E%3C/body%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%22%0A%22%0A%7C%20%20%20%3Cbody%3E"],"a897ca0ad0492945709d0772c91e33d485ddf9c7":[async_test('html5lib_webkit01.html a897ca0ad0492945709d0772c91e33d485ddf9c7'), "%3Chead%3E%3C/head%3E%20%3Cstyle%3E%3C/style%3Eddd", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%20%20%3Cstyle%3E%0A%7C%20%20%20%22%20%22%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22ddd%22"],"7274654c671e2e1715a017a239a98399496b7ba6":[async_test('html5lib_webkit01.html 7274654c671e2e1715a017a239a98399496b7ba6'), "%3Ckbd%3E%3Ctable%3E%3C/kbd%3E%3Ccol%3E%3Cselect%3E%3Ctr%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ckbd%3E%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E"],"346ed4219453716e3fee23ccddf283fde408d349":[async_test('html5lib_webkit01.html 346ed4219453716e3fee23ccddf283fde408d349'), "%3Ckbd%3E%3Ctable%3E%3C/kbd%3E%3Ccol%3E%3Cselect%3E%3Ctr%3E%3C/table%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ckbd%3E%0A%7C%20%20%20%20%20%20%20%3Cselect%3E%0A%7C%20%20%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ccolgroup%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ccol%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%3Cdiv%3E"],"4d1b6f58e6bb11d27e2097f656abdd1122a45a67":[async_test('html5lib_webkit01.html 4d1b6f58e6bb11d27e2097f656abdd1122a45a67'), "%3Ca%3E%3Cli%3E%3Cstyle%3E%3C/style%3E%3Ctitle%3E%3C/title%3E%3C/a%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%3Cli%3E%0A%7C%20%20%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cstyle%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctitle%3E"],"bb7bc3a43938aef67cffb49084f27cc678cd9b7a":[async_test('html5lib_webkit01.html bb7bc3a43938aef67cffb49084f27cc678cd9b7a'), "%3Cfont%3E%3C/p%3E%3Cp%3E%3Cmeta%3E%3Ctitle%3E%3C/title%3E%3C/font%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfont%3E%0A%7C%20%20%20%20%20%20%20%3Cp%3E%0A%7C%20%20%20%20%20%3Cp%3E%0A%7C%20%20%20%20%20%20%20%3Cfont%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cmeta%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctitle%3E"],"992947d22821e1eb7b9116a99420b6c7f5ad46f2":[async_test('html5lib_webkit01.html 992947d22821e1eb7b9116a99420b6c7f5ad46f2'), "%3Ca%3E%3Ccenter%3E%3Ctitle%3E%3C/title%3E%3Ca%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%3Ccenter%3E%0A%7C%20%20%20%20%20%20%20%3Ca%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctitle%3E%0A%7C%20%20%20%20%20%20%20%3Ca%3E"],"88eca99701e0ad1fda391722e5f0cdcf1e2b667d":[async_test('html5lib_webkit01.html 88eca99701e0ad1fda391722e5f0cdcf1e2b667d'), "%3Csvg%3E%3Ctitle%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20title%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"4b36a9545e5d8df93c447eaa8b1dc42d704d9c61":[async_test('html5lib_webkit01.html 4b36a9545e5d8df93c447eaa8b1dc42d704d9c61'), "%3Csvg%3E%3Ctitle%3E%3Crect%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20title%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Crect%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"dc2437252e38b998fec43311653af309a65ef35f":[async_test('html5lib_webkit01.html dc2437252e38b998fec43311653af309a65ef35f'), "%3Csvg%3E%3Ctitle%3E%3Csvg%3E%3Cdiv%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20title%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"ec499b1124d241faaa28e2f985ecf5f3fa00fcf8":[async_test('html5lib_webkit01.html ec499b1124d241faaa28e2f985ecf5f3fa00fcf8'), "%3Cimg%20%3C%3D%22%22%20FAIL%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cimg%3E%0A%7C%20%20%20%20%20%20%20%3C%3D%22%22%0A%7C%20%20%20%20%20%20%20fail%3D%22%22"],"cd236e537fa5d967d11efea30d96cd6ef6c9f46b":[async_test('html5lib_webkit01.html cd236e537fa5d967d11efea30d96cd6ef6c9f46b'), "%3Cul%3E%3Cli%3E%3Cdiv%20id%3D%27foo%27/%3EA%3C/li%3E%3Cli%3EB%3Cdiv%3EC%3C/div%3E%3C/li%3E%3C/ul%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cul%3E%0A%7C%20%20%20%20%20%20%20%3Cli%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20id%3D%22foo%22%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22A%22%0A%7C%20%20%20%20%20%20%20%3Cli%3E%0A%7C%20%20%20%20%20%20%20%20%20%22B%22%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22C%22"],"2ee90ed930fca8db8278161af28adde1e0c3907b":[async_test('html5lib_webkit01.html 2ee90ed930fca8db8278161af28adde1e0c3907b'), "%3Csvg%3E%3Cem%3E%3Cdesc%3E%3C/em%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%3Cdesc%3E"],"9804e9659cd045f199d9f58ef85c2639724359aa":[async_test('html5lib_webkit01.html 9804e9659cd045f199d9f58ef85c2639724359aa'), "%3Ctable%3E%3Ctr%3E%3Ctd%3E%3Csvg%3E%3Cdesc%3E%3Ctd%3E%3C/desc%3E%3Ccircle%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20desc%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ccircle%3E"],"a785e349a36349db19df18c06032315c6356486c":[async_test('html5lib_webkit01.html a785e349a36349db19df18c06032315c6356486c'), "%3Csvg%3E%3Ctfoot%3E%3C/mi%3E%3Ctd%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20tfoot%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Csvg%20td%3E"],"401c8625b8574b46d03b8e95acd29358c82b53d3":[async_test('html5lib_webkit01.html 401c8625b8574b46d03b8e95acd29358c82b53d3'), "%3Cmath%3E%3Cmrow%3E%3Cmrow%3E%3Cmn%3E1%3C/mn%3E%3C/mrow%3E%3Cmi%3Ea%3C/mi%3E%3C/mrow%3E%3C/math%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cmath%20math%3E%0A%7C%20%20%20%20%20%20%20%3Cmath%20mrow%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cmath%20mrow%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cmath%20mn%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%221%22%0A%7C%20%20%20%20%20%20%20%20%20%3Cmath%20mi%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22a%22"],"1390b296dc6152683e9de9820194bca39e18cbd6":[async_test('html5lib_webkit01.html 1390b296dc6152683e9de9820194bca39e18cbd6'), "%3C%21doctype%20html%3E%3Cinput%20type%3D%22hidden%22%3E%3Cframeset%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cframeset%3E"],"7dc7e88fa9eba71234bdb4037a15a4f70183a466":[async_test('html5lib_webkit01.html 7dc7e88fa9eba71234bdb4037a15a4f70183a466'), "%3C%21doctype%20html%3E%3Cinput%20type%3D%22button%22%3E%3Cframeset%3E", "%23document%0A%7C%20%3C%21DOCTYPE%20html%3E%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cinput%3E%0A%7C%20%20%20%20%20%20%20type%3D%22button%22"], } init_tests(get_type()); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02.html b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02.html index 55ee1aad..5c9bf4ef 100644 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02.html +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02.html
@@ -18,9 +18,9 @@ <script src="/resources/testharnessreport.js"></script> <script> var num_iframes = 8; - var order = ['f50b8c15847159a6d2c6ecc2bd1e4a944ba5aae6','326328ea805a2ebdde707e08567713f88a4cf8ab','05138397908cfdad69a3bfe5da5a06098320b504','2aaa2ac0d7cec6144633d8f82f3bcaafa7498cd9','4a256d7ef602c7c917c758e15981b9710f9b4130','98cea04429ddbe4ffaaa0b91fe77b8c0b1f7c1f4','209ad7d6f6c9c53cb856c7d78b2bc4a7f38abd5f','cb9a86fbac96b08a6e708a2dbcd9f78539dfe9c6','c46a4badc6b1ebc524e6f90ea56183310e93ab25','464eeaecc49646ff810cadad537880c9b473a262','7b4eb6981451ede406f2f4112e83a8584e7adbf5','73aed96d7cd3116e4a3e701104616c07d1ec5e0c','139a546c72bfcedf638d031f33da43f24995f688','6e33515b4dc011dd390d433a6358bf68b786b1fd','b6d2377b0dd710ca812c97b2b65cb5d2e93b0e5b','21a5b2b413c4db8ed588334b9a50dea9872bbcfa','90d3f6f2dff994f63293ca46f7cd50a75cde96a6',]; + var order = ['f50b8c15847159a6d2c6ecc2bd1e4a944ba5aae6','326328ea805a2ebdde707e08567713f88a4cf8ab','05138397908cfdad69a3bfe5da5a06098320b504','2aaa2ac0d7cec6144633d8f82f3bcaafa7498cd9','4a256d7ef602c7c917c758e15981b9710f9b4130','98cea04429ddbe4ffaaa0b91fe77b8c0b1f7c1f4','209ad7d6f6c9c53cb856c7d78b2bc4a7f38abd5f','cb9a86fbac96b08a6e708a2dbcd9f78539dfe9c6','c46a4badc6b1ebc524e6f90ea56183310e93ab25','464eeaecc49646ff810cadad537880c9b473a262','7b4eb6981451ede406f2f4112e83a8584e7adbf5','73aed96d7cd3116e4a3e701104616c07d1ec5e0c','139a546c72bfcedf638d031f33da43f24995f688','6e33515b4dc011dd390d433a6358bf68b786b1fd','b6d2377b0dd710ca812c97b2b65cb5d2e93b0e5b','21a5b2b413c4db8ed588334b9a50dea9872bbcfa','90d3f6f2dff994f63293ca46f7cd50a75cde96a6','3e6b37a5fd0b16769f71f8e6a022ef6a972769d0','66c5e72324003827309d3590a9ba56412ba68f79','329d2522353afa12afea478bbfafdb0ff0656572',]; var tests = { - "f50b8c15847159a6d2c6ecc2bd1e4a944ba5aae6":[async_test('html5lib_webkit02.html f50b8c15847159a6d2c6ecc2bd1e4a944ba5aae6'), "%3Cfoo%20bar%3Dqux/%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20bar%3D%22qux/%22"],"326328ea805a2ebdde707e08567713f88a4cf8ab":[async_test('html5lib_webkit02.html 326328ea805a2ebdde707e08567713f88a4cf8ab'), "%3Cp%20id%3D%22status%22%3E%3Cnoscript%3E%3Cstrong%3EA%3C/strong%3E%3C/noscript%3E%3Cspan%3EB%3C/span%3E%3C/p%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cp%3E%0A%7C%20%20%20%20%20%20%20id%3D%22status%22%0A%7C%20%20%20%20%20%20%20%3Cnoscript%3E%0A%7C%20%20%20%20%20%20%20%20%20%22%3Cstrong%3EA%3C/strong%3E%22%0A%7C%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%20%20%22B%22"],"05138397908cfdad69a3bfe5da5a06098320b504":[async_test('html5lib_webkit02.html 05138397908cfdad69a3bfe5da5a06098320b504'), "%3Cdiv%3E%3Csarcasm%3E%3Cdiv%3E%3C/div%3E%3C/sarcasm%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Csarcasm%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"2aaa2ac0d7cec6144633d8f82f3bcaafa7498cd9":[async_test('html5lib_webkit02.html 2aaa2ac0d7cec6144633d8f82f3bcaafa7498cd9'), "%3Chtml%3E%3Cbody%3E%3Cimg%20src%3D%22%22%20border%3D%220%22%20alt%3D%22%3E%3Cdiv%3EA%3C/div%3E%3C/body%3E%3C/html%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E"],"4a256d7ef602c7c917c758e15981b9710f9b4130":[async_test('html5lib_webkit02.html 4a256d7ef602c7c917c758e15981b9710f9b4130'), "%3Ctable%3E%3Ctd%3E%3C/tbody%3EA", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22A%22%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"98cea04429ddbe4ffaaa0b91fe77b8c0b1f7c1f4":[async_test('html5lib_webkit02.html 98cea04429ddbe4ffaaa0b91fe77b8c0b1f7c1f4'), "%3Ctable%3E%3Ctd%3E%3C/thead%3EA", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22A%22"],"209ad7d6f6c9c53cb856c7d78b2bc4a7f38abd5f":[async_test('html5lib_webkit02.html 209ad7d6f6c9c53cb856c7d78b2bc4a7f38abd5f'), "%3Ctable%3E%3Ctd%3E%3C/tfoot%3EA", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22A%22"],"cb9a86fbac96b08a6e708a2dbcd9f78539dfe9c6":[async_test('html5lib_webkit02.html cb9a86fbac96b08a6e708a2dbcd9f78539dfe9c6'), "%3Ctable%3E%3Cthead%3E%3Ctd%3E%3C/tbody%3EA", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22A%22"],"c46a4badc6b1ebc524e6f90ea56183310e93ab25":[async_test('html5lib_webkit02.html c46a4badc6b1ebc524e6f90ea56183310e93ab25'), "%3Clegend%3Etest%3C/legend%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Clegend%3E%0A%7C%20%20%20%20%20%20%20%22test%22"],"464eeaecc49646ff810cadad537880c9b473a262":[async_test('html5lib_webkit02.html 464eeaecc49646ff810cadad537880c9b473a262'), "%3Ctable%3E%3Cinput%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cinput%3E%0A%7C%20%20%20%20%20%3Ctable%3E"],"7b4eb6981451ede406f2f4112e83a8584e7adbf5":[async_test('html5lib_webkit02.html 7b4eb6981451ede406f2f4112e83a8584e7adbf5'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%3Caside%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cb%3E"],"73aed96d7cd3116e4a3e701104616c07d1ec5e0c":[async_test('html5lib_webkit02.html 73aed96d7cd3116e4a3e701104616c07d1ec5e0c'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E%3C/em%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%3Caside%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cb%3E"],"139a546c72bfcedf638d031f33da43f24995f688":[async_test('html5lib_webkit02.html 139a546c72bfcedf638d031f33da43f24995f688'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Caside%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E"],"6e33515b4dc011dd390d433a6358bf68b786b1fd":[async_test('html5lib_webkit02.html 6e33515b4dc011dd390d433a6358bf68b786b1fd'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E%3C/em%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Caside%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E"],"b6d2377b0dd710ca812c97b2b65cb5d2e93b0e5b":[async_test('html5lib_webkit02.html b6d2377b0dd710ca812c97b2b65cb5d2e93b0e5b'), "%3Csvg%3E%3CforeignObject%3E%3Cdiv%3Efoo%3C/div%3E%3Cplaintext%3E%3C/foreignObject%3E%3C/svg%3E%3Cdiv%3Ebar%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20foreignObject%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22foo%22%0A%7C%20%20%20%20%20%20%20%20%20%3Cplaintext%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22%3C/foreignObject%3E%3C/svg%3E%3Cdiv%3Ebar%3C/div%3E%22"],"21a5b2b413c4db8ed588334b9a50dea9872bbcfa":[async_test('html5lib_webkit02.html 21a5b2b413c4db8ed588334b9a50dea9872bbcfa'), "%3Csvg%3E%3CforeignObject%3E%3C/foreignObject%3E%3Ctitle%3E%3C/svg%3Efoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20foreignObject%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20title%3E%0A%7C%20%20%20%20%20%22foo%22"],"90d3f6f2dff994f63293ca46f7cd50a75cde96a6":[async_test('html5lib_webkit02.html 90d3f6f2dff994f63293ca46f7cd50a75cde96a6'), "%3C/foreignObject%3E%3Cplaintext%3E%3Cdiv%3Efoo%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cplaintext%3E%0A%7C%20%20%20%20%20%20%20%22%3Cdiv%3Efoo%3C/div%3E%22"], + "f50b8c15847159a6d2c6ecc2bd1e4a944ba5aae6":[async_test('html5lib_webkit02.html f50b8c15847159a6d2c6ecc2bd1e4a944ba5aae6'), "%3Cfoo%20bar%3Dqux/%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20bar%3D%22qux/%22"],"326328ea805a2ebdde707e08567713f88a4cf8ab":[async_test('html5lib_webkit02.html 326328ea805a2ebdde707e08567713f88a4cf8ab'), "%3Cp%20id%3D%22status%22%3E%3Cnoscript%3E%3Cstrong%3EA%3C/strong%3E%3C/noscript%3E%3Cspan%3EB%3C/span%3E%3C/p%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cp%3E%0A%7C%20%20%20%20%20%20%20id%3D%22status%22%0A%7C%20%20%20%20%20%20%20%3Cnoscript%3E%0A%7C%20%20%20%20%20%20%20%20%20%22%3Cstrong%3EA%3C/strong%3E%22%0A%7C%20%20%20%20%20%20%20%3Cspan%3E%0A%7C%20%20%20%20%20%20%20%20%20%22B%22"],"05138397908cfdad69a3bfe5da5a06098320b504":[async_test('html5lib_webkit02.html 05138397908cfdad69a3bfe5da5a06098320b504'), "%3Cdiv%3E%3Csarcasm%3E%3Cdiv%3E%3C/div%3E%3C/sarcasm%3E%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%3Csarcasm%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E"],"2aaa2ac0d7cec6144633d8f82f3bcaafa7498cd9":[async_test('html5lib_webkit02.html 2aaa2ac0d7cec6144633d8f82f3bcaafa7498cd9'), "%3Chtml%3E%3Cbody%3E%3Cimg%20src%3D%22%22%20border%3D%220%22%20alt%3D%22%3E%3Cdiv%3EA%3C/div%3E%3C/body%3E%3C/html%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E"],"4a256d7ef602c7c917c758e15981b9710f9b4130":[async_test('html5lib_webkit02.html 4a256d7ef602c7c917c758e15981b9710f9b4130'), "%3Ctable%3E%3Ctd%3E%3C/tbody%3EA", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%22A%22%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E"],"98cea04429ddbe4ffaaa0b91fe77b8c0b1f7c1f4":[async_test('html5lib_webkit02.html 98cea04429ddbe4ffaaa0b91fe77b8c0b1f7c1f4'), "%3Ctable%3E%3Ctd%3E%3C/thead%3EA", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22A%22"],"209ad7d6f6c9c53cb856c7d78b2bc4a7f38abd5f":[async_test('html5lib_webkit02.html 209ad7d6f6c9c53cb856c7d78b2bc4a7f38abd5f'), "%3Ctable%3E%3Ctd%3E%3C/tfoot%3EA", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Ctbody%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22A%22"],"cb9a86fbac96b08a6e708a2dbcd9f78539dfe9c6":[async_test('html5lib_webkit02.html cb9a86fbac96b08a6e708a2dbcd9f78539dfe9c6'), "%3Ctable%3E%3Cthead%3E%3Ctd%3E%3C/tbody%3EA", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Ctable%3E%0A%7C%20%20%20%20%20%20%20%3Cthead%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%22A%22"],"c46a4badc6b1ebc524e6f90ea56183310e93ab25":[async_test('html5lib_webkit02.html c46a4badc6b1ebc524e6f90ea56183310e93ab25'), "%3Clegend%3Etest%3C/legend%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Clegend%3E%0A%7C%20%20%20%20%20%20%20%22test%22"],"464eeaecc49646ff810cadad537880c9b473a262":[async_test('html5lib_webkit02.html 464eeaecc49646ff810cadad537880c9b473a262'), "%3Ctable%3E%3Cinput%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cinput%3E%0A%7C%20%20%20%20%20%3Ctable%3E"],"7b4eb6981451ede406f2f4112e83a8584e7adbf5":[async_test('html5lib_webkit02.html 7b4eb6981451ede406f2f4112e83a8584e7adbf5'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%3Caside%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cb%3E"],"73aed96d7cd3116e4a3e701104616c07d1ec5e0c":[async_test('html5lib_webkit02.html 73aed96d7cd3116e4a3e701104616c07d1ec5e0c'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E%3C/em%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%3Caside%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cb%3E"],"139a546c72bfcedf638d031f33da43f24995f688":[async_test('html5lib_webkit02.html 139a546c72bfcedf638d031f33da43f24995f688'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Caside%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E"],"6e33515b4dc011dd390d433a6358bf68b786b1fd":[async_test('html5lib_webkit02.html 6e33515b4dc011dd390d433a6358bf68b786b1fd'), "%3Cb%3E%3Cem%3E%3Cfoo%3E%3Cfoo%3E%3Cfoo%3E%3Caside%3E%3C/b%3E%3C/em%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%3Cem%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cfoo%3E%0A%7C%20%20%20%20%20%3Caside%3E%0A%7C%20%20%20%20%20%20%20%3Cb%3E"],"b6d2377b0dd710ca812c97b2b65cb5d2e93b0e5b":[async_test('html5lib_webkit02.html b6d2377b0dd710ca812c97b2b65cb5d2e93b0e5b'), "%3Csvg%3E%3CforeignObject%3E%3Cdiv%3Efoo%3C/div%3E%3Cplaintext%3E%3C/foreignObject%3E%3C/svg%3E%3Cdiv%3Ebar%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20foreignObject%3E%0A%7C%20%20%20%20%20%20%20%20%20%3Cdiv%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22foo%22%0A%7C%20%20%20%20%20%20%20%20%20%3Cplaintext%3E%0A%7C%20%20%20%20%20%20%20%20%20%20%20%22%3C/foreignObject%3E%3C/svg%3E%3Cdiv%3Ebar%3C/div%3E%22"],"21a5b2b413c4db8ed588334b9a50dea9872bbcfa":[async_test('html5lib_webkit02.html 21a5b2b413c4db8ed588334b9a50dea9872bbcfa'), "%3Csvg%3E%3CforeignObject%3E%3C/foreignObject%3E%3Ctitle%3E%3C/svg%3Efoo", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20foreignObject%3E%0A%7C%20%20%20%20%20%20%20%3Csvg%20title%3E%0A%7C%20%20%20%20%20%22foo%22"],"90d3f6f2dff994f63293ca46f7cd50a75cde96a6":[async_test('html5lib_webkit02.html 90d3f6f2dff994f63293ca46f7cd50a75cde96a6'), "%3C/foreignObject%3E%3Cplaintext%3E%3Cdiv%3Efoo%3C/div%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cplaintext%3E%0A%7C%20%20%20%20%20%20%20%22%3Cdiv%3Efoo%3C/div%3E%22"],"3e6b37a5fd0b16769f71f8e6a022ef6a972769d0":[async_test('html5lib_webkit02.html 3e6b37a5fd0b16769f71f8e6a022ef6a972769d0'), "%3Csvg%20xml%3Abase%20xml%3Alang%20xml%3Aspace%20xml%3Abaaah%20definitionurl%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Csvg%20svg%3E%0A%7C%20%20%20%20%20%20%20definitionurl%3D%22%22%0A%7C%20%20%20%20%20%20%20xml%20lang%3D%22%22%0A%7C%20%20%20%20%20%20%20xml%20space%3D%22%22%0A%7C%20%20%20%20%20%20%20xml%3Abaaah%3D%22%22%0A%7C%20%20%20%20%20%20%20xml%3Abase%3D%22%22"],"66c5e72324003827309d3590a9ba56412ba68f79":[async_test('html5lib_webkit02.html 66c5e72324003827309d3590a9ba56412ba68f79'), "%3Cmath%20definitionurl%20xlink%3Atitle%20xlink%3Ashow%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cmath%20math%3E%0A%7C%20%20%20%20%20%20%20definitionURL%3D%22%22%0A%7C%20%20%20%20%20%20%20xlink%20show%3D%22%22%0A%7C%20%20%20%20%20%20%20xlink%20title%3D%22%22"],"329d2522353afa12afea478bbfafdb0ff0656572":[async_test('html5lib_webkit02.html 329d2522353afa12afea478bbfafdb0ff0656572'), "%3Cmath%20DEFINITIONURL%3E", "%23document%0A%7C%20%3Chtml%3E%0A%7C%20%20%20%3Chead%3E%0A%7C%20%20%20%3Cbody%3E%0A%7C%20%20%20%20%20%3Cmath%20math%3E%0A%7C%20%20%20%20%20%20%20definitionURL%3D%22%22"], } init_tests(get_type()); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=uri-expected.txt b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=uri-expected.txt index 90886a9..210903a6 100644 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=uri-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=uri-expected.txt
@@ -16,5 +16,8 @@ PASS html5lib_webkit02.html b6d2377b0dd710ca812c97b2b65cb5d2e93b0e5b PASS html5lib_webkit02.html 21a5b2b413c4db8ed588334b9a50dea9872bbcfa PASS html5lib_webkit02.html 90d3f6f2dff994f63293ca46f7cd50a75cde96a6 +PASS html5lib_webkit02.html 3e6b37a5fd0b16769f71f8e6a022ef6a972769d0 +PASS html5lib_webkit02.html 66c5e72324003827309d3590a9ba56412ba68f79 +PASS html5lib_webkit02.html 329d2522353afa12afea478bbfafdb0ff0656572 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=write-expected.txt b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=write-expected.txt index 90886a9..210903a6 100644 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=write-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=write-expected.txt
@@ -16,5 +16,8 @@ PASS html5lib_webkit02.html b6d2377b0dd710ca812c97b2b65cb5d2e93b0e5b PASS html5lib_webkit02.html 21a5b2b413c4db8ed588334b9a50dea9872bbcfa PASS html5lib_webkit02.html 90d3f6f2dff994f63293ca46f7cd50a75cde96a6 +PASS html5lib_webkit02.html 3e6b37a5fd0b16769f71f8e6a022ef6a972769d0 +PASS html5lib_webkit02.html 66c5e72324003827309d3590a9ba56412ba68f79 +PASS html5lib_webkit02.html 329d2522353afa12afea478bbfafdb0ff0656572 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=write_single-expected.txt b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=write_single-expected.txt index 90886a9..210903a6 100644 --- a/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=write_single-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/syntax/parsing/html5lib_webkit02_run_type=write_single-expected.txt
@@ -16,5 +16,8 @@ PASS html5lib_webkit02.html b6d2377b0dd710ca812c97b2b65cb5d2e93b0e5b PASS html5lib_webkit02.html 21a5b2b413c4db8ed588334b9a50dea9872bbcfa PASS html5lib_webkit02.html 90d3f6f2dff994f63293ca46f7cd50a75cde96a6 +PASS html5lib_webkit02.html 3e6b37a5fd0b16769f71f8e6a022ef6a972769d0 +PASS html5lib_webkit02.html 66c5e72324003827309d3590a9ba56412ba68f79 +PASS html5lib_webkit02.html 329d2522353afa12afea478bbfafdb0ff0656572 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/tools/html5lib_tests_revision b/third_party/blink/web_tests/external/wpt/html/tools/html5lib_tests_revision index 4535af2..dae44a0 100644 --- a/third_party/blink/web_tests/external/wpt/html/tools/html5lib_tests_revision +++ b/third_party/blink/web_tests/external/wpt/html/tools/html5lib_tests_revision
@@ -1 +1 @@ -95417e63a22e6624013558fd5a7d44d0265491b9 +251b2efff71c914dd184c868fdd70b9d9e54aed4
diff --git a/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-blocking-duration.html.ini b/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-blocking-duration.html.ini new file mode 100644 index 0000000..5d138694 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-blocking-duration.html.ini
@@ -0,0 +1,4 @@ +[loaf-blocking-duration.html] + [LoAF blockingDuration should be equivalent to long tasks: Non-rendering] + expected: + if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html index 5bb168e..f920ecc 100644 --- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html +++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html
@@ -70,6 +70,56 @@ assert_equals(vid.videoWidth, cv.width); assert_equals(vid.videoHeight, cv.height); }, "Test that a video element rendering a disabled video track reports correct intrinsic dimensions"); + +promise_test(async t => { + const originalWidth = cv.width; + const originalHeight = cv.height; + + const vid2 = document.createElement("video"); + const ctx = cv.getContext("2d"); + ctx.fillStyle = "red"; + ctx.fillRect(0, 0, cv.width, cv.height); + const stream = cv.captureStream(); + const stream2 = stream.clone(); + t.add_cleanup(() => { + for (let track of [...stream.getTracks(), ...stream2.getTracks()]) { + track.stop(); + } + vid.srcObject = null; + vid2.srcObject = null; + cv.width = originalWidth; + cv.height = originalHeight; + }); + + stream.getTracks()[0].enabled = false; + + vid.srcObject = stream; + vid2.srcObject = stream2; + vid.play(); + vid2.play(); + await Promise.all([ + new Promise(r => vid.onresize = r), + new Promise(r => vid2.onresize = r), + ]); + + // Test "flow" of the disabled track by checking for "resize" events on a + // video element rendering that track. They should not fire. As a reference, + // we look for two "resize" events on a different video element rendering an + // enabled clone of the disabled track. We look for two and not one event + // because then we don't rely on any ordering of events coming from the two + // video elements. + let resized = 0; + vid.addEventListener("resize", () => ++resized); + + for (let i = 0; i < 2; ++i) { + cv.width = cv.width / 2; + cv.height = cv.height / 2; + ctx.fillRect(0, 0, cv.width, cv.height); + await new Promise(r => vid2.onresize = r); + } + + assert_equals(resized, 0); +}, "Test that frames don't flow for a disabled video track"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/resize-observer/devicepixel2.html.ini b/third_party/blink/web_tests/external/wpt/resize-observer/devicepixel2.html.ini new file mode 100644 index 0000000..3f8d6d0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/resize-observer/devicepixel2.html.ini
@@ -0,0 +1,3 @@ +[devicepixel2.html] + expected: + if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js b/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js index 91efe529..e41464e 100644 --- a/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js +++ b/third_party/blink/web_tests/external/wpt/resources/chromium/mock-pressure-service.js
@@ -1,5 +1,5 @@ import {PressureManager, PressureManagerReceiver, PressureStatus} from '/gen/services/device/public/mojom/pressure_manager.mojom.m.js' -import {PressureFactor, PressureState} from '/gen/services/device/public/mojom/pressure_update.mojom.m.js' +import {PressureFactor, PressureSource, PressureState} from '/gen/services/device/public/mojom/pressure_update.mojom.m.js' class MockPressureService { constructor() { @@ -14,6 +14,7 @@ this.observer_ = null; }); this.reset(); + this.mojomSourceType_ = new Map([['cpu', PressureSource.kCpu]]); this.mojomStateType_ = new Map([ ['nominal', PressureState.kNominal], ['fair', PressureState.kFair], ['serious', PressureState.kSerious], ['critical', PressureState.kCritical] @@ -47,9 +48,14 @@ this.updatesDelivered_ = 0; } - async addClient(observer) { + async addClient(observer, source) { if (this.observer_ !== null) - throw new Error('BindObserver() has already been called'); + throw new Error('addClient() has already been called'); + + // TODO(crbug.com/1342184): Consider other sources. + // For now, "cpu" is the only source. + if (source !== PressureSource.kCpu) + throw new Error('Call addClient() with a wrong PressureSource'); this.observer_ = observer; this.observer_.onConnectionError.addListener(() => { @@ -106,7 +112,10 @@ return this.updatesDelivered_; } - setPressureUpdate(state, factors) { + setPressureUpdate(source, state, factors) { + if (!this.mojomSourceType_.has(source)) + throw new Error(`PressureSource '${source}' is invalid`); + if (!this.mojomStateType_.has(state)) throw new Error(`PressureState '${state}' is invalid`); @@ -120,6 +129,7 @@ } this.pressureUpdate_ = { + source: this.mojomSourceType_.get(source), state: this.mojomStateType_.get(state), factors: pressureFactors, };
diff --git a/third_party/blink/web_tests/external/wpt/svg/embedded/image-crossorigin.sub-expected.txt b/third_party/blink/web_tests/external/wpt/svg/embedded/image-crossorigin.sub-expected.txt new file mode 100644 index 0000000..daad420 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/embedded/image-crossorigin.sub-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +PASS Can get pixels of canvas with same origin image drawn +FAIL Can get pixels of canvas with CORS enabled cross origin image drawn Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. +PASS Can't get pixels of canvas with CORS enabled cross origin image drawn from non-CORS element +PASS Can't get pixels of canvas with non-CORS enabled cross origin image drawn +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/svg/embedded/image-crossorigin.sub.html b/third_party/blink/web_tests/external/wpt/svg/embedded/image-crossorigin.sub.html new file mode 100644 index 0000000..531512e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/embedded/image-crossorigin.sub.html
@@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<title>Test Crossorigin</title> +<link rel="help" href="https://www.w3.org/TR/SVG/embedded.html#ImageElementCrossoriginAttribute"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script class="testbody" type="text/javascript"> + + function draw_and_read_image(image, should_throw) { + let c = document.createElement('canvas'); + document.body.appendChild(c); + let ctx = c.getContext('2d'); + ctx.drawImage(image, 0, 0); + + function get_image_data() { + ctx.getImageData(0, 0, 4, 4); + } + + if (should_throw) { + assert_throws_dom('SecurityError', get_image_data); + } else { + get_image_data(); + } + + document.body.removeChild(c); + } + + async_test(t => { + let image = document.createElementNS("http://www.w3.org/2000/svg", "image"); + image.setAttribute("href", "/images/green.png"); + image.crossOrigin = "anonymous"; + image.onload = t.step_func_done(() => { + draw_and_read_image(image, false); + }); + image.onerror = t.unreached_func(); + }, "Can get pixels of canvas with same origin image drawn"); + + async_test(t => { + let image = document.createElementNS("http://www.w3.org/2000/svg", "image"); + image.setAttribute("href", "http://{{hosts[][www]}}:{{ports[http][0]}}/images/green.png?pipe=header(Access-Control-Allow-Origin,*)"); + image.crossOrigin = "anonymous"; + image.onload = t.step_func_done(() => { + draw_and_read_image(image, false); + }); + image.onerror = t.unreached_func(); + }, "Can get pixels of canvas with CORS enabled cross origin image drawn"); + + async_test(t => { + let image = document.createElementNS("http://www.w3.org/2000/svg", "image"); + image.setAttribute("href", "http://{{hosts[][www]}}:{{ports[http][0]}}/images/green.png?pipe=header(Access-Control-Allow-Origin,*)"); + image.onload = t.step_func_done(() => { + draw_and_read_image(image, true); + }); + image.onerror = t.unreached_func(); + }, "Can't get pixels of canvas with CORS enabled cross origin image drawn from non-CORS element"); + + async_test(t => { + let image = document.createElementNS("http://www.w3.org/2000/svg", "image"); + image.setAttribute("href", "http://{{hosts[][www]}}:{{ports[http][0]}}/images/green.png"); + + image.onload = t.step_func_done(() => { + draw_and_read_image(image, true); + }); + image.onerror = t.unreached_func(); + }, "Can't get pixels of canvas with non-CORS enabled cross origin image drawn"); + +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/svg/embedded/image-crossorigin.sub.html.ini b/third_party/blink/web_tests/external/wpt/svg/embedded/image-crossorigin.sub.html.ini new file mode 100644 index 0000000..b6fb429 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/embedded/image-crossorigin.sub.html.ini
@@ -0,0 +1,3 @@ +[image-crossorigin.sub.html] + [Can get pixels of canvas with CORS enabled cross origin image drawn] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/opacity-ref.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/opacity-ref.svg new file mode 100644 index 0000000..18c00ab --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/opacity-ref.svg
@@ -0,0 +1,26 @@ +<svg xmlns="http://www.w3.org/2000/svg"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + text { + font-size: 50px; + } + </style> + <defs> + <path id="path" d="M100, 120 300, 120"/> + </defs> + <text x="100" y="60" opacity="0.5"> + <tspan>tspan</tspan> + </text> + <text opacity="0.5"> + <textPath href="#path">textPath</textPath> + </text> + <text x="100" y="180" opacity="0.5"> + <a href="https://www.w3.org"><tspan>link</tspan></a> + </text> + <text x="100" y="240" opacity="0.5"> + <a href="https://www.w3.org"><tspan>another link</tspan></a> + </text> + <text x="100" y="300" opacity="0.25" font-family="Ahem"> + <tspan>XXXX</tspan> + </text> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/opacity.svg b/third_party/blink/web_tests/external/wpt/svg/text/reftests/opacity.svg new file mode 100644 index 0000000..949de0c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/opacity.svg
@@ -0,0 +1,31 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml"> + <metadata> + <h:title>Opacity on tspan, textPath, and a elements</h:title> + <h:link rel="help" href="https://svgwg.org/svg2-draft/text.html"/> + <h:link rel="match" href="opacity-ref.svg"/> + <h:link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + </metadata> + <style> + text { + font-size: 50px; + } + </style> + <defs> + <path id="path" d="M100, 120 300, 120"/> + </defs> + <text x="100" y="60"> + <tspan style="opacity: 0.5">tspan</tspan> + </text> + <text> + <textPath href="#path" style="opacity: 0.5">textPath</textPath> + </text> + <text x="100" y="180"> + <a href="https://www.w3.org" style="opacity: 0.5"><tspan>link</tspan></a> + </text> + <text x="100" y="240"> + <a href="https://www.w3.org"><tspan style="opacity: 0.5">another link</tspan></a> + </text> + <text x="100" y="300" opacity="0.5" font-family="Ahem"> + <tspan style="opacity: 0.5">XXXX</tspan> + </text> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/opacity.svg.ini b/third_party/blink/web_tests/external/wpt/svg/text/reftests/opacity.svg.ini new file mode 100644 index 0000000..51c0b47 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/opacity.svg.ini
@@ -0,0 +1,2 @@ +[opacity.svg] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/public-key-credential-to-json.https.window.js.ini b/third_party/blink/web_tests/external/wpt/webauthn/public-key-credential-to-json.https.window.js.ini new file mode 100644 index 0000000..0919b04 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webauthn/public-key-credential-to-json.https.window.js.ini
@@ -0,0 +1,3 @@ +[public-key-credential-to-json.https.window.html] + expected: + if product == "chrome": ERROR
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/conftest.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/conftest.py index f28fb06..30069a0 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/conftest.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/perform_actions/conftest.py
@@ -69,7 +69,7 @@ @pytest.fixture def key_reporter(session, test_actions_page, request): - """Represents focused input element from `test_keys_page` fixture.""" + """Represents focused input element from `test_actions_page` fixture.""" input_el = session.find.css("#keys", all=False) input_el.click() session.execute_script("resetEvents();")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/conftest.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/conftest.py index 34c8e5d..8275efc2 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/conftest.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/conftest.py
@@ -28,7 +28,7 @@ @pytest.fixture def key_reporter(session, test_actions_page, request): - """Represents focused input element from `test_keys_page` fixture.""" + """Represents focused input element from `test_actions_page` fixture.""" input_el = session.find.css("#keys", all=False) input_el.click() session.execute_script("resetEvents();")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/refine.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/refine.py index 90f7225..d405209 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/refine.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/refine.py
@@ -1,5 +1,5 @@ def get_events(session): - """Return list of key events recorded in the test_keys_page fixture.""" + """Return list of key events recorded in the test_actions_page fixture.""" events = session.execute_script("return allEvents.events;") or [] # `key` values in `allEvents` may be escaped (see `escapeSurrogateHalf` in # test_keys_wdspec.html), so this converts them back into unicode literals.
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/test_actions_wdspec.html b/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/test_actions_wdspec.html deleted file mode 100644 index 6f844cd..0000000 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/release_actions/support/test_actions_wdspec.html +++ /dev/null
@@ -1,197 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<html> -<head> - <title>Test Actions</title> - <style> - div { padding:0px; margin: 0px; } - #trackPointer { position: fixed; } - #resultContainer { width: 600px; height: 60px; } - .area { width: 100px; height: 50px; background-color: #ccc; } - .block { width: 5px; height: 5px; border: solid 1px red; } - #dragArea { position: relative; } - #dragTarget { position: absolute; top:22px; left:47px;} - </style> - <script> - "use strict"; - var els = {}; - var allEvents = { events: [] }; - function displayMessage(message) { - document.getElementById("events").innerHTML = "<p>" + message + "</p>"; - } - - function appendMessage(message) { - document.getElementById("events").innerHTML += "<p>" + message + "</p>"; - } - - /** - * Escape |key| if it's in a surrogate-half character range. - * - * Example: given "\ud83d" return "U+d83d". - * - * Otherwise JSON.stringify will convert it to U+FFFD (REPLACEMENT CHARACTER) - * when returning a value from executeScript, for example. - */ - function escapeSurrogateHalf(key) { - if (typeof key !== "undefined" && key.length === 1) { - var charCode = key.charCodeAt(0); - var highSurrogate = charCode >= 0xD800 && charCode <= 0xDBFF; - var surrogate = highSurrogate || (charCode >= 0xDC00 && charCode <= 0xDFFF); - if (surrogate) { - key = "U+" + charCode.toString(16); - } - } - return key; - } - - function recordKeyboardEvent(event) { - var key = escapeSurrogateHalf(event.key); - allEvents.events.push({ - "code": event.code, - "key": key, - "which": event.which, - "location": event.location, - "ctrl": event.ctrlKey, - "meta": event.metaKey, - "shift": event.shiftKey, - "repeat": event.repeat, - "type": event.type - }); - appendMessage(event.type + " " + - "code: " + event.code + ", " + - "key: " + key + ", " + - "which: " + event.which + ", " + - "keyCode: " + event.keyCode); - } - - function recordPointerEvent(event) { - if (event.type === "contextmenu") { - event.preventDefault(); - } - allEvents.events.push({ - "type": event.type, - "button": event.button, - "buttons": event.buttons, - "pageX": event.pageX, - "pageY": event.pageY, - "ctrlKey": event.ctrlKey, - "metaKey": event.metaKey, - "altKey": event.altKey, - "shiftKey": event.shiftKey, - "target": event.target.id - }); - appendMessage(event.type + " " + - "button: " + event.button + ", " + - "pageX: " + event.pageX + ", " + - "pageY: " + event.pageY + ", " + - "button: " + event.button + ", " + - "buttons: " + event.buttons + ", " + - "ctrlKey: " + event.ctrlKey + ", " + - "altKey: " + event.altKey + ", " + - "metaKey: " + event.metaKey + ", " + - "shiftKey: " + event.shiftKey + ", " + - "target id: " + event.target.id); - } - - function recordFirstPointerMove(event) { - recordPointerEvent(event); - window.removeEventListener("mousemove", recordFirstPointerMove); - } - - function grabOnce(event) { - grab(event); - els.dragTarget.removeEventListener("mousedown", grabOnce); - } - - function dropOnce(moveHandler) { - return function (event) { - moveHandler(event); - els.dragArea.removeEventListener("mouseup", dropOnce); - } - } - - function resetEvents() { - allEvents.events.length = 0; - displayMessage(""); - } - - function drop(moveHandler) { - return function (event) { - els.dragArea.removeEventListener("mousemove", moveHandler); - els.dragTarget.style.backgroundColor = "yellow"; - els.dragTarget.addEventListener("mousedown", grab); - recordPointerEvent(event); - }; - } - - function move(el, offsetX, offsetY, timeout) { - return function(event) { - setTimeout(function() { - el.style.top = event.clientY + offsetY + "px"; - el.style.left = event.clientX + offsetX + "px"; - }, timeout); - }; - } - - function grab(event) { - event.target.style.backgroundColor = "red"; - let boxRect = event.target.getBoundingClientRect(); - let areaRect = event.target.parentElement.getBoundingClientRect(); - let moveHandler = move( - event.target, - // coordinates of dragTarget must be relative to dragArea such that - // dragTarget remains under the pointer - -(areaRect.left + (event.clientX - boxRect.left)), - -(areaRect.top + (event.clientY - boxRect.top)), - 20); - els.dragArea.addEventListener("mousemove", moveHandler); - els.dragArea.addEventListener("mouseup", dropOnce(drop(moveHandler))); - } - - document.addEventListener("DOMContentLoaded", function() { - var keyReporter = document.getElementById("keys"); - keyReporter.addEventListener("keyup", recordKeyboardEvent); - keyReporter.addEventListener("keypress", recordKeyboardEvent); - keyReporter.addEventListener("keydown", recordKeyboardEvent); - - var outer = document.getElementById("outer"); - outer.addEventListener("click", recordPointerEvent); - outer.addEventListener("dblclick", recordPointerEvent); - outer.addEventListener("mousedown", recordPointerEvent); - outer.addEventListener("mouseup", recordPointerEvent); - outer.addEventListener("contextmenu", recordPointerEvent); - - window.addEventListener("mousemove", recordFirstPointerMove); - //visual cue for mousemove - var pointer = document.getElementById("trackPointer"); - window.addEventListener("mousemove", move(pointer, 15, 15, 30)); - // drag and drop - els.dragArea = document.getElementById("dragArea"); - els.dragTarget = document.getElementById("dragTarget"); - els.dragTarget.addEventListener("mousedown", grabOnce); - }); - </script> -</head> -<body> - <div id="trackPointer" class="block"></div> - <div> - <h2>KeyReporter</h2> - <input type="text" id="keys" size="80"> - </div> - <div> - <h2>ClickReporter</h2> - <div id="outer" class="area"> - </div> - </div> - <div> - <h2>DragReporter</h2> - <div id="dragArea" class="area"> - <div id="dragTarget" class="block"></div> - </div> - </div> - <div id="resultContainer"> - <h2>Events</h2> - <div id="events"></div> - </div> -</body> -</html>
diff --git a/third_party/blink/web_tests/http/tests/devtools/layers/layer-compositing-reasons-expected.txt b/third_party/blink/web_tests/http/tests/devtools/layers/layer-compositing-reasons-expected.txt index ef5b4345..37c8137 100644 --- a/third_party/blink/web_tests/http/tests/devtools/layers/layer-compositing-reasons-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/layers/layer-compositing-reasons-expected.txt
@@ -1,17 +1,19 @@ Tests layer compositing reasons in Layers Panel -Compositing reason ids for div#transform3d: transform3D -Compositing reason ids for div#scale3d: scale3D -Compositing reason ids for div#rotate3d: rotate3D -Compositing reason ids for div#translate3d: translate3D -Compositing reason ids for div#backface-visibility: backfaceVisibilityHidden -Compositing reason ids for div#animation: activeTransformAnimation -Compositing reason ids for div#animation-scale: activeScaleAnimation -Compositing reason ids for div#animation-rotate: activeRotateAnimation -Compositing reason ids for div#animation-translate: activeTranslateAnimation -Compositing reason ids for div#transformWithCompositedDescendants: overlap -Compositing reason ids for div#transformWithCompositedDescendants-individual: overlap -Compositing reason ids for div#opacityWithCompositedDescendants: overflowScrolling,rootScroller -Compositing reason ids for div#reflectionWithCompositedDescendants: filterWithCompositedDescendants -Compositing reason ids for div#perspective: perspectiveWith3DDescendants -Compositing reason ids for div#preserve3d: preserve3DWith3DDescendants +Compositing reason ids for div#transform3d: 3DTransform +Compositing reason ids for div#scale3d: 3DScale +Compositing reason ids for div#rotate3d: 3DRotate +Compositing reason ids for div#translate3d: 3DTranslate +Compositing reason ids for div#backface-visibility: BackfaceVisibilityHidden +Compositing reason ids for div#animation: ActiveTransformAnimation +Compositing reason ids for div#animation-scale: ActiveScaleAnimation +Compositing reason ids for div#animation-rotate: ActiveRotateAnimation +Compositing reason ids for div#animation-translate: ActiveTranslateAnimation +Compositing reason ids for div#transformWithCompositedDescendants: Overlap +Compositing reason ids for div#transformWithCompositedDescendants-individual: Overlap +Compositing reason ids for div#opacityWithCompositedDescendants: OverflowScrolling,RootScroller +Compositing reason ids for div#reflectionWithCompositedDescendants: OverflowScrolling,RootScroller +Compositing reason ids for div#perspective: PerspectiveWith3DDescendants +Compositing reason ids for div#preserve3d: Preserve3DWith3DDescendants +Compositing reason ids for div#scrollOpaque: OverflowScrolling +Compositing reason ids for div#scrollForced: OverflowScrolling
diff --git a/third_party/blink/web_tests/http/tests/devtools/layers/layer-compositing-reasons.js b/third_party/blink/web_tests/http/tests/devtools/layers/layer-compositing-reasons.js index 134ea0e..f6dd21f3 100644 --- a/third_party/blink/web_tests/http/tests/devtools/layers/layer-compositing-reasons.js +++ b/third_party/blink/web_tests/http/tests/devtools/layers/layer-compositing-reasons.js
@@ -20,7 +20,8 @@ 'transform3d', 'scale3d', 'rotate3d', 'translate3d', 'backface-visibility', 'animation', 'animation-scale', 'animation-rotate', 'animation-translate', 'transformWithCompositedDescendants', 'transformWithCompositedDescendants-individual', - 'opacityWithCompositedDescendants', 'reflectionWithCompositedDescendants', 'perspective', 'preserve3d' + 'opacityWithCompositedDescendants', 'reflectionWithCompositedDescendants', 'perspective', 'preserve3d', + 'scrollOpaque', 'scrollForced' ]; await LayersTestRunner.requestLayers();
diff --git a/third_party/blink/web_tests/http/tests/devtools/layers/resources/compositing-reasons.html b/third_party/blink/web_tests/http/tests/devtools/layers/resources/compositing-reasons.html index 0e2d869..bf5459c 100644 --- a/third_party/blink/web_tests/http/tests/devtools/layers/resources/compositing-reasons.html +++ b/third_party/blink/web_tests/http/tests/devtools/layers/resources/compositing-reasons.html
@@ -26,6 +26,12 @@ min-height: 20px; background: blue; } +.clip { + /* limits transform animation expansion to avoid unnecessary overlaps. */ + width: 100px; + height: 100px; + overflow: hidden; +} </style> <script type="application/x-javascript"> if (window.internals) @@ -36,10 +42,18 @@ <div id="rotate3d" style="rotate: 0 1 0 45deg;">3d rotate</div> <div id="translate3d" style="translate: 0px 0px 100px;">3d translate</div> <div id="backface-visibility" style="backface-visibility: hidden">backface hidden</div> -<div id="animation" style="width: 50px; height: 50px; -webkit-animation-name: rotate; -webkit-animation-iteration-count: infinite; -webkit-animation-duration: 5s;">animated</div> -<div id="animation-scale" style="width: 50px; height: 50px; animation-name: scale-individual; animation-iteration-count: infinite; animation-duration: 5s;">animated individual</div> -<div id="animation-rotate" style="width: 50px; height: 50px; animation-name: rotate-individual; animation-iteration-count: infinite; animation-duration: 5s;">animated individual</div> -<div id="animation-translate" style="width: 50px; height: 50px; animation-name: translate-individual; animation-iteration-count: infinite; animation-duration: 5s;">animated individual</div> +<div class="clip"> + <div id="animation" style="width: 50px; height: 50px; animation: rotate infinite 5s">animated</div> +</div> +<div class="clip"> + <div id="animation-scale" style="width: 50px; height: 50px; animation: scale-individual infinite 5s">animated individual</div> +</div> +<div class="clip"> + <div id="animation-rotate" style="width: 50px; height: 50px; animation: rotate-individual infinite 5s">animated individual</div> +</div> +<div class="clip"> + <div id="animation-translate" style="width: 50px; height: 50px; animation: translate-individual infinite 5s">animated individual</div> +</div> <div id="transformWithCompositedDescendants" style="transform: rotate(10deg)"> <div style="transform: scale3d(2, 3, 4);"> </div> @@ -63,4 +77,9 @@ <div style="transform: translateZ(100px);">preserve3d </div> </div> - +<div id="scrollOpaque" style="width: 100px; height: 100px; overflow: scroll; background: blue"> + <div style="width: 1000px; height: 1000px"></div> +</div> +<div id="scrollForced" style="width: 100px; height: 100px; overflow: scroll; will-change: scroll-position"> + <div style="width: 1000px; height: 1000px"></div> +</div>
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt rename to third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac-mac11/external/wpt/css/css-contain/container-queries/nested-query-containers-expected.txt b/third_party/blink/web_tests/platform/mac-mac11/external/wpt/css/css-contain/container-queries/nested-query-containers-expected.txt deleted file mode 100644 index b2d4d49..0000000 --- a/third_party/blink/web_tests/platform/mac-mac11/external/wpt/css/css-contain/container-queries/nested-query-containers-expected.txt +++ /dev/null
@@ -1,35 +0,0 @@ -This is a testharness.js-based test. -PASS test1 - inline - 0b000 -FAIL test2 - inline - 0b001 assert_equals: expected "block" but got "inline" -PASS test3 - inline - 0b010 -PASS test4 - inline - 0b011 -FAIL test5 - inline - 0b100 assert_equals: expected "block" but got "inline" -FAIL test6 - inline - 0b101 assert_equals: expected "block" but got "inline" -PASS test7 - inline - 0b110 -PASS test8 - inline - 0b111 -PASS test9 - contents - 0b000 -PASS test10 - contents - 0b001 -PASS test11 - contents - 0b010 -PASS test12 - contents - 0b011 -PASS test13 - contents - 0b100 -PASS test14 - contents - 0b101 -PASS test15 - contents - 0b110 -PASS test16 - contents - 0b111 -PASS test17 - table-cell - 0b000 -FAIL test18 - table-cell - 0b001 assert_equals: clientWidth expected 2 but got 10 -PASS test19 - table-cell - 0b010 -PASS test20 - table-cell - 0b011 -FAIL test21 - table-cell - 0b100 assert_equals: clientWidth expected 2 but got 4 -FAIL test22 - table-cell - 0b101 assert_equals: clientWidth expected 2 but got 10 -PASS test23 - table-cell - 0b110 -PASS test24 - table-cell - 0b111 -PASS test25 - table - 0b000 -FAIL test26 - table - 0b001 assert_equals: clientWidth expected 4 but got 12 -PASS test27 - table - 0b010 -PASS test28 - table - 0b011 -FAIL test29 - table - 0b100 assert_equals: clientWidth expected 4 but got 6 -FAIL test30 - table - 0b101 assert_equals: clientWidth expected 4 but got 12 -PASS test31 - table - 0b110 -PASS test32 - table - 0b111 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/css/css-contain/container-queries/nested-query-containers-expected.txt b/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/css/css-contain/container-queries/nested-query-containers-expected.txt deleted file mode 100644 index b2d4d49..0000000 --- a/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/css/css-contain/container-queries/nested-query-containers-expected.txt +++ /dev/null
@@ -1,35 +0,0 @@ -This is a testharness.js-based test. -PASS test1 - inline - 0b000 -FAIL test2 - inline - 0b001 assert_equals: expected "block" but got "inline" -PASS test3 - inline - 0b010 -PASS test4 - inline - 0b011 -FAIL test5 - inline - 0b100 assert_equals: expected "block" but got "inline" -FAIL test6 - inline - 0b101 assert_equals: expected "block" but got "inline" -PASS test7 - inline - 0b110 -PASS test8 - inline - 0b111 -PASS test9 - contents - 0b000 -PASS test10 - contents - 0b001 -PASS test11 - contents - 0b010 -PASS test12 - contents - 0b011 -PASS test13 - contents - 0b100 -PASS test14 - contents - 0b101 -PASS test15 - contents - 0b110 -PASS test16 - contents - 0b111 -PASS test17 - table-cell - 0b000 -FAIL test18 - table-cell - 0b001 assert_equals: clientWidth expected 2 but got 10 -PASS test19 - table-cell - 0b010 -PASS test20 - table-cell - 0b011 -FAIL test21 - table-cell - 0b100 assert_equals: clientWidth expected 2 but got 4 -FAIL test22 - table-cell - 0b101 assert_equals: clientWidth expected 2 but got 10 -PASS test23 - table-cell - 0b110 -PASS test24 - table-cell - 0b111 -PASS test25 - table - 0b000 -FAIL test26 - table - 0b001 assert_equals: clientWidth expected 4 but got 12 -PASS test27 - table - 0b010 -PASS test28 - table - 0b011 -FAIL test29 - table - 0b100 assert_equals: clientWidth expected 4 but got 6 -FAIL test30 - table - 0b101 assert_equals: clientWidth expected 4 but got 12 -PASS test31 - table - 0b110 -PASS test32 - table - 0b111 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-contain/container-queries/nested-query-containers-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-contain/container-queries/nested-query-containers-expected.txt deleted file mode 100644 index b2d4d49..0000000 --- a/third_party/blink/web_tests/platform/win/external/wpt/css/css-contain/container-queries/nested-query-containers-expected.txt +++ /dev/null
@@ -1,35 +0,0 @@ -This is a testharness.js-based test. -PASS test1 - inline - 0b000 -FAIL test2 - inline - 0b001 assert_equals: expected "block" but got "inline" -PASS test3 - inline - 0b010 -PASS test4 - inline - 0b011 -FAIL test5 - inline - 0b100 assert_equals: expected "block" but got "inline" -FAIL test6 - inline - 0b101 assert_equals: expected "block" but got "inline" -PASS test7 - inline - 0b110 -PASS test8 - inline - 0b111 -PASS test9 - contents - 0b000 -PASS test10 - contents - 0b001 -PASS test11 - contents - 0b010 -PASS test12 - contents - 0b011 -PASS test13 - contents - 0b100 -PASS test14 - contents - 0b101 -PASS test15 - contents - 0b110 -PASS test16 - contents - 0b111 -PASS test17 - table-cell - 0b000 -FAIL test18 - table-cell - 0b001 assert_equals: clientWidth expected 2 but got 10 -PASS test19 - table-cell - 0b010 -PASS test20 - table-cell - 0b011 -FAIL test21 - table-cell - 0b100 assert_equals: clientWidth expected 2 but got 4 -FAIL test22 - table-cell - 0b101 assert_equals: clientWidth expected 2 but got 10 -PASS test23 - table-cell - 0b110 -PASS test24 - table-cell - 0b111 -PASS test25 - table - 0b000 -FAIL test26 - table - 0b001 assert_equals: clientWidth expected 4 but got 12 -PASS test27 - table - 0b010 -PASS test28 - table - 0b011 -FAIL test29 - table - 0b100 assert_equals: clientWidth expected 4 but got 6 -FAIL test30 - table - 0b101 assert_equals: clientWidth expected 4 but got 12 -PASS test31 - table - 0b110 -PASS test32 - table - 0b111 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/wpt_internal/compute-pressure/losing-focus-suspends-data-delivery.https.window.js b/third_party/blink/web_tests/wpt_internal/compute-pressure/losing-focus-suspends-data-delivery.https.window.js index 552ed47..fadb38c 100644 --- a/third_party/blink/web_tests/wpt_internal/compute-pressure/losing-focus-suspends-data-delivery.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/compute-pressure/losing-focus-suspends-data-delivery.https.window.js
@@ -13,15 +13,16 @@ observer.disconnect(); }); observer.observe('cpu'); - mockPressureService.setPressureUpdate('critical'); + mockPressureService.setPressureUpdate('cpu', 'critical'); mockPressureService.startPlatformCollector(/*sampleRate*/ 5.0); await t.step_wait( () => observerChanges.length > 0, 'observer should receive data'); assert_equals(observerChanges.length, 1); + assert_equals(observerChanges[0][0].source, 'cpu'); assert_equals(observerChanges[0][0].state, 'critical'); window.internals.setFocused(false); - mockPressureService.setPressureUpdate('nominal'); + mockPressureService.setPressureUpdate('cpu', 'nominal'); await new Promise(resolve => t.step_timeout(resolve, 2000)); assert_equals(observerChanges.length, 1); @@ -29,5 +30,6 @@ await t.step_wait( () => observerChanges.length > 1, 'observer should receive data'); assert_equals(observerChanges.length, 2); + assert_equals(observerChanges[1][0].source, 'cpu'); assert_equals(observerChanges[1][0].state, 'nominal'); }, 'Observer should not receive PressureRecord if page loses focus');
diff --git a/third_party/closure_compiler/externs/accessibility_private.js b/third_party/closure_compiler/externs/accessibility_private.js index b19986d..e0631025 100644 --- a/third_party/closure_compiler/externs/accessibility_private.js +++ b/third_party/closure_compiler/externs/accessibility_private.js
@@ -265,6 +265,7 @@ GOOGLE_TTS_LANGUAGE_PACKS: 'googleTtsLanguagePacks', DICTATION_CONTEXT_CHECKING: 'dictationContextChecking', CHROMEVOX_TABS_DEPRECATION: 'chromevoxTabsDeprecation', + CHROMEVOX_SETTINGS_MIGRATION: 'chromevoxSettingsMigration', }; /**
diff --git a/third_party/puffin/README.chromium b/third_party/puffin/README.chromium index 1d18f21..055875ff 100644 --- a/third_party/puffin/README.chromium +++ b/third_party/puffin/README.chromium
@@ -50,4 +50,5 @@ have deflates, we can still generate a raw patch. - Updating puffdiff.cc, puffpatch.cc, and puffin_stream.cc to close streams properly. This is an existing bug in the AOSP implementation, will notify the owners. -- Removing unnecessary symlink at third_party/puffin/src. \ No newline at end of file +- Removing unnecessary symlink at third_party/puffin/src. +- Fixing one case where a stream is closed early. \ No newline at end of file
diff --git a/third_party/puffin/src/puffpatch.cc b/third_party/puffin/src/puffpatch.cc index 335ce87c..dddb25f 100644 --- a/third_party/puffin/src/puffpatch.cc +++ b/third_party/puffin/src/puffpatch.cc
@@ -115,11 +115,11 @@ dst_stream->Close(); return Status::P_READ_ERROR; } - src_stream->Close(); std::copy(buffer.data(), buffer.data() + write_size, puffed_src.data() + bytes_wrote); bytes_wrote += write_size; } + src_stream->Close(); // Read the patch Buffer zucchini_patch; TEST_AND_RETURN_VALUE(BrotliDecode(patch_start, patch_size, &zucchini_patch),
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 399d0ed9..8e11367 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -906,6 +906,7 @@ 'chromeos-betty-pi-arc-chrome-dchecks': 'chromeos_betty-pi-arc_dchecks_reclient', 'chromeos-betty-pi-arc-finch-smoke-chrome': 'chromeos_betty-pi-arc_dchecks_reclient', 'chromeos-brya-chrome-skylab-fyi': 'chromeos_brya_include_unwind_tables_official_dchecks_skylab_reclient', + 'chromeos-jacuzzi-chrome-skylab-fyi': 'chromeos_jacuzzi_include_unwind_tables_official_dchecks_skylab_reclient', 'chromeos-octopus-chrome-skylab-fyi': 'chromeos_octopus_include_unwind_tables_official_dchecks_skylab_reclient', 'chromeos-trogdor-chrome-skylab-fyi': 'chromeos_trogdor_include_unwind_tables_official_dchecks_skylab_reclient', 'chromeos-volteer-chrome-skylab-fyi': 'chromeos_volteer_include_unwind_tables_official_dchecks_skylab_reclient', @@ -967,6 +968,7 @@ 'chromeos-eve-chrome': 'chromeos_eve_include_unwind_tables_official_dchecks', 'chromeos-eve-compile-chrome': 'chromeos_eve_include_unwind_tables_official_dchecks', 'chromeos-jacuzzi-chrome': 'chromeos_jacuzzi_include_unwind_tables_official', + 'chromeos-jacuzzi-chrome-skylab': 'chromeos_jacuzzi_include_unwind_tables_official_dchecks_skylab_reclient', 'chromeos-jacuzzi-compile-chrome': 'chromeos_jacuzzi_include_unwind_tables_official', 'chromeos-kevin-chrome': 'chromeos_kevin_include_unwind_tables_official_dchecks', 'chromeos-kevin-compile-chrome': 'chromeos_kevin_include_unwind_tables_official_dchecks', @@ -2267,6 +2269,11 @@ # 'dcheck_always_on', 'also_build_lacros_chrome_for_architecture_arm', ], + + 'chromeos_jacuzzi_include_unwind_tables_official_dchecks_skylab_reclient': [ + 'chromeos_device_reclient', 'jacuzzi', 'include_unwind_tables', 'official', 'dcheck_always_on', 'is_skylab', + ], + 'chromeos_jacuzzi_include_unwind_tables_official_reclient': [ 'chromeos_device_reclient', 'jacuzzi', 'include_unwind_tables', 'official', # TODO(crbug.com/1275785): Enable DCHECKs on jacuzzi bots when the
diff --git a/tools/mb/mb_config_expectations/internal.chromeos.fyi.json b/tools/mb/mb_config_expectations/internal.chromeos.fyi.json index bb95ae78..302d675 100644 --- a/tools/mb/mb_config_expectations/internal.chromeos.fyi.json +++ b/tools/mb/mb_config_expectations/internal.chromeos.fyi.json
@@ -40,6 +40,18 @@ "use_remoteexec": true } }, + "chromeos-jacuzzi-chrome-skylab-fyi": { + "args_file": "//build/args/chromeos/jacuzzi.gni", + "gn_args": { + "dcheck_always_on": true, + "exclude_unwind_tables": false, + "is_chrome_branded": true, + "is_chromeos_device": true, + "is_official_build": true, + "is_skylab": true, + "use_remoteexec": true + } + }, "chromeos-octopus-chrome-skylab-fyi": { "args_file": "//build/args/chromeos/octopus.gni", "gn_args": {
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.json b/tools/mb/mb_config_expectations/tryserver.chrome.json index 7fb5129..a76c027 100644 --- a/tools/mb/mb_config_expectations/tryserver.chrome.json +++ b/tools/mb/mb_config_expectations/tryserver.chrome.json
@@ -165,6 +165,18 @@ "use_goma": true } }, + "chromeos-jacuzzi-chrome-skylab": { + "args_file": "//build/args/chromeos/jacuzzi.gni", + "gn_args": { + "dcheck_always_on": true, + "exclude_unwind_tables": false, + "is_chrome_branded": true, + "is_chromeos_device": true, + "is_official_build": true, + "is_skylab": true, + "use_remoteexec": true + } + }, "chromeos-jacuzzi-compile-chrome": { "args_file": "//build/args/chromeos/jacuzzi.gni", "gn_args": {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d9510696..c9b0cf94 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -25435,6 +25435,7 @@ <int value="41" label="ScanningApp"/> <int value="42" label="DiagnosticsApp"/> <int value="43" label="PrintManagementApp"/> + <int value="44" label="ShortcutCustomizationApp"/> <int value="45" label="ShimlessRMAApp"/> <int value="46" label="OSFeedbackApp"/> <int value="47" label="Cursive"/> @@ -58792,6 +58793,7 @@ <int value="-1710772665" label="disable-my-files-navigation"/> <int value="-1710314754" label="MessagesForAndroidStackingAnimation:disabled"/> + <int value="-1707624866" label="SmdsSupportEuiccUpload:enabled"/> <int value="-1706483123" label="VmStatusPage:enabled"/> <int value="-1704472714" label="UseMessagesGoogleComDomain:disabled"/> <int value="-1704022650" label="EnableDangerousDownloadDialog:enabled"/> @@ -59722,6 +59724,7 @@ label="UseLookalikesForNavigationSuggestions:enabled"/> <int value="-1227660915" label="WebContentsOcclusion:disabled"/> <int value="-1226536953" label="DeskTemplateSync:disabled"/> + <int value="-1226486549" label="SmdsSupportEuiccUpload:disabled"/> <int value="-1225861190" label="SupportTool:disabled"/> <int value="-1225772151" label="OfflineHome:disabled"/> <int value="-1225629234" label="SyncPseudoUSSFavicons:enabled"/> @@ -61066,6 +61069,7 @@ <int value="-503601144" label="UserDataSnapshot:disabled"/> <int value="-503457958" label="SkipServiceWorkerCheckInstallOnly:enabled"/> <int value="-503430431" label="XRSandbox:enabled"/> + <int value="-502813092" label="SmdsSupport:enabled"/> <int value="-502004335" label="OobeHidDetectionRevamp:enabled"/> <int value="-501853726" label="MultiZoneRgbKeyboard:enabled"/> <int value="-499723386" label="EnableFilesAppCopyImage:disabled"/> @@ -62109,6 +62113,7 @@ <int value="69571279" label="ExperimentalRgbKeyboardPatterns:disabled"/> <int value="69778786" label="NotificationPermissionVariant:disabled"/> <int value="71290103" label="ArcNearbySharing:enabled"/> + <int value="72097284" label="SmdsSupport:disabled"/> <int value="73008877" label="AutofillEnableSupportForPhoneNumberTrunkTypes:enabled"/> <int value="73606763" label="XsurfaceMetricsReporting:disabled"/> @@ -92718,6 +92723,16 @@ <int value="7" label="Partial Data not allowed to upload"/> <int value="8" label="Continuous collection start"/> <int value="9" label="Continuous collection success"/> + <int value="10" label="Collect and store inputs success"/> + <int value="11" label="Observation time reached"/> + <int value="12" label="Delayed task posted"/> + <int value="13" label="Immediate observation posted"/> + <int value="14" label="Waiting for non delayed trigger"/> + <int value="15" label="Histogram trigger hit"/> + <int value="16" label="No segment info found failure"/> + <int value="17" label="Disallowed for recording"/> + <int value="18" label="Observation disallowed for recording"/> + <int value="19" label="Training data missing"/> </enum> <enum name="SegmentationPlatformValidationResult">
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml index 42f1142..85357c7 100644 --- a/tools/metrics/histograms/metadata/chromeos/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -2440,6 +2440,21 @@ </histogram> <histogram + name="ChromeOS.Settings.Device.Touchpad.{TouchpadType}.Sensitivity.Changed" + enum="PointerSensitivity" expires_after="2024-03-22"> + <owner>dpad@google.com</owner> + <owner>cros-peripherals@google.com</owner> + <summary> + Records the value of the sensitivity setting when the {TouchpadType} + touchpad settings are updated. + </summary> + <token key="TouchpadType"> + <variant name="External" summary="external touchpad"/> + <variant name="Internal" summary="internal touchpad"/> + </token> +</histogram> + +<histogram name="ChromeOS.Settings.Device.Touchpad.{TouchpadType}.Sensitivity.Initial" enum="PointerSensitivity" expires_after="2024-03-22"> <owner>dpad@google.com</owner> @@ -2455,6 +2470,27 @@ </histogram> <histogram + name="ChromeOS.Settings.Device.Touchpad.{TouchpadType}.{TouchpadSetting}.Changed" + enum="Boolean" expires_after="2024-03-22"> + <owner>dpad@google.com</owner> + <owner>cros-peripherals@google.com</owner> + <summary> + Records the value of the {TouchpadSetting} settings when the {TouchpadType} + touchpad settings are updated. + </summary> + <token key="TouchpadType"> + <variant name="External" summary="external touchpad"/> + <variant name="Internal" summary="internal touchpad"/> + </token> + <token key="TouchpadSetting"> + <variant name="AccelerationEnabled"/> + <variant name="ReverseScrolling"/> + <variant name="TapDragging"/> + <variant name="TapToClick"/> + </token> +</histogram> + +<histogram name="ChromeOS.Settings.Device.Touchpad.{TouchpadType}.{TouchpadSetting}.Initial" enum="Boolean" expires_after="2024-03-22"> <owner>dpad@google.com</owner> @@ -2491,13 +2527,27 @@ </token> </histogram> +<histogram name="ChromeOS.Settings.Device.{Peripheral}.Sensitivity.Changed" + enum="PointerSensitivity" expires_after="2024-03-22"> + <owner>dpad@google.com</owner> + <owner>cros-peripherals@google.com</owner> + <summary> + Records the value of the sensitivity setting when the {Peripheral} device + settings are updated. The value ranges from 1 to 5. + </summary> + <token key="Peripheral"> + <variant name="Mouse"/> + <variant name="PointingStick"/> + </token> +</histogram> + <histogram name="ChromeOS.Settings.Device.{Peripheral}.Sensitivity.Initial" enum="PointerSensitivity" expires_after="2024-03-22"> <owner>dpad@google.com</owner> <owner>cros-peripherals@google.com</owner> <summary> Records the value of the sensitivity setting when the {Peripheral} device is - first initialized. The value ranges from 1 to 5. + is first initialized. The value ranges from 1 to 5. </summary> <token key="Peripheral"> <variant name="Mouse"/> @@ -2506,6 +2556,26 @@ </histogram> <histogram + name="ChromeOS.Settings.Device.{Peripheral}.{PeripheralSetting}.Changed" + enum="Boolean" expires_after="2024-03-22"> + <owner>dpad@google.com</owner> + <owner>cros-peripherals@google.com</owner> + <summary> + Records the value of the {PeripheralSetting} settings when the {Peripheral} + device settings are updated. + </summary> + <token key="Peripheral"> + <variant name="Mouse"/> + <variant name="PointingStick"/> + </token> + <token key="PeripheralSetting"> + <variant name="AccelerationEnabled"/> + <variant name="ReverseScrolling"/> + <variant name="SwapPrimaryButtons"/> + </token> +</histogram> + +<histogram name="ChromeOS.Settings.Device.{Peripheral}.{PeripheralSetting}.Initial" enum="Boolean" expires_after="2024-03-22"> <owner>dpad@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml index 0032899..c997edf 100644 --- a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
@@ -56,7 +56,8 @@ </histogram> <histogram name="ChromeOS.Settings.Bluetooth.BluetoothOnOff" - enum="BooleanToggled" expires_after="2023-04-17"> + enum="BooleanToggled" expires_after="2024-04-17"> + <owner>wesokuhara@google.com</owner> <owner>xiaohuic@chromium.org</owner> <owner>cros-settings@google.com</owner> <summary> @@ -341,7 +342,8 @@ </histogram> <histogram name="ChromeOS.Settings.People.AddAccountCount" units="accounts" - expires_after="2023-04-17"> + expires_after="2024-04-17"> + <owner>wesokuhara@google.com</owner> <owner>xiaohuic@chromium.org</owner> <owner>cros-settings@google.com</owner> <summary> @@ -388,7 +390,8 @@ </histogram> <histogram name="ChromeOS.Settings.SearchRequestsPerSession" - units="mojo search requests" expires_after="2023-04-17"> + units="mojo search requests" expires_after="2024-04-17"> + <owner>wesokuhara@google.com</owner> <owner>xiaohuic@chromium.org</owner> <owner>cros-settings@google.com</owner> <summary> @@ -418,7 +421,7 @@ </histogram> <histogram name="ChromeOS.Settings.SearchResultSettingSelected" - enum="OsSetting" expires_after="2023-04-17"> + enum="OsSetting" expires_after="2024-04-17"> <owner>wesokuhara@google.com</owner> <owner>xiaohuic@chromium.org</owner> <owner>cros-settings@google.com</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index fa3bf73d..c089caf0 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@ }, "win": { "hash": "82a32facded20e5c34bf09833eed3c66fc0bcbbc", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/9aa87085b27f3c7ac30d803071baa96655bc957e/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/75c6500b8dabe5344ac0255cb3d33182b4fd161f/trace_processor_shell.exe" }, "linux_arm": { "hash": "1d229abc94dea54ab4bb4327e78e18f942d08bf9",
diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn index 94bfa46..18fa280 100644 --- a/ui/accessibility/BUILD.gn +++ b/ui/accessibility/BUILD.gn
@@ -210,7 +210,7 @@ } if (is_fuchsia) { - public_deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_cpp" ] + public_deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_hlcpp" ] } if (use_aura) { @@ -345,9 +345,8 @@ ] deps += [ - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_cpp", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.math:fuchsia.math_hlcpp", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.views:fuchsia.ui.views_cpp_hlcpp_conversion", "//third_party/fuchsia-sdk/sdk/pkg/inspect", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
diff --git a/ui/accessibility/platform/BUILD.gn b/ui/accessibility/platform/BUILD.gn index c9777e07..ebc2470 100644 --- a/ui/accessibility/platform/BUILD.gn +++ b/ui/accessibility/platform/BUILD.gn
@@ -145,10 +145,9 @@ public_deps += [ "//base", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_cpp", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_hlcpp", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.math:fuchsia.math_hlcpp", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.gfx:fuchsia.ui.gfx_cpp_hlcpp_conversion", - "//third_party/fuchsia-sdk/sdk/pkg/component_incoming_cpp", "//third_party/fuchsia-sdk/sdk/pkg/inspect", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index 548efed..4584db34 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -250,7 +250,7 @@ if (parent->delegate_ && parent->delegate_->HasModalDialog()) return absl::nullopt; - NOTREACHED() + DCHECK(false) << "Unable to find the child in the list of its parent's children."; return absl::nullopt; }
diff --git a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h index c3b9ea46..14cd1e5 100644 --- a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h +++ b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h
@@ -5,7 +5,7 @@ #ifndef UI_ACCESSIBILITY_PLATFORM_FUCHSIA_ACCESSIBILITY_BRIDGE_FUCHSIA_H_ #define UI_ACCESSIBILITY_PLATFORM_FUCHSIA_ACCESSIBILITY_BRIDGE_FUCHSIA_H_ -#include <fidl/fuchsia.accessibility.semantics/cpp/fidl.h> +#include <fuchsia/accessibility/semantics/cpp/fidl.h> #include <lib/inspect/cpp/vmo/types.h> #include "base/component_export.h" @@ -25,7 +25,7 @@ // // Note that |node_update.node_data| should not have any node ID fields // (node_id, child_ids, offset_container_id, etc.) filled initially. - virtual void UpdateNode(fuchsia_accessibility_semantics::Node node) = 0; + virtual void UpdateNode(fuchsia::accessibility::semantics::Node node) = 0; // Translates |node_id| to a fuchsia node ID, and sends the deletion to // fuchsia.
diff --git a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.cc b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.cc index 6ec63b6..dd5c705 100644 --- a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.cc +++ b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.cc
@@ -14,30 +14,33 @@ namespace ui { namespace { +using HitTestCallback = + fuchsia::accessibility::semantics::SemanticListener::HitTestCallback; + // Error allowed for each edge when converting from gfx::RectF to gfx::Rect. constexpr float kRectConversionError = 0.5; absl::optional<ax::mojom::Action> ConvertAction( - fuchsia_accessibility_semantics::Action fuchsia_action) { + fuchsia::accessibility::semantics::Action fuchsia_action) { switch (fuchsia_action) { - case fuchsia_accessibility_semantics::Action::kDefault: + case fuchsia::accessibility::semantics::Action::DEFAULT: return ax::mojom::Action::kDoDefault; - case fuchsia_accessibility_semantics::Action::kDecrement: + case fuchsia::accessibility::semantics::Action::DECREMENT: return ax::mojom::Action::kDecrement; - case fuchsia_accessibility_semantics::Action::kIncrement: + case fuchsia::accessibility::semantics::Action::INCREMENT: return ax::mojom::Action::kIncrement; - case fuchsia_accessibility_semantics::Action::kShowOnScreen: + case fuchsia::accessibility::semantics::Action::SHOW_ON_SCREEN: return ax::mojom::Action::kScrollToMakeVisible; - case fuchsia_accessibility_semantics::Action::kSecondary: + case fuchsia::accessibility::semantics::Action::SECONDARY: LOG(WARNING) << "SECONDARY action not supported"; return {}; - case fuchsia_accessibility_semantics::Action::kSetFocus: + case fuchsia::accessibility::semantics::Action::SET_FOCUS: return ax::mojom::Action::kFocus; - case fuchsia_accessibility_semantics::Action::kSetValue: + case fuchsia::accessibility::semantics::Action::SET_VALUE: return ax::mojom::Action::kSetValue; default: LOG(WARNING) - << "Unknown fuchsia_accessibility_semantics::Action with value " + << "Unknown fuchsia::accessibility::semantics::Action with value " << static_cast<int>(fuchsia_action); return {}; } @@ -47,7 +50,7 @@ AccessibilityBridgeFuchsiaImpl::AccessibilityBridgeFuchsiaImpl( aura::Window* window, - fuchsia_ui_views::ViewRef view_ref, + fuchsia::ui::views::ViewRef view_ref, base::RepeatingCallback<void(bool)> on_semantics_enabled, OnConnectionClosedCallback on_connection_closed, inspect::Node inspect_node) @@ -84,14 +87,13 @@ } void AccessibilityBridgeFuchsiaImpl::UpdateNode( - fuchsia_accessibility_semantics::Node node) { - DCHECK(node.node_id().has_value()); + fuchsia::accessibility::semantics::Node node) { + DCHECK(node.has_node_id()); - node.node_id(MaybeToFuchsiaRootID(node.node_id().value())); + node.set_node_id(MaybeToFuchsiaRootID(node.node_id())); - if (node.container_id()) { - node.container_id(MaybeToFuchsiaRootID(node.container_id().value())); - } + if (node.has_container_id()) + node.set_container_id(MaybeToFuchsiaRootID(node.container_id())); semantic_provider_->Update(std::move(node)); } @@ -108,17 +110,16 @@ void AccessibilityBridgeFuchsiaImpl::OnAccessibilityHitTestResult( int hit_test_request_id, absl::optional<uint32_t> result) { - auto it = pending_hit_test_completers_.find(hit_test_request_id); - if (it == pending_hit_test_completers_.end()) { + auto it = pending_hit_test_callbacks_.find(hit_test_request_id); + if (it == pending_hit_test_callbacks_.end()) return; - } - fuchsia_accessibility_semantics::Hit hit; + fuchsia::accessibility::semantics::Hit hit; if (result) - hit.node_id(MaybeToFuchsiaRootID(*result)); + hit.set_node_id(MaybeToFuchsiaRootID(*result)); - std::move(it->second).Run(std::move(hit)); - pending_hit_test_completers_.erase(it); + it->second(std::move(hit)); + pending_hit_test_callbacks_.erase(it); } float AccessibilityBridgeFuchsiaImpl::GetDeviceScaleFactor() { @@ -144,7 +145,7 @@ bool AccessibilityBridgeFuchsiaImpl::OnAccessibilityAction( uint32_t node_id, - fuchsia_accessibility_semantics::Action action) { + fuchsia::accessibility::semantics::Action action) { // If the action was requested on the root, translate to the root node's // unique ID. if (node_id == AXFuchsiaSemanticProvider::kFuchsiaRootNodeId) { @@ -172,7 +173,7 @@ action_data.action = *ax_action; action_data.target_node_id = node_id; - if (action == fuchsia_accessibility_semantics::Action::kShowOnScreen) { + if (action == fuchsia::accessibility::semantics::Action::SHOW_ON_SCREEN) { // The scroll-to-make-visible action expects coordinates in the local // coordinate space of |node|. So, we need to translate node's bounds to the // origin. @@ -193,9 +194,8 @@ return true; } -void AccessibilityBridgeFuchsiaImpl::OnHitTest( - fuchsia_math::PointF point, - ui::AXFuchsiaSemanticProvider::Delegate::HitTestCallback callback) { +void AccessibilityBridgeFuchsiaImpl::OnHitTest(fuchsia::math::PointF point, + HitTestCallback callback) { ui::AXPlatformNodeFuchsia* ax_platform_node_fuchsia = nullptr; if (root_node_id_) { @@ -207,22 +207,21 @@ } if (!ax_platform_node_fuchsia) { - fuchsia_accessibility_semantics::Hit hit; - std::move(callback).Run(std::move(hit)); + fuchsia::accessibility::semantics::Hit hit; + callback(std::move(hit)); return; } ui::AXActionData action_data; action_data.action = ax::mojom::Action::kHitTest; gfx::Point target_point; - target_point.set_x(point.x()); - target_point.set_y(point.y()); + target_point.set_x(point.x); + target_point.set_y(point.y); action_data.target_point = target_point; action_data.hit_test_event_to_fire = ax::mojom::Event::kHitTestResult; action_data.request_id = next_hittest_request_id_++; - pending_hit_test_completers_.insert_or_assign(action_data.request_id, - std::move(callback)); + pending_hit_test_callbacks_[action_data.request_id] = std::move(callback); ax_platform_node_fuchsia->PerformAction(std::move(action_data)); }
diff --git a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h index 7c0af27..619d6e70 100644 --- a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h +++ b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h
@@ -5,7 +5,7 @@ #ifndef UI_ACCESSIBILITY_PLATFORM_FUCHSIA_ACCESSIBILITY_BRIDGE_FUCHSIA_IMPL_H_ #define UI_ACCESSIBILITY_PLATFORM_FUCHSIA_ACCESSIBILITY_BRIDGE_FUCHSIA_IMPL_H_ -#include <fidl/fuchsia.accessibility.semantics/cpp/fidl.h> +#include <fuchsia/accessibility/semantics/cpp/fidl.h> #include <fuchsia/ui/views/cpp/fidl.h> #include <lib/inspect/cpp/vmo/types.h> @@ -47,14 +47,14 @@ // do not reconnect). AccessibilityBridgeFuchsiaImpl( aura::Window* root_window, - fuchsia_ui_views::ViewRef view_ref, + fuchsia::ui::views::ViewRef view_ref, base::RepeatingCallback<void(bool)> on_semantics_enabled, OnConnectionClosedCallback on_connection_closed, inspect::Node inspect_node); ~AccessibilityBridgeFuchsiaImpl() override; // AccessibilityBridgeFuchsia overrides. - void UpdateNode(fuchsia_accessibility_semantics::Node node) override; + void UpdateNode(fuchsia::accessibility::semantics::Node node) override; void DeleteNode(uint32_t node_id) override; void OnAccessibilityHitTestResult(int hit_test_request_id, absl::optional<uint32_t> result) override; @@ -66,8 +66,11 @@ bool OnSemanticsManagerConnectionClosed(zx_status_t status) override; bool OnAccessibilityAction( uint32_t node_id, - fuchsia_accessibility_semantics::Action action) override; - void OnHitTest(fuchsia_math::PointF point, HitTestCallback callback) override; + fuchsia::accessibility::semantics::Action action) override; + void OnHitTest( + fuchsia::math::PointF point, + fuchsia::accessibility::semantics::SemanticListener::HitTestCallback + callback) override; void OnSemanticsEnabled(bool enabled) override; // Test-only method to set `semantic_provider_`. @@ -96,8 +99,10 @@ // Holds callbacks for hit tests that have not yet completed, keyed by a // request ID that this class generates. - base::flat_map<int /* request_id */, HitTestCallback> - pending_hit_test_completers_; + base::flat_map< + int /* request_id */, + fuchsia::accessibility::semantics::SemanticListener::HitTestCallback> + pending_hit_test_callbacks_; // Next hit test request ID to use. int next_hittest_request_id_ = 1;
diff --git a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_unittest.cc b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_unittest.cc index d5112c1..112a47f 100644 --- a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_unittest.cc +++ b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_unittest.cc
@@ -2,11 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <fidl/fuchsia.accessibility.semantics/cpp/fidl.h> -#include <fidl/fuchsia.ui.views/cpp/hlcpp_conversion.h> +#include <fuchsia/accessibility/semantics/cpp/fidl.h> #include <lib/ui/scenic/cpp/view_ref_pair.h> -#include "base/test/bind.h" #include "base/test/task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -18,10 +16,10 @@ namespace ui { namespace { -class FakeSemanticProvider : public AXFuchsiaSemanticProvider { +class MockSemanticProvider : public AXFuchsiaSemanticProvider { public: // AXFuchsiaSemanticProvider overrides. - bool Update(fuchsia_accessibility_semantics::Node node) override { + bool Update(fuchsia::accessibility::semantics::Node node) override { last_update_ = std::move(node); return true; } @@ -34,7 +32,7 @@ bool Clear() override { return true; } void SendEvent( - fuchsia_accessibility_semantics::SemanticEvent event) override { + fuchsia::accessibility::semantics::SemanticEvent event) override { last_event_ = std::move(event); } @@ -44,29 +42,29 @@ void SetPixelScale(float pixel_scale) override { pixel_scale_ = pixel_scale; } - const absl::optional<fuchsia_accessibility_semantics::Node>& last_update() + const absl::optional<fuchsia::accessibility::semantics::Node>& last_update() const { return last_update_; } const absl::optional<uint32_t>& last_deletion() const { return last_deletion_; } - const absl::optional<fuchsia_accessibility_semantics::SemanticEvent>& + const absl::optional<fuchsia::accessibility::semantics::SemanticEvent>& last_event() const { return last_event_; } private: - absl::optional<fuchsia_accessibility_semantics::Node> last_update_; + absl::optional<fuchsia::accessibility::semantics::Node> last_update_; absl::optional<uint32_t> last_deletion_; - absl::optional<fuchsia_accessibility_semantics::SemanticEvent> last_event_; + absl::optional<fuchsia::accessibility::semantics::SemanticEvent> last_event_; float pixel_scale_ = 1.f; }; -class FakeAXPlatformNodeDelegate : public AXPlatformNodeDelegate { +class MockAXPlatformNodeDelegate : public AXPlatformNodeDelegate { public: - FakeAXPlatformNodeDelegate() = default; - ~FakeAXPlatformNodeDelegate() override = default; + MockAXPlatformNodeDelegate() = default; + ~MockAXPlatformNodeDelegate() override = default; bool AccessibilityPerformAction(const AXActionData& data) override { last_action_data_.emplace(data); @@ -95,13 +93,12 @@ void SetUp() override { mock_ax_platform_node_delegate_ = - std::make_unique<FakeAXPlatformNodeDelegate>(); - auto mock_semantic_provider = std::make_unique<FakeSemanticProvider>(); + std::make_unique<MockAXPlatformNodeDelegate>(); + auto mock_semantic_provider = std::make_unique<MockSemanticProvider>(); mock_semantic_provider_ = mock_semantic_provider.get(); auto view_ref_pair = scenic::ViewRefPair::New(); accessibility_bridge_ = std::make_unique<AccessibilityBridgeFuchsiaImpl>( - /*root_window=*/nullptr, - fidl::HLCPPToNatural(std::move(view_ref_pair.view_ref)), + /*root_window=*/nullptr, std::move(view_ref_pair.view_ref), base::RepeatingCallback<void(bool)>(), base::RepeatingCallback<bool(zx_status_t)>(), inspect::Node()); accessibility_bridge_->set_semantic_provider_for_test( @@ -113,38 +110,36 @@ base::test::SingleThreadTaskEnvironment task_environment_{ base::test::SingleThreadTaskEnvironment::MainThreadType::IO}; - std::unique_ptr<FakeAXPlatformNodeDelegate> mock_ax_platform_node_delegate_; - FakeSemanticProvider* mock_semantic_provider_; + std::unique_ptr<MockAXPlatformNodeDelegate> mock_ax_platform_node_delegate_; + MockSemanticProvider* mock_semantic_provider_; std::unique_ptr<AccessibilityBridgeFuchsiaImpl> accessibility_bridge_; }; TEST_F(AccessibilityBridgeFuchsiaTest, UpdateNode) { - accessibility_bridge_->UpdateNode({{ - .node_id = 1u, - .attributes = fuchsia_accessibility_semantics::Attributes{{ - .label = "label", - }}, - }}); + fuchsia::accessibility::semantics::Node node; + node.set_node_id(1u); + node.mutable_attributes()->set_label("label"); - const absl::optional<fuchsia_accessibility_semantics::Node>& last_update = + accessibility_bridge_->UpdateNode(std::move(node)); + + const absl::optional<fuchsia::accessibility::semantics::Node>& last_update = mock_semantic_provider_->last_update(); - ASSERT_TRUE(last_update.has_value()); EXPECT_EQ(last_update->node_id(), 1u); - ASSERT_TRUE(last_update->attributes()); - ASSERT_TRUE(last_update->attributes()->label().has_value()); - EXPECT_EQ(last_update->attributes()->label().value(), "label"); + ASSERT_TRUE(last_update->has_attributes()); + ASSERT_TRUE(last_update->attributes().has_label()); + EXPECT_EQ(last_update->attributes().label(), "label"); } TEST_F(AccessibilityBridgeFuchsiaTest, UpdateNodeReplaceNodeID) { accessibility_bridge_->SetRootID(1u); - fuchsia_accessibility_semantics::Node node; - node.node_id(1u); + fuchsia::accessibility::semantics::Node node; + node.set_node_id(1u); accessibility_bridge_->UpdateNode(std::move(node)); - const absl::optional<fuchsia_accessibility_semantics::Node>& last_update = + const absl::optional<fuchsia::accessibility::semantics::Node>& last_update = mock_semantic_provider_->last_update(); ASSERT_TRUE(last_update.has_value()); EXPECT_EQ(last_update->node_id(), @@ -154,17 +149,17 @@ TEST_F(AccessibilityBridgeFuchsiaTest, UpdateNodeReplaceOffsetContainerID) { accessibility_bridge_->SetRootID(1u); - fuchsia_accessibility_semantics::Node node; - node.node_id(2u); - node.container_id(1u); + fuchsia::accessibility::semantics::Node node; + node.set_node_id(2u); + node.set_container_id(1u); accessibility_bridge_->UpdateNode(std::move(node)); - const absl::optional<fuchsia_accessibility_semantics::Node>& last_update = + const absl::optional<fuchsia::accessibility::semantics::Node>& last_update = mock_semantic_provider_->last_update(); ASSERT_TRUE(last_update.has_value()); - ASSERT_TRUE(last_update->container_id().has_value()); - EXPECT_EQ(last_update->container_id().value(), + ASSERT_TRUE(last_update->has_container_id()); + EXPECT_EQ(last_update->container_id(), AXFuchsiaSemanticProvider::kFuchsiaRootNodeId); } @@ -216,11 +211,11 @@ } TEST_F(AccessibilityBridgeFuchsiaTest, HitTest) { - auto root_delegate = std::make_unique<FakeAXPlatformNodeDelegate>(); + auto root_delegate = std::make_unique<MockAXPlatformNodeDelegate>(); AXPlatformNode* root_platform_node = AXPlatformNode::Create(root_delegate.get()); - auto child_delegate = std::make_unique<FakeAXPlatformNodeDelegate>(); + auto child_delegate = std::make_unique<MockAXPlatformNodeDelegate>(); AXPlatformNode* child_platform_node = AXPlatformNode::Create(child_delegate.get()); @@ -228,27 +223,21 @@ // dispatches the hit test request to it. accessibility_bridge_->SetRootID(root_platform_node->GetUniqueId()); - fuchsia_math::PointF target_point = {{ - .x = 1.f, - .y = 2.f, - }}; + fuchsia::math::PointF target_point; + target_point.x = 1.f; + target_point.y = 2.f; - // Set hit_test_result to a nonsense value to ensure that it's modified - // later. + // Set hit_test_result to a nonsense value to ensure that it's modified later. uint32_t hit_test_result = 100u; // Request a hit test. Note that the callback will not be invoked until // OnAccessibilityHitTestResult() is called. accessibility_bridge_->OnHitTest( target_point, - base::BindLambdaForTesting( - [&hit_test_result]( - const fidl::Response< - fuchsia_accessibility_semantics::SemanticListener::HitTest>& - response) { - ASSERT_TRUE(response.result().node_id().has_value()); - hit_test_result = response.result().node_id().value(); - })); + [&hit_test_result](fuchsia::accessibility::semantics::Hit hit) { + ASSERT_TRUE(hit.has_node_id()); + hit_test_result = hit.node_id(); + }); // Verify that the platform node's delegate received the hit test request. const absl::optional<ui::AXActionData>& action_data = @@ -258,8 +247,8 @@ // The request_id field defaults to -1, so verify that it was set to a // non-negative value. EXPECT_GE(action_data->request_id, 0); - EXPECT_EQ(action_data->target_point.x(), target_point.x()); - EXPECT_EQ(action_data->target_point.y(), target_point.y()); + EXPECT_EQ(action_data->target_point.x(), target_point.x); + EXPECT_EQ(action_data->target_point.y(), target_point.y); EXPECT_EQ(action_data->action, ax::mojom::Action::kHitTest); // Simulate a hit test result. This should invoke the callback. @@ -272,7 +261,7 @@ } TEST_F(AccessibilityBridgeFuchsiaTest, HitTestReturnsRoot) { - auto root_delegate = std::make_unique<FakeAXPlatformNodeDelegate>(); + auto root_delegate = std::make_unique<MockAXPlatformNodeDelegate>(); AXPlatformNode* root_platform_node = AXPlatformNode::Create(root_delegate.get()); @@ -280,27 +269,21 @@ // dispatches the hit test request to it. accessibility_bridge_->SetRootID(root_platform_node->GetUniqueId()); - fuchsia_math::PointF target_point = {{ - .x = 1.f, - .y = 2.f, - }}; + fuchsia::math::PointF target_point; + target_point.x = 1.f; + target_point.y = 2.f; - // Set hit_test_result to a nonsense value to ensure that it's modified - // later. + // Set hit_test_result to a nonsense value to ensure that it's modified later. uint32_t hit_test_result = 100u; // Request a hit test. Note that the callback will not be invoked until // OnAccessibilityHitTestResult() is called. accessibility_bridge_->OnHitTest( target_point, - base::BindLambdaForTesting( - [&hit_test_result]( - const fidl::Response< - fuchsia_accessibility_semantics::SemanticListener::HitTest>& - response) { - ASSERT_TRUE(response.result().node_id().has_value()); - hit_test_result = response.result().node_id().value(); - })); + [&hit_test_result](fuchsia::accessibility::semantics::Hit hit) { + ASSERT_TRUE(hit.has_node_id()); + hit_test_result = hit.node_id(); + }); const absl::optional<ui::AXActionData>& action_data = root_delegate->last_action_data(); @@ -316,7 +299,7 @@ } TEST_F(AccessibilityBridgeFuchsiaTest, HitTestReturnsEmptyResult) { - auto root_delegate = std::make_unique<FakeAXPlatformNodeDelegate>(); + auto root_delegate = std::make_unique<MockAXPlatformNodeDelegate>(); AXPlatformNode* root_platform_node = AXPlatformNode::Create(root_delegate.get()); @@ -324,24 +307,19 @@ // dispatches the hit test request to it. accessibility_bridge_->SetRootID(root_platform_node->GetUniqueId()); - fuchsia_math::PointF target_point{{ - .x = 1.f, - .y = 2.f, - }}; + fuchsia::math::PointF target_point; + target_point.x = 1.f; + target_point.y = 2.f; // Request a hit test. Note that the callback will not be invoked until // OnAccessibilityHitTestResult() is called. bool callback_ran = false; accessibility_bridge_->OnHitTest( target_point, - base::BindLambdaForTesting( - [&callback_ran]( - const fidl::Response< - fuchsia_accessibility_semantics::SemanticListener::HitTest>& - response) { - callback_ran = true; - ASSERT_FALSE(response.result().node_id().has_value()); - })); + [&callback_ran](fuchsia::accessibility::semantics::Hit hit) { + callback_ran = true; + ASSERT_FALSE(hit.has_node_id()); + }); const absl::optional<ui::AXActionData>& action_data = root_delegate->last_action_data(); @@ -357,7 +335,7 @@ } TEST_F(AccessibilityBridgeFuchsiaTest, PerformActionOnRoot) { - auto root_delegate = std::make_unique<FakeAXPlatformNodeDelegate>(); + auto root_delegate = std::make_unique<MockAXPlatformNodeDelegate>(); AXPlatformNode* root_platform_node = AXPlatformNode::Create(root_delegate.get()); @@ -368,7 +346,7 @@ // Perform DEFAULT action. accessibility_bridge_->OnAccessibilityAction( AXFuchsiaSemanticProvider::kFuchsiaRootNodeId, - fuchsia_accessibility_semantics::Action::kDefault); + fuchsia::accessibility::semantics::Action::DEFAULT); const absl::optional<ui::AXActionData>& action_data = root_delegate->last_action_data(); @@ -377,7 +355,7 @@ } TEST_F(AccessibilityBridgeFuchsiaTest, ScrollToMakeVisible) { - auto delegate = std::make_unique<FakeAXPlatformNodeDelegate>(); + auto delegate = std::make_unique<MockAXPlatformNodeDelegate>(); ui::AXNodeData data; data.relative_bounds.bounds = gfx::RectF( /*x_min=*/1.f, /*y_min=*/2.f, /*width=*/3.f, /*height=*/4.f); @@ -388,15 +366,15 @@ // Request a SHOW_ON_SCREEN action. accessibility_bridge_->OnAccessibilityAction( delegate->GetUniqueId(), - fuchsia_accessibility_semantics::Action::kShowOnScreen); + fuchsia::accessibility::semantics::Action::SHOW_ON_SCREEN); const absl::optional<ui::AXActionData>& action_data = delegate->last_action_data(); ASSERT_TRUE(action_data.has_value()); EXPECT_EQ(action_data->action, ax::mojom::Action::kScrollToMakeVisible); - // The target rect should have the same size as the node's bounds, but - // should have (x, y) == (0, 0). + // The target rect should have the same size as the node's bounds, but should + // have (x, y) == (0, 0). EXPECT_EQ(action_data->target_rect.x(), 0.f); EXPECT_EQ(action_data->target_rect.y(), 0.f); EXPECT_EQ(action_data->target_rect.width(), 3.f);
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider.h b/ui/accessibility/platform/fuchsia/semantic_provider.h index 14435065..8f48dfe4 100644 --- a/ui/accessibility/platform/fuchsia/semantic_provider.h +++ b/ui/accessibility/platform/fuchsia/semantic_provider.h
@@ -5,10 +5,9 @@ #ifndef UI_ACCESSIBILITY_PLATFORM_FUCHSIA_SEMANTIC_PROVIDER_H_ #define UI_ACCESSIBILITY_PLATFORM_FUCHSIA_SEMANTIC_PROVIDER_H_ -#include <fidl/fuchsia.accessibility.semantics/cpp/fidl.h> +#include <fuchsia/accessibility/semantics/cpp/fidl.h> #include "base/component_export.h" -#include "base/functional/callback_forward.h" namespace ui { @@ -30,9 +29,9 @@ Delegate(); virtual ~Delegate(); - using HitTestCallback = base::OnceCallback<void( - const fidl::Response< - fuchsia_accessibility_semantics::SemanticListener::HitTest>&)>; + using HitTestCallback = + fuchsia::accessibility::semantics::SemanticListener::HitTestCallback; + // Called when the FIDL channel to the Semantics Manager is closed. If this // callback returns true, an attempt to reconnect will be made. virtual bool OnSemanticsManagerConnectionClosed(zx_status_t status) = 0; @@ -42,14 +41,14 @@ // method returns true, this means that the action will be handled. virtual bool OnAccessibilityAction( uint32_t node_id, - fuchsia_accessibility_semantics::Action action) = 0; + fuchsia::accessibility::semantics::Action action) = 0; // Processes an incoming hit test request from Fuchsia. It // receives a point in Scenic View pixel coordinates and a callback to // return the result when the hit test is done. Please see // |fuchsia.accessibility.semantics.SemanticListener| for documentation on // hit tests. - virtual void OnHitTest(fuchsia_math::PointF point, + virtual void OnHitTest(fuchsia::math::PointF point, HitTestCallback callback) = 0; // Called whenever Fuchsia enables / disables semantic updates. @@ -61,7 +60,7 @@ // Adds a semantic node to be updated. It is mandatory that the node has at // least an unique ID. - virtual bool Update(fuchsia_accessibility_semantics::Node node) = 0; + virtual bool Update(fuchsia::accessibility::semantics::Node node) = 0; // Marks a semantic node to be deleted. Returns false if the node is not // present in the list of semantic nodes known by this provider. @@ -74,7 +73,7 @@ // https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.accessibility.semantics/semantics_manager.fidl // for documentation on events. virtual void SendEvent( - fuchsia_accessibility_semantics::SemanticEvent event) = 0; + fuchsia::accessibility::semantics::SemanticEvent event) = 0; // Returns true if there are pending updates or deletions to be made. virtual bool HasPendingUpdates() const = 0;
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider_impl.cc b/ui/accessibility/platform/fuchsia/semantic_provider_impl.cc index 976db4d..50bfb72 100644 --- a/ui/accessibility/platform/fuchsia/semantic_provider_impl.cc +++ b/ui/accessibility/platform/fuchsia/semantic_provider_impl.cc
@@ -4,33 +4,22 @@ #include "ui/accessibility/platform/fuchsia/semantic_provider_impl.h" -#include <fidl/fuchsia.ui.gfx/cpp/fidl.h> -#include <lib/async/default.h> #include <lib/sys/cpp/component_context.h> +#include <lib/ui/scenic/cpp/commands.h> #include "base/check.h" #include "base/check_op.h" -#include "base/fuchsia/fuchsia_component_connect.h" #include "base/fuchsia/fuchsia_logging.h" -#include "base/strings/string_piece.h" +#include "base/fuchsia/process_context.h" #include "ui/gfx/geometry/transform.h" namespace ui { namespace { -using fuchsia_accessibility_semantics::Node; +using fuchsia::accessibility::semantics::Node; constexpr size_t kMaxOperationsPerBatch = 16; -SemanticTreeEventHandler::SemanticTreeEventHandler( - base::OnceCallback<void(fidl::UnbindInfo)> on_fidl_error_callback) - : on_fidl_error_callback_(std::move(on_fidl_error_callback)) {} -SemanticTreeEventHandler::~SemanticTreeEventHandler() = default; - -void SemanticTreeEventHandler::on_fidl_error(fidl::UnbindInfo error) { - std::move(on_fidl_error_callback_).Run(error); -} - } // namespace AXFuchsiaSemanticProviderImpl::Batch::Batch(Type type) : type_(type) {} @@ -45,7 +34,7 @@ } void AXFuchsiaSemanticProviderImpl::Batch::Append( - fuchsia_accessibility_semantics::Node node) { + fuchsia::accessibility::semantics::Node node) { DCHECK_EQ(type_, Type::kUpdate); DCHECK(!IsFull()); updates_.push_back(std::move(node)); @@ -59,18 +48,11 @@ } void AXFuchsiaSemanticProviderImpl::Batch::Apply( - fidl::Client<fuchsia_accessibility_semantics::SemanticTree>* - semantic_tree) { - if (type_ == Type::kUpdate && !updates_.empty()) { - auto result = (*semantic_tree)->UpdateSemanticNodes(std::move(updates_)); - LOG_IF(ERROR, result.is_error()) - << base::FidlMethodResultErrorMessage(result, "UpdateSemanticNodes"); - } else if (type_ == Type::kDelete && !delete_node_ids_.empty()) { - auto result = - (*semantic_tree)->DeleteSemanticNodes(std::move(delete_node_ids_)); - LOG_IF(ERROR, result.is_error()) - << base::FidlMethodResultErrorMessage(result, "DeleteSemanticNodes"); - } + fuchsia::accessibility::semantics::SemanticTreePtr* semantic_tree) { + if (type_ == Type::kUpdate && !updates_.empty()) + (*semantic_tree)->UpdateSemanticNodes(std::move(updates_)); + else if (type_ == Type::kDelete && !delete_node_ids_.empty()) + (*semantic_tree)->DeleteSemanticNodes(std::move(delete_node_ids_)); } AXFuchsiaSemanticProviderImpl::NodeInfo ::NodeInfo() = default; @@ -80,68 +62,35 @@ AXFuchsiaSemanticProviderImpl::Delegate::~Delegate() = default; AXFuchsiaSemanticProviderImpl::AXFuchsiaSemanticProviderImpl( - fuchsia_ui_views::ViewRef view_ref, + fuchsia::ui::views::ViewRef view_ref, Delegate* delegate) - : delegate_(delegate) { + : view_ref_(std::move(view_ref)), + delegate_(delegate), + semantic_listener_binding_(this) { + sys::ComponentContext* component_context = base::ComponentContextForProcess(); + DCHECK(component_context); DCHECK(delegate_); - auto semantics_manager_client_end = base::fuchsia_component::Connect< - fuchsia_accessibility_semantics::SemanticsManager>(); - // TODO(crbug.com/1431519): Create a path for gracefully failing to connect to - // SemanticsManager instead of CHECKing. - CHECK(semantics_manager_client_end.is_ok()) - << base::FidlConnectionErrorMessage(semantics_manager_client_end); - fidl::Client semantics_manager( - std::move(semantics_manager_client_end.value()), - async_get_default_dispatcher()); - - auto semantic_listener_endpoints = fidl::CreateEndpoints< - fuchsia_accessibility_semantics::SemanticListener>(); - ZX_CHECK(semantic_listener_endpoints.is_ok(), - semantic_listener_endpoints.status_value()); - semantic_listener_binding_.emplace( - async_get_default_dispatcher(), - std::move(semantic_listener_endpoints->server), this, - base::FidlBindingClosureWarningLogger( - "fuchsia.accessibility.semantics.SemanticListener")); - - semantic_tree_event_handler_.emplace(base::BindOnce( - [](AXFuchsiaSemanticProviderImpl* semantic_provider, - fidl::UnbindInfo info) { - ZX_LOG(ERROR, info.status()) << "SemanticListener disconnected"; - semantic_provider->delegate_->OnSemanticsManagerConnectionClosed( - info.status()); - semantic_provider->semantic_updates_enabled_ = false; - }, - this)); - - auto semantic_tree_endpoints = - fidl::CreateEndpoints<fuchsia_accessibility_semantics::SemanticTree>(); - ZX_CHECK(semantic_tree_endpoints.is_ok(), - semantic_tree_endpoints.status_value()); - semantic_tree_.Bind(std::move(semantic_tree_endpoints->client), - async_get_default_dispatcher(), - &semantic_tree_event_handler_.value()); - - auto result = semantics_manager->RegisterViewForSemantics({{ - .view_ref = std::move(view_ref), - .listener = std::move(semantic_listener_endpoints->client), - .semantic_tree_request = std::move(semantic_tree_endpoints->server), - }}); - if (result.is_error()) { - ZX_LOG(ERROR, result.error_value().status()) - << "Error calling RegisterViewForSemantics()"; - } + component_context->svc() + ->Connect<fuchsia::accessibility::semantics::SemanticsManager>() + ->RegisterViewForSemantics(std::move(view_ref_), + semantic_listener_binding_.NewBinding(), + semantic_tree_.NewRequest()); + semantic_tree_.set_error_handler([this](zx_status_t status) { + ZX_LOG(ERROR, status) << "SemanticTree disconnected"; + delegate_->OnSemanticsManagerConnectionClosed(status); + semantic_updates_enabled_ = false; + }); } AXFuchsiaSemanticProviderImpl::~AXFuchsiaSemanticProviderImpl() = default; bool AXFuchsiaSemanticProviderImpl::Update( - fuchsia_accessibility_semantics::Node node) { + fuchsia::accessibility::semantics::Node node) { if (!semantic_updates_enabled()) return false; - DCHECK(node.node_id().has_value()); + DCHECK(node.has_node_id()); // If the updated node is the root, we need to account for the pixel scale in // its transform. @@ -154,41 +103,37 @@ // Convert to fuchsia's transform type. std::array<float, 16> mat = {}; transform.GetColMajorF(mat.data()); - fuchsia_ui_gfx::Matrix4Value fuchsia_transform{{ - .value = {{ - .matrix = std::move(mat), - }}, - .variable_id = 0, - }}; + fuchsia::ui::gfx::Matrix4Value fuchsia_transform = + scenic::NewMatrix4Value(mat); // The root node will never have an offset container, so its transform will // always be the identity matrix. Thus, we can safely overwrite it here. - node.node_to_container_transform(std::move(fuchsia_transform.value())); + node.set_node_to_container_transform(std::move(fuchsia_transform.value)); } else { - auto found_not_reachable = not_reachable_.find(node.node_id().value()); + auto found_not_reachable = not_reachable_.find(node.node_id()); const bool is_not_reachable = found_not_reachable != not_reachable_.end(); const absl::optional<uint32_t> parent_node_id = - GetParentForNode(node.node_id().value()); + GetParentForNode(node.node_id()); if (is_not_reachable && parent_node_id) { // Connection parent -> |node| exists now. not_reachable_.erase(found_not_reachable); - nodes_[node.node_id().value()].parents.insert(*parent_node_id); + nodes_[node.node_id()].parents.insert(*parent_node_id); } else if (!parent_node_id) { // No node or multiple nodes points to this one, so it is not reachable. if (!is_not_reachable) - not_reachable_[node.node_id().value()] = {}; + not_reachable_[node.node_id()] = {}; } } // If the node is not present in the map, the list of children will be empty // so this is a no-op in the call below. - std::vector<uint32_t>& children = nodes_[node.node_id().value()].children; + std::vector<uint32_t>& children = nodes_[node.node_id()].children; // Before updating the node, update the list of children to be not reachable, // in case the new list of children change. - MarkChildrenAsNotReachable(children, node.node_id().value()); - children = node.child_ids().value_or(std::vector<uint32_t>()); - MarkChildrenAsReachable(children, node.node_id().value()); + MarkChildrenAsNotReachable(children, node.node_id()); + children = node.has_child_ids() ? node.child_ids() : std::vector<uint32_t>(); + MarkChildrenAsReachable(children, node.node_id()); Batch& batch = GetCurrentUnfilledBatch(Batch::Type::kUpdate); batch.Append(std::move(node)); @@ -214,7 +159,7 @@ } batches_.clear(); - semantic_tree_->CommitUpdates().ThenExactlyOnce( + semantic_tree_->CommitUpdates( fit::bind_member(this, &AXFuchsiaSemanticProviderImpl::OnCommitComplete)); commit_inflight_ = true; } @@ -246,14 +191,8 @@ } void AXFuchsiaSemanticProviderImpl::SendEvent( - fuchsia_accessibility_semantics::SemanticEvent event) { - semantic_tree_->SendSemanticEvent({{.semantic_event = std::move(event)}}) - .ThenExactlyOnce( - [](fidl::Result< - fuchsia_accessibility_semantics::SemanticTree::SendSemanticEvent>& - result) { - ZX_LOG_IF(ERROR, result.is_error(), result.error_value().status()); - }); + fuchsia::accessibility::semantics::SemanticEvent event) { + semantic_tree_->SendSemanticEvent(std::move(event), [](auto...) {}); } bool AXFuchsiaSemanticProviderImpl::HasPendingUpdates() const { @@ -274,46 +213,37 @@ } void AXFuchsiaSemanticProviderImpl::OnAccessibilityActionRequested( - AXFuchsiaSemanticProviderImpl::OnAccessibilityActionRequestedRequest& - request, - AXFuchsiaSemanticProviderImpl::OnAccessibilityActionRequestedCompleter:: - Sync& completer) { - if (delegate_->OnAccessibilityAction(request.node_id(), request.action())) { - completer.Reply(true); + uint32_t node_id, + fuchsia::accessibility::semantics::Action action, + fuchsia::accessibility::semantics::SemanticListener:: + OnAccessibilityActionRequestedCallback callback) { + if (delegate_->OnAccessibilityAction(node_id, action)) { + callback(true); return; } // The action was not handled. - completer.Reply(false); + callback(false); } -void AXFuchsiaSemanticProviderImpl::HitTest( - AXFuchsiaSemanticProviderImpl::HitTestRequest& request, - AXFuchsiaSemanticProviderImpl::HitTestCompleter::Sync& completer) { - delegate_->OnHitTest( - {{ - .x = request.local_point().x() * pixel_scale_, - .y = request.local_point().y() * pixel_scale_, - }}, - base::BindOnce( - [](HitTestCompleter::Async async_completer, - const fidl::Response< - fuchsia_accessibility_semantics::SemanticListener::HitTest>& - result) { async_completer.Reply(result); }, - completer.ToAsync())); +void AXFuchsiaSemanticProviderImpl::HitTest(fuchsia::math::PointF local_point, + HitTestCallback callback) { + fuchsia::math::PointF point; + point.x = local_point.x * pixel_scale_; + point.y = local_point.y * pixel_scale_; + + delegate_->OnHitTest(point, std::move(callback)); return; } void AXFuchsiaSemanticProviderImpl::OnSemanticsModeChanged( - AXFuchsiaSemanticProviderImpl::OnSemanticsModeChangedRequest& request, - AXFuchsiaSemanticProviderImpl::OnSemanticsModeChangedCompleter::Sync& - completer) { - if (semantic_updates_enabled_ != request.updates_enabled()) { - delegate_->OnSemanticsEnabled(request.updates_enabled()); - } + bool update_enabled, + OnSemanticsModeChangedCallback callback) { + if (semantic_updates_enabled_ != update_enabled) + delegate_->OnSemanticsEnabled(update_enabled); - semantic_updates_enabled_ = request.updates_enabled(); - completer.Reply(); + semantic_updates_enabled_ = update_enabled; + callback(); } void AXFuchsiaSemanticProviderImpl::MarkChildrenAsNotReachable( @@ -382,15 +312,12 @@ AXFuchsiaSemanticProviderImpl::GetCurrentUnfilledBatch(Batch::Type type) { if (batches_.empty() || batches_.back().type() != type || batches_.back().IsFull()) - batches_.emplace_back(type); + batches_.push_back(Batch(type)); return batches_.back(); } -void AXFuchsiaSemanticProviderImpl::OnCommitComplete( - fidl::Result<fuchsia_accessibility_semantics::SemanticTree::CommitUpdates>& - result) { - ZX_LOG_IF(ERROR, result.is_error(), result.error_value().status()); +void AXFuchsiaSemanticProviderImpl::OnCommitComplete() { commit_inflight_ = false; TryToCommit(); } @@ -410,10 +337,10 @@ // We need to fill the `child_ids` field to prevent Update() from trampling // our connectivity bookkeeping. Update() will handle setting the // `node_to_container_transform` field. - Update({{ - .node_id = kFuchsiaRootNodeId, - .child_ids = nodes_[kFuchsiaRootNodeId].children, - }}); + fuchsia::accessibility::semantics::Node root_node_update; + root_node_update.set_node_id(kFuchsiaRootNodeId); + root_node_update.set_child_ids(nodes_[kFuchsiaRootNodeId].children); + Update(std::move(root_node_update)); } } // namespace ui
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider_impl.h b/ui/accessibility/platform/fuchsia/semantic_provider_impl.h index 879ae45..16e34af 100644 --- a/ui/accessibility/platform/fuchsia/semantic_provider_impl.h +++ b/ui/accessibility/platform/fuchsia/semantic_provider_impl.h
@@ -5,7 +5,7 @@ #ifndef UI_ACCESSIBILITY_PLATFORM_FUCHSIA_SEMANTIC_PROVIDER_IMPL_H_ #define UI_ACCESSIBILITY_PLATFORM_FUCHSIA_SEMANTIC_PROVIDER_IMPL_H_ -#include <fidl/fuchsia.accessibility.semantics/cpp/fidl.h> +#include <fuchsia/accessibility/semantics/cpp/fidl.h> #include <fuchsia/ui/views/cpp/fidl.h> #include <lib/fidl/cpp/binding.h> @@ -20,30 +20,12 @@ namespace ui { -namespace { - -class SemanticTreeEventHandler - : public fidl::AsyncEventHandler< - fuchsia_accessibility_semantics::SemanticTree> { - public: - explicit SemanticTreeEventHandler( - base::OnceCallback<void(fidl::UnbindInfo)> on_fidl_error_callback); - ~SemanticTreeEventHandler() override; - - void on_fidl_error(fidl::UnbindInfo error) override; - - private: - base::OnceCallback<void(fidl::UnbindInfo)> on_fidl_error_callback_; -}; - -} // namespace - // Clients instantiate this class, which connects to the Fuchsia semantics API. // This object must remain alive across the entire lifespan of the corresponding // fuchsia view. class COMPONENT_EXPORT(AX_PLATFORM) AXFuchsiaSemanticProviderImpl : public AXFuchsiaSemanticProvider, - public fidl::Server<fuchsia_accessibility_semantics::SemanticListener> { + public fuchsia::accessibility::semantics::SemanticListener { public: // Arguments: // |view_ref|: identifies the view providing semantics. Please consult @@ -54,7 +36,7 @@ // During construction, this class connects to // |fuchsia.accessibility.semantics.SemanticsManager| to register itself as a // semantic provider. - AXFuchsiaSemanticProviderImpl(fuchsia_ui_views::ViewRef view_ref, + AXFuchsiaSemanticProviderImpl(fuchsia::ui::views::ViewRef view_ref, Delegate* delegate); ~AXFuchsiaSemanticProviderImpl() override; @@ -62,10 +44,11 @@ bool semantic_updates_enabled() const { return semantic_updates_enabled_; } // AXFuchsiaSemanticProvider overrides. - bool Update(fuchsia_accessibility_semantics::Node node) override; + bool Update(fuchsia::accessibility::semantics::Node node) override; bool Delete(uint32_t node_id) override; bool Clear() override; - void SendEvent(fuchsia_accessibility_semantics::SemanticEvent event) override; + void SendEvent( + fuchsia::accessibility::semantics::SemanticEvent event) override; bool HasPendingUpdates() const override; float GetPixelScale() const override; void SetPixelScale(float pixel_scale) override; @@ -102,16 +85,16 @@ // Adds an update or deletion to the batch. This fails if the batch is full // or if the new item is not the same type of the batch. - void Append(fuchsia_accessibility_semantics::Node node); + void Append(fuchsia::accessibility::semantics::Node node); void AppendDeletion(uint32_t delete_node_id); // Sends enqueued operations to SemanticsManager. - void Apply(fidl::Client<fuchsia_accessibility_semantics::SemanticTree>* - semantic_tree); + void Apply( + fuchsia::accessibility::semantics::SemanticTreePtr* semantic_tree); private: Type type_; - std::vector<fuchsia_accessibility_semantics::Node> updates_; + std::vector<fuchsia::accessibility::semantics::Node> updates_; std::vector<uint32_t> delete_node_ids_; }; @@ -124,10 +107,7 @@ // Invoked whenever Fuchsia responds that a commit was received. This tries to // commit again if there are pending upedates or deletions. - void OnCommitComplete( - fidl::Result< - fuchsia_accessibility_semantics::SemanticTree::CommitUpdates>& - result); + void OnCommitComplete(); // Mark all |child_ids| not reachable from |parent_id|, meaning: // - If |parent_id| was the only parent, the children are now disconnected @@ -153,29 +133,29 @@ // have a parent or it has multiple parents, returns absl::nullopt. absl::optional<uint32_t> GetParentForNode(const uint32_t node_id); - // fuchsia_accessibility_semantics::SemanticListener: + // fuchsia::accessibility::semantics::SemanticListener: void OnAccessibilityActionRequested( - OnAccessibilityActionRequestedRequest& request, - OnAccessibilityActionRequestedCompleter::Sync& completer) override; + uint32_t node_id, + fuchsia::accessibility::semantics::Action action, + fuchsia::accessibility::semantics::SemanticListener:: + OnAccessibilityActionRequestedCallback callback) override; - // fuchsia_accessibility_semantics::SemanticListener: - void HitTest(HitTestRequest& request, - HitTestCompleter::Sync& completer) override; + // fuchsia::accessibility::semantics::SemanticListener: + void HitTest(::fuchsia::math::PointF local_point, + HitTestCallback callback) override; - // fuchsia_accessibility_semantics::SemanticListener: - void OnSemanticsModeChanged( - OnSemanticsModeChangedRequest& request, - OnSemanticsModeChangedCompleter::Sync& completer) override; + // fuchsia::accessibility::semantics::SemanticListener: + void OnSemanticsModeChanged(bool update_enabled, + OnSemanticsModeChangedCallback callback) override; + + fuchsia::ui::views::ViewRef view_ref_; Delegate* const delegate_; - absl::optional< - fidl::ServerBinding<fuchsia_accessibility_semantics::SemanticListener>> + fidl::Binding<fuchsia::accessibility::semantics::SemanticListener> semantic_listener_binding_; - fidl::Client<fuchsia_accessibility_semantics::SemanticTree> semantic_tree_; - - absl::optional<SemanticTreeEventHandler> semantic_tree_event_handler_; + fuchsia::accessibility::semantics::SemanticTreePtr semantic_tree_; bool semantic_updates_enabled_ = false;
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider_unittest.cc b/ui/accessibility/platform/fuchsia/semantic_provider_unittest.cc index ba85f51..fb675cca 100644 --- a/ui/accessibility/platform/fuchsia/semantic_provider_unittest.cc +++ b/ui/accessibility/platform/fuchsia/semantic_provider_unittest.cc
@@ -4,26 +4,27 @@ #include "semantic_provider_impl.h" -#include <fidl/fuchsia.accessibility.semantics/cpp/fidl.h> -#include <fidl/fuchsia.ui.views/cpp/hlcpp_conversion.h> -#include <lib/async/default.h> +#include <fuchsia/accessibility/semantics/cpp/fidl.h> #include <lib/ui/scenic/cpp/view_ref_pair.h> #include <algorithm> #include <memory> -#include "base/fuchsia/fidl_event_handler.h" +#include "base/auto_reset.h" +#include "base/fuchsia/process_context.h" #include "base/fuchsia/scoped_service_binding.h" #include "base/fuchsia/test_component_context_for_process.h" #include "base/functional/callback.h" #include "base/run_loop.h" +#include "base/test/bind.h" #include "base/test/task_environment.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/transform.h" namespace ui { namespace { -using fuchsia_accessibility_semantics::Node; +using fuchsia::accessibility::semantics::Node; class AXFuchsiaSemanticProviderDelegate : public AXFuchsiaSemanticProvider::Delegate { @@ -38,18 +39,19 @@ bool OnAccessibilityAction( uint32_t node_id, - fuchsia_accessibility_semantics::Action action) override { + fuchsia::accessibility::semantics::Action action) override { on_accessibility_action_called_ = true; on_accessibility_action_node_id_ = node_id; on_accessibility_action_action_ = std::move(action); return true; } - void OnHitTest(fuchsia_math::PointF point, - HitTestCallback callback) override { + void OnHitTest( + fuchsia::math::PointF point, + fuchsia::accessibility::semantics::SemanticListener::HitTestCallback + callback) override { on_hit_test_called_ = true; on_hit_test_point_ = std::move(point); - std::move(callback).Run({}); } void OnSemanticsEnabled(bool enabled) override { @@ -59,9 +61,9 @@ bool on_semantics_manager_connection_closed_called_; bool on_accessibility_action_called_; uint32_t on_accessibility_action_node_id_ = 10000000; - fuchsia_accessibility_semantics::Action on_accessibility_action_action_; + fuchsia::accessibility::semantics::Action on_accessibility_action_action_; bool on_hit_test_called_; - fuchsia_math::PointF on_hit_test_point_; + fuchsia::math::PointF on_hit_test_point_; bool on_semantics_enabled_called_; }; @@ -69,25 +71,25 @@ // (0 (1 2 (3 4 (5)))) std::vector<Node> TreeNodes() { Node node_0; - node_0.node_id(0u); - node_0.child_ids({{1u, 2u}}); + node_0.set_node_id(0u); + node_0.set_child_ids({1u, 2u}); Node node_1; - node_1.node_id(1u); + node_1.set_node_id(1u); Node node_2; - node_2.node_id(2u); - node_2.child_ids({{3u, 4u}}); + node_2.set_node_id(2u); + node_2.set_child_ids({3u, 4u}); Node node_3; - node_3.node_id(3u); + node_3.set_node_id(3u); Node node_4; - node_4.node_id(4u); - node_4.child_ids({{5u}}); + node_4.set_node_id(4u); + node_4.set_child_ids({5u}); Node node_5; - node_5.node_id(5u); + node_5.set_node_id(5u); std::vector<Node> update; update.push_back(std::move(node_0)); @@ -101,14 +103,12 @@ class AXFuchsiaSemanticProviderTest : public ::testing::Test, - public fidl::Server<fuchsia_accessibility_semantics::SemanticsManager>, - public fidl::Server<fuchsia_accessibility_semantics::SemanticTree> { + public fuchsia::accessibility::semantics::SemanticsManager, + public fuchsia::accessibility::semantics::SemanticTree { public: AXFuchsiaSemanticProviderTest() : semantics_manager_bindings_(test_context_.additional_services(), this), - semantic_listener_error_handler_( - base::BindRepeating([](fidl::UnbindInfo info) { ADD_FAILURE(); })) { - } + semantic_tree_binding_(this) {} ~AXFuchsiaSemanticProviderTest() override = default; AXFuchsiaSemanticProviderTest(const AXFuchsiaSemanticProviderTest&) = delete; AXFuchsiaSemanticProviderTest& operator=( @@ -118,8 +118,7 @@ delegate_ = std::make_unique<AXFuchsiaSemanticProviderDelegate>(); semantic_provider_ = std::make_unique<ui::AXFuchsiaSemanticProviderImpl>( - fidl::HLCPPToNatural(std::move(view_ref_pair.view_ref)), - delegate_.get()); + std::move(view_ref_pair.view_ref), delegate_.get()); // Spin the loop to allow registration with the SemanticsManager to be // processed. @@ -127,52 +126,39 @@ } protected: - // fuchsia_accessibility_semantics::SemanticsManager implementation. + // fuchsia::accessibility::semantics::SemanticsManager implementation. void RegisterViewForSemantics( - AXFuchsiaSemanticProviderTest::RegisterViewForSemanticsRequest& request, - AXFuchsiaSemanticProviderTest::RegisterViewForSemanticsCompleter::Sync& - completer) final { - semantic_listener_.Bind(std::move(request.listener()), - async_get_default_dispatcher(), - &semantic_listener_error_handler_); - semantic_tree_binding_.emplace(async_get_default_dispatcher(), - std::move(request.semantic_tree_request()), - this, fidl::kIgnoreBindingClosure); - semantic_listener_->OnSemanticsModeChanged({{.updates_enabled = true}}) - .Then( - [](fidl::Result<fuchsia_accessibility_semantics::SemanticListener:: - OnSemanticsModeChanged>& result) { - ASSERT_TRUE(result.is_ok()); - }); + fuchsia::ui::views::ViewRef view_ref, + fidl::InterfaceHandle<fuchsia::accessibility::semantics::SemanticListener> + listener, + fidl::InterfaceRequest<fuchsia::accessibility::semantics::SemanticTree> + semantic_tree_request) final { + semantic_listener_ = listener.Bind(); + semantic_listener_.set_error_handler([](zx_status_t status) { + // The test should fail if an error occurs. + ADD_FAILURE(); + }); + semantic_tree_binding_.Bind(std::move(semantic_tree_request)); + semantic_listener_->OnSemanticsModeChanged(true, []() {}); } - // fuchsia_accessibility_semantics::SemanticTree implementation. + // fuchsia::accessibility::semantics::SemanticTree implementation. void UpdateSemanticNodes( - AXFuchsiaSemanticProviderTest::UpdateSemanticNodesRequest& request, - AXFuchsiaSemanticProviderTest::UpdateSemanticNodesCompleter::Sync& - ignored_completer) final { + std::vector<fuchsia::accessibility::semantics::Node> nodes) final { num_update_semantic_nodes_called_++; - node_updates_.push_back(std::move(request.nodes())); + node_updates_.push_back(std::move(nodes)); } - void DeleteSemanticNodes( - AXFuchsiaSemanticProviderTest::DeleteSemanticNodesRequest& request, - AXFuchsiaSemanticProviderTest::DeleteSemanticNodesCompleter::Sync& - ignored_completer) final { + void DeleteSemanticNodes(std::vector<uint32_t> node_ids) final { num_delete_semantic_nodes_called_++; } - void CommitUpdates( - AXFuchsiaSemanticProviderTest::CommitUpdatesCompleter::Sync& completer) - final { - completer.Reply(); - } + void CommitUpdates(CommitUpdatesCallback callback) final { callback(); } void SendSemanticEvent( - AXFuchsiaSemanticProviderTest::SendSemanticEventRequest& request, - AXFuchsiaSemanticProviderTest::SendSemanticEventCompleter::Sync& - completer) override { - completer.Reply(); + fuchsia::accessibility::semantics::SemanticEvent semantic_event, + SendSemanticEventCallback callback) override { + callback(); } - const std::vector<std::vector<fuchsia_accessibility_semantics::Node>>& + const std::vector<std::vector<fuchsia::accessibility::semantics::Node>>& node_updates() { return node_updates_; } @@ -183,8 +169,8 @@ base::TestComponentContextForProcess test_context_; // Binding to fake Semantics Manager Fuchsia service, implemented by this test // class. - base::ScopedNaturalServiceBinding< - fuchsia_accessibility_semantics::SemanticsManager> + base::ScopedServiceBinding< + fuchsia::accessibility::semantics::SemanticsManager> semantics_manager_bindings_; uint32_t num_update_semantic_nodes_called_ = 0; @@ -192,23 +178,19 @@ base::RepeatingClosure on_commit_; - fidl::Client<fuchsia_accessibility_semantics::SemanticListener> - semantic_listener_; - base::FidlErrorEventHandler<fuchsia_accessibility_semantics::SemanticListener> - semantic_listener_error_handler_; - absl::optional< - fidl::ServerBinding<fuchsia_accessibility_semantics::SemanticTree>> + fuchsia::accessibility::semantics::SemanticListenerPtr semantic_listener_; + fidl::Binding<fuchsia::accessibility::semantics::SemanticTree> semantic_tree_binding_; std::unique_ptr<AXFuchsiaSemanticProviderDelegate> delegate_; std::unique_ptr<ui::AXFuchsiaSemanticProviderImpl> semantic_provider_; // Node updates batched per API call to UpdateSemanticNodes(). - std::vector<std::vector<fuchsia_accessibility_semantics::Node>> node_updates_; + std::vector<std::vector<fuchsia::accessibility::semantics::Node>> + node_updates_; }; TEST_F(AXFuchsiaSemanticProviderTest, HandlesOnSemanticsConnectionClosed) { - ASSERT_TRUE(semantic_tree_binding_.has_value()); - semantic_tree_binding_->Close(ZX_ERR_PEER_CLOSED); + semantic_tree_binding_.Close(ZX_ERR_PEER_CLOSED); // Spin the loop to allow the channel-close to be handled. base::RunLoop().RunUntilIdle(); @@ -218,17 +200,9 @@ TEST_F(AXFuchsiaSemanticProviderTest, HandlesOnAccessibilityAction) { bool action_handled = false; - semantic_listener_ - ->OnAccessibilityActionRequested({{ - .node_id = 1u, - .action = fuchsia_accessibility_semantics::Action::kDefault, - }}) - .Then([&action_handled]( - fidl::Result<fuchsia_accessibility_semantics::SemanticListener:: - OnAccessibilityActionRequested>& result) { - ASSERT_TRUE(result.is_ok()); - action_handled = result->handled(); - }); + semantic_listener_->OnAccessibilityActionRequested( + /*node_id=*/1u, fuchsia::accessibility::semantics::Action::DEFAULT, + [&action_handled](bool handled) { action_handled = handled; }); // Spin the loop to handle the request, and receive the response. base::RunLoop().RunUntilIdle(); @@ -237,7 +211,7 @@ EXPECT_TRUE(delegate_->on_accessibility_action_called_); EXPECT_EQ(delegate_->on_accessibility_action_node_id_, 1u); EXPECT_EQ(delegate_->on_accessibility_action_action_, - fuchsia_accessibility_semantics::Action::kDefault); + fuchsia::accessibility::semantics::Action::DEFAULT); } TEST_F(AXFuchsiaSemanticProviderTest, HandlesOnHitTest) { @@ -246,32 +220,31 @@ // Note that the point is sent here and will be converted according to the // device scale used. Only then it gets sent to the handler, which receives // the value already with the proper scaling. - semantic_listener_ - ->HitTest({{ - .local_point = {{.x = 4, .y = 6}}, - }}) - .Then([](fidl::Result< - fuchsia_accessibility_semantics::SemanticListener::HitTest>& - result) { ASSERT_TRUE(result.is_ok()); }); + fuchsia::math::PointF point; + point.x = 4; + point.y = 6; + semantic_listener_->HitTest(std::move(point), [](auto...) {}); // Spin the loop to allow the call to be processed. base::RunLoop().RunUntilIdle(); EXPECT_TRUE(delegate_->on_hit_test_called_); - EXPECT_EQ(delegate_->on_hit_test_point_.x(), 8.0); - EXPECT_EQ(delegate_->on_hit_test_point_.y(), 12.0); + EXPECT_EQ(delegate_->on_hit_test_point_.x, 8.0); + EXPECT_EQ(delegate_->on_hit_test_point_.y, 12.0); } -// Verify that the AXFuchsiaSemanticProviderImpl constructor triggered the call -// chain RegisterViewForSemantics -> OnSemanticsModeChanged -> -// OnSemanticsEnabled. TEST_F(AXFuchsiaSemanticProviderTest, HandlesOnSemanticsEnabled) { + semantic_listener_->OnSemanticsModeChanged(false, [](auto...) {}); + + // Spin the loop to handle the call. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(delegate_->on_semantics_enabled_called_); } TEST_F(AXFuchsiaSemanticProviderTest, SendsRootOnly) { Node root; - root.node_id(0u); + root.set_node_id(0u); EXPECT_TRUE(semantic_provider_->Update(std::move(root))); // Spin the loop to process the update call. @@ -331,8 +304,8 @@ EXPECT_TRUE(semantic_provider_->HasPendingUpdates()); Node node_4; - node_4.node_id(4u); - node_4.child_ids({}); + node_4.set_node_id(4u); + node_4.set_child_ids({}); EXPECT_TRUE(semantic_provider_->Update(std::move(node_4))); // Spin the loop to process the node update. @@ -358,8 +331,8 @@ EXPECT_FALSE(semantic_provider_->HasPendingUpdates()); Node node_4; - node_4.node_id(4u); - node_4.child_ids({}); // This removes child 5. + node_4.set_node_id(4u); + node_4.set_child_ids({}); // This removes child 5. EXPECT_TRUE(semantic_provider_->Update(std::move(node_4))); // Spin the loop to process the update call. @@ -399,8 +372,8 @@ // Add child 5 to another node. Node node_1; - node_1.node_id(1u); - node_1.child_ids({{5u}}); + node_1.set_node_id(1u); + node_1.set_child_ids({5u}); EXPECT_TRUE(semantic_provider_->Update(std::move(node_1))); // Spin the loop to process the update. @@ -409,8 +382,8 @@ EXPECT_TRUE(semantic_provider_->HasPendingUpdates()); Node node_4; - node_4.node_id(4u); - node_4.child_ids({}); + node_4.set_node_id(4u); + node_4.set_child_ids({}); EXPECT_TRUE(semantic_provider_->Update(std::move(node_4))); // Spin the loop to process the update. @@ -436,8 +409,8 @@ // Add child 5 to another node. Note that 5 will have two parents, and the // commit must be held until it has only one. Node node_1; - node_1.node_id(1u); - node_1.child_ids({{5u}}); + node_1.set_node_id(1u); + node_1.set_child_ids({5u}); EXPECT_TRUE(semantic_provider_->Update(std::move(node_1))); // Spin the loop to process the update. @@ -447,8 +420,8 @@ // Updates node 4 to no longer point to 5. Node node_4; - node_4.node_id(4u); - node_4.child_ids({}); + node_4.set_node_id(4u); + node_4.set_child_ids({}); EXPECT_TRUE(semantic_provider_->Update(std::move(node_4))); // Spin the loop to process the update. @@ -472,8 +445,8 @@ EXPECT_FALSE(semantic_provider_->HasPendingUpdates()); Node new_root; - new_root.node_id(0u); - new_root.child_ids({{1u, 2u}}); + new_root.set_node_id(0u); + new_root.set_child_ids({1u, 2u}); EXPECT_TRUE(semantic_provider_->Update(std::move(new_root))); // Spin the loop to process the update. @@ -488,11 +461,11 @@ std::vector<Node> updates; for (uint32_t i = 0; i < 30; ++i) { Node node; - node.node_id(i); - node.child_ids({{i + 1}}); + node.set_node_id(i); + node.set_child_ids({i + 1}); updates.push_back(std::move(node)); } - updates.back().child_ids()->clear(); + updates.back().clear_child_ids(); for (auto& node : updates) { EXPECT_TRUE(semantic_provider_->Update(std::move(node))); @@ -535,12 +508,12 @@ // update sent to fuchsia should not contain a transform. { Node node; - node.node_id(0u); + node.set_node_id(0u); // Set child_ids to make sure they're not overwritten later. - node.child_ids({{1u}}); + node.set_child_ids({1u}); semantic_provider_->Update(std::move(node)); Node child; - child.node_id(1u); + child.set_node_id(1u); semantic_provider_->Update(std::move(child)); } @@ -553,13 +526,13 @@ const auto& first_update_batch = node_updates()[0]; ASSERT_EQ(first_update_batch.size(), 2u); EXPECT_EQ(first_update_batch[0].node_id(), 0u); - const fuchsia_accessibility_semantics::Node& node = first_update_batch[0]; - ASSERT_TRUE(node.node_to_container_transform().has_value()); - const auto& transform = node.node_to_container_transform()->matrix(); + const fuchsia::accessibility::semantics::Node& node = first_update_batch[0]; + ASSERT_TRUE(node.has_node_to_container_transform()); + const auto& transform = node.node_to_container_transform().matrix; EXPECT_EQ(transform[0], 1.f); EXPECT_EQ(transform[5], 1.f); - ASSERT_EQ(node.child_ids()->size(), 1u); - EXPECT_EQ(node.child_ids().value()[0], 1u); + ASSERT_EQ(node.child_ids().size(), 1u); + EXPECT_EQ(node.child_ids()[0], 1u); } // Now, set a new pixel scale != 1. This step should force an update to @@ -576,22 +549,23 @@ ASSERT_EQ(node_updates().size(), 2u); const auto& second_update_batch = node_updates()[1]; ASSERT_EQ(second_update_batch.size(), 1u); - const fuchsia_accessibility_semantics::Node& node = second_update_batch[0]; + const fuchsia::accessibility::semantics::Node& node = + second_update_batch[0]; EXPECT_EQ(node.node_id(), 0u); - ASSERT_TRUE(node.node_to_container_transform().has_value()); - const auto& transform = node.node_to_container_transform()->matrix(); + ASSERT_TRUE(node.has_node_to_container_transform()); + const auto& transform = node.node_to_container_transform().matrix; EXPECT_EQ(transform[0], 1.f / kPixelScale); EXPECT_EQ(transform[5], 1.f / kPixelScale); - ASSERT_EQ(node.child_ids()->size(), 1u); - EXPECT_EQ(node.child_ids().value()[0], 1u); + ASSERT_EQ(node.child_ids().size(), 1u); + EXPECT_EQ(node.child_ids()[0], 1u); } // Finally, send one more update, and verify that the semantic provider // accounted for the new pixel scale in the root node's transform. { Node node; - node.node_id(0u); - node.child_ids({{1u}}); + node.set_node_id(0u); + node.set_child_ids({1u}); semantic_provider_->Update(std::move(node)); } @@ -604,14 +578,14 @@ ASSERT_EQ(node_updates().size(), 3u); const auto& third_update_batch = node_updates()[2]; ASSERT_EQ(third_update_batch.size(), 1u); - const fuchsia_accessibility_semantics::Node& node = third_update_batch[0]; + const fuchsia::accessibility::semantics::Node& node = third_update_batch[0]; EXPECT_EQ(node.node_id(), 0u); - ASSERT_TRUE(node.node_to_container_transform().has_value()); - const auto& transform = node.node_to_container_transform()->matrix(); + ASSERT_TRUE(node.has_node_to_container_transform()); + const auto& transform = node.node_to_container_transform().matrix; EXPECT_EQ(transform[0], 1.f / kPixelScale); EXPECT_EQ(transform[5], 1.f / kPixelScale); - ASSERT_EQ(node.child_ids()->size(), 1u); - EXPECT_EQ(node.child_ids().value()[0], 1u); + ASSERT_EQ(node.child_ids().size(), 1u); + EXPECT_EQ(node.child_ids()[0], 1u); } }
diff --git a/ui/base/cocoa/bubble_closer.h b/ui/base/cocoa/bubble_closer.h index edc3558..4bf694f 100644 --- a/ui/base/cocoa/bubble_closer.h +++ b/ui/base/cocoa/bubble_closer.h
@@ -5,7 +5,7 @@ #ifndef UI_BASE_COCOA_BUBBLE_CLOSER_H_ #define UI_BASE_COCOA_BUBBLE_CLOSER_H_ -#include <objc/objc.h> +#include <memory> #include "base/component_export.h" #include "base/functional/callback.h" @@ -31,8 +31,11 @@ private: void OnClickOutside(); - id event_tap_ = nil; // Weak. Owned by AppKit. base::RepeatingClosure on_click_outside_; + + struct ObjCStorage; + std::unique_ptr<ObjCStorage> objc_storage_; + base::WeakPtrFactory<BubbleCloser> factory_{this}; };
diff --git a/ui/base/cocoa/bubble_closer.mm b/ui/base/cocoa/bubble_closer.mm index a0b19a0..e3b05d9 100644 --- a/ui/base/cocoa/bubble_closer.mm +++ b/ui/base/cocoa/bubble_closer.mm
@@ -6,13 +6,20 @@ #import <AppKit/AppKit.h> +#include <memory> + #include "base/memory/weak_ptr.h" namespace ui { +struct BubbleCloser::ObjCStorage { + id event_tap_ = nil; // Weak. Owned by AppKit. +}; + BubbleCloser::BubbleCloser(NSWindow* window, base::RepeatingClosure on_click_outside) - : on_click_outside_(std::move(on_click_outside)) { + : on_click_outside_(std::move(on_click_outside)), + objc_storage_(std::make_unique<ObjCStorage>()) { // Capture a WeakPtr. This allows the block to detect another event monitor // for the same event deleting |this|. base::WeakPtr<BubbleCloser> weak_ptr = factory_.GetWeakPtr(); @@ -45,14 +52,14 @@ return event; }; - event_tap_ = + objc_storage_->event_tap_ = [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown handler:block]; } BubbleCloser::~BubbleCloser() { - [NSEvent removeMonitor:event_tap_]; + [NSEvent removeMonitor:objc_storage_->event_tap_]; } void BubbleCloser::OnClickOutside() {
diff --git a/ui/compositor/overscroll/scroll_input_handler.cc b/ui/compositor/overscroll/scroll_input_handler.cc index b744855..ac9904d3 100644 --- a/ui/compositor/overscroll/scroll_input_handler.cc +++ b/ui/compositor/overscroll/scroll_input_handler.cc
@@ -70,7 +70,7 @@ // Falling back to the main thread should never be required when an explicit // ElementId is provided. - DCHECK(!result.needs_main_thread_hit_test); + DCHECK(!result.main_thread_hit_test_reasons); cc::ScrollState scroll_state = CreateScrollState(event, false); input_handler_weak_ptr_->ScrollUpdate(&scroll_state, base::TimeDelta());
diff --git a/ui/events/ash/keyboard_capability.cc b/ui/events/ash/keyboard_capability.cc index c1ce7bf..bd2b88a 100644 --- a/ui/events/ash/keyboard_capability.cc +++ b/ui/events/ash/keyboard_capability.cc
@@ -20,6 +20,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "device/udev_linux/scoped_udev.h" +#include "ui/base/ui_base_features.h" #include "ui/events/ash/event_rewriter_ash.h" #include "ui/events/ash/keyboard_layout_util.h" #include "ui/events/ash/mojom/modifier_key.mojom-shared.h" @@ -36,6 +37,10 @@ using KeyboardTopRowLayout = KeyboardCapability::KeyboardTopRowLayout; using DeviceType = KeyboardCapability::DeviceType; +// Represents scancode value seen in scan code mapping which denotes that the +// FKey is missing on the physical device. +const int kCustomAbsentScanCode = 0x00; + // Hotrod controller vendor/product ids. const int kHotrodRemoteVendorId = 0x0471; const int kHotrodRemoteProductId = 0x21cc; @@ -44,6 +49,11 @@ constexpr char kCustomTopRowLayoutAttribute[] = "function_row_physmap"; constexpr char kCustomTopRowLayoutProperty[] = "FUNCTION_ROW_PHYSMAP"; +constexpr KeyboardCode kFunctionKeys[] = { + VKEY_F1, VKEY_F2, VKEY_F3, VKEY_F4, VKEY_F5, + VKEY_F6, VKEY_F7, VKEY_F8, VKEY_F9, VKEY_F10, + VKEY_F11, VKEY_F12, VKEY_F13, VKEY_F14, VKEY_F15, +}; constexpr KeyboardCode kMaxCustomTopRowLayoutFKeyCode = VKEY_F15; constexpr size_t kNumCustomTopRowFKeys = (kMaxCustomTopRowLayoutFKeyCode - VKEY_F1) + 1; @@ -294,6 +304,69 @@ layout, std::move(top_row_scan_codes)}; } +std::vector<TopRowActionKey> IdentifyCustomTopRowActionKeys( + const std::vector<uint32_t>& top_row_scan_codes) { + // TODO(dpad): Handle privacy screen in scan code mapping. + static constexpr auto kCustomScancodeMapping = + base::MakeFixedFlatMap<uint32_t, TopRowActionKey>({ + // Scan code is only `kCustomScanCodeFKeyMissing` when the FKey is + // absent on the keyboard. + {kCustomAbsentScanCode, TopRowActionKey::kNone}, + + // Vivaldi-specific extended Set-1 AT-style scancodes. + {0x90, TopRowActionKey::kPreviousTrack}, + {0x91, TopRowActionKey::kFullscreen}, + {0x92, TopRowActionKey::kOverview}, + {0x93, TopRowActionKey::kScreenshot}, + {0x94, TopRowActionKey::kScreenBrightnessDown}, + {0x95, TopRowActionKey::kScreenBrightnessUp}, + {0x97, TopRowActionKey::kKeyboardBacklightDown}, + {0x98, TopRowActionKey::kKeyboardBacklightUp}, + {0x99, TopRowActionKey::kNextTrack}, + {0x9A, TopRowActionKey::kPlayPause}, + {0x9B, TopRowActionKey::kMicrophoneMute}, + {0x9E, TopRowActionKey::kKeyboardBacklightToggle}, + {0xA0, TopRowActionKey::kVolumeMute}, + {0xAE, TopRowActionKey::kVolumeDown}, + {0xB0, TopRowActionKey::kVolumeUp}, + {0xE9, TopRowActionKey::kForward}, + {0xEA, TopRowActionKey::kBack}, + {0xE7, TopRowActionKey::kRefresh}, + + // HID 32-bit usage codes + {0x070046, TopRowActionKey::kScreenshot}, + {0x0B002F, TopRowActionKey::kMicrophoneMute}, + {0x0C00E2, TopRowActionKey::kVolumeMute}, + {0x0C00E9, TopRowActionKey::kVolumeUp}, + {0x0C00EA, TopRowActionKey::kVolumeDown}, + {0x0C006F, TopRowActionKey::kScreenBrightnessUp}, + {0x0C0070, TopRowActionKey::kScreenBrightnessDown}, + {0x0C0079, TopRowActionKey::kKeyboardBacklightUp}, + {0x0C007A, TopRowActionKey::kKeyboardBacklightDown}, + {0x0C007C, TopRowActionKey::kKeyboardBacklightToggle}, + {0x0C00B5, TopRowActionKey::kNextTrack}, + {0x0C00B6, TopRowActionKey::kPreviousTrack}, + {0x0C00CD, TopRowActionKey::kPlayPause}, + {0x0C0224, TopRowActionKey::kBack}, + {0x0C0225, TopRowActionKey::kForward}, + {0x0C0227, TopRowActionKey::kRefresh}, + {0x0C0232, TopRowActionKey::kFullscreen}, + {0x0C029F, TopRowActionKey::kOverview}, + }); + + std::vector<TopRowActionKey> top_row_action_keys; + top_row_action_keys.reserve(top_row_scan_codes.size()); + for (const auto& scancode : top_row_scan_codes) { + auto* action_key = kCustomScancodeMapping.find(scancode); + if (action_key != kCustomScancodeMapping.end()) { + top_row_action_keys.push_back(action_key->second); + } else { + top_row_action_keys.push_back(TopRowActionKey::kUnknown); + } + } + return top_row_action_keys; +} + std::vector<TopRowActionKey> IdentifyTopRowActionKeys( DeviceType device_type, KeyboardTopRowLayout layout, @@ -308,8 +381,7 @@ return {kLayoutWilcoDrallionTopRowActionKeys.begin(), kLayoutWilcoDrallionTopRowActionKeys.end()}; case KeyboardCapability::KeyboardTopRowLayout::kKbdTopRowLayoutCustom: - // TODO(dpad): Implement custom top row action key mapping. - return {}; + return IdentifyCustomTopRowActionKeys(top_row_scan_codes); } } @@ -365,6 +437,38 @@ return event_device_info; } +// static +absl::optional<TopRowActionKey> KeyboardCapability::ConvertToTopRowActionKey( + ui::KeyboardCode key_code) { + static constexpr auto kVKeyToTopRowActionKeyMap = + base::MakeFixedFlatMap<ui::KeyboardCode, TopRowActionKey>({ + {VKEY_BROWSER_BACK, TopRowActionKey::kBack}, + {VKEY_BROWSER_FORWARD, TopRowActionKey::kForward}, + {VKEY_BROWSER_REFRESH, TopRowActionKey::kRefresh}, + {VKEY_ZOOM, TopRowActionKey::kFullscreen}, + {VKEY_MEDIA_LAUNCH_APP1, TopRowActionKey::kOverview}, + {VKEY_SNAPSHOT, TopRowActionKey::kScreenshot}, + {VKEY_BRIGHTNESS_DOWN, TopRowActionKey::kScreenBrightnessDown}, + {VKEY_BRIGHTNESS_UP, TopRowActionKey::kScreenBrightnessUp}, + {VKEY_MICROPHONE_MUTE_TOGGLE, TopRowActionKey::kMicrophoneMute}, + {VKEY_VOLUME_MUTE, TopRowActionKey::kVolumeMute}, + {VKEY_VOLUME_DOWN, TopRowActionKey::kVolumeDown}, + {VKEY_VOLUME_UP, TopRowActionKey::kVolumeUp}, + {VKEY_KBD_BACKLIGHT_TOGGLE, + TopRowActionKey::kKeyboardBacklightToggle}, + {VKEY_KBD_BRIGHTNESS_DOWN, TopRowActionKey::kKeyboardBacklightDown}, + {VKEY_KBD_BRIGHTNESS_UP, TopRowActionKey::kKeyboardBacklightUp}, + {VKEY_MEDIA_NEXT_TRACK, TopRowActionKey::kNextTrack}, + {VKEY_MEDIA_PREV_TRACK, TopRowActionKey::kPreviousTrack}, + {VKEY_MEDIA_PLAY_PAUSE, TopRowActionKey::kPlayPause}, + {VKEY_ALL_APPLICATIONS, TopRowActionKey::kLauncher}, + }); + const auto* action_key = kVKeyToTopRowActionKeyMap.find(key_code); + return (action_key != kVKeyToTopRowActionKeyMap.end()) + ? absl::make_optional<TopRowActionKey>(action_key->second) + : absl::nullopt; +} + void KeyboardCapability::AddObserver(Observer* observer) { delegate_->AddObserver(observer); } @@ -425,6 +529,24 @@ return absl::nullopt; } +absl::optional<KeyboardCode> KeyboardCapability::GetCorrespondingFunctionKey( + const InputDevice& keyboard, + TopRowActionKey action_key) const { + auto* keyboard_info = GetKeyboardInfo(keyboard); + if (!keyboard_info) { + return absl::nullopt; + } + + auto iter = + base::ranges::find(keyboard_info->top_row_action_keys, action_key); + if (iter == keyboard_info->top_row_action_keys.end()) { + return absl::nullopt; + } + + return kFunctionKeys[std::distance(keyboard_info->top_row_action_keys.begin(), + iter)]; +} + bool KeyboardCapability::HasLauncherButton( const absl::optional<InputDevice>& keyboard) { // Use current implementation. If keyboard is provided, launcher button @@ -617,7 +739,8 @@ // Enable only when flag is enabled to avoid crashing while problem is // addressed. This issue exists the `EventDeviceInfo` objects are only allowed // to be created on a thread that allows blocking. See b/272960076 - if (ash::features::IsInputDeviceSettingsSplitEnabled()) { + if (ash::features::IsInputDeviceSettingsSplitEnabled() || + features::IsShortcutCustomizationAppEnabled()) { keyboard_info.event_device_info = CreateEventDeviceInfoFromInputDevice(keyboard); } @@ -651,6 +774,31 @@ return GetTopRowScanCodes(*keyboard); } +bool KeyboardCapability::HasGlobeKey(const InputDevice& keyboard) const { + const KeyboardInfo* keyboard_info = GetKeyboardInfo(keyboard); + if (!keyboard_info) { + return false; + } + + // TODO(dpad): This is not quite right, some external keyboards have it as + // well. + // Globe key only exists on drallion or wilco devices. + return keyboard_info->top_row_layout == + KeyboardTopRowLayout::kKbdTopRowLayoutDrallion || + keyboard_info->top_row_layout == + KeyboardTopRowLayout::kKbdTopRowLayoutWilco; +} + +bool KeyboardCapability::HasGlobeKeyOnAnyKeyboard() const { + for (const ui::InputDevice& keyboard : + ui::DeviceDataManager::GetInstance()->GetKeyboardDevices()) { + if (HasGlobeKey(keyboard)) { + return true; + } + } + return false; +} + void KeyboardCapability::OnDeviceListsComplete() { TrimKeyboardInfoMap(); } @@ -724,7 +872,7 @@ // Handle assistant key. if (key_code == KeyboardCode::VKEY_ASSISTANT) { const KeyboardInfo* keyboard_info = GetKeyboardInfo(keyboard); - return keyboard_info && + return keyboard_info && keyboard_info->event_device_info && keyboard_info->event_device_info->HasKeyEvent(KEY_ASSISTANT); }
diff --git a/ui/events/ash/keyboard_capability.h b/ui/events/ash/keyboard_capability.h index ae58841..74c2ad3 100644 --- a/ui/events/ash/keyboard_capability.h +++ b/ui/events/ash/keyboard_capability.h
@@ -23,8 +23,10 @@ // TODO(dpad): Handle privacy screen toggle and display mirror top row keys. enum class TopRowActionKey { - kBack = 0, - kMinValue = kBack, + kNone = 0, + kMinValue = kNone, + kUnknown, + kBack, kForward, kRefresh, kFullscreen, @@ -42,7 +44,8 @@ kNextTrack, kPreviousTrack, kPlayPause, - kMaxValue = kPlayPause, + kLauncher, + kMaxValue = kLauncher, }; inline constexpr auto kLayout1TopRowActionKeys = @@ -238,6 +241,11 @@ static std::unique_ptr<EventDeviceInfo> CreateEventDeviceInfoFromInputDevice( const InputDevice& keyboard); + // Converts from the given `key_code` to the corresponding meaning in + // `TopRowActionKey` enum. + static absl::optional<TopRowActionKey> ConvertToTopRowActionKey( + ui::KeyboardCode key_code); + void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); @@ -324,6 +332,16 @@ TopRowActionKey action_key) const; bool HasTopRowActionKeyOnAnyKeyboard(TopRowActionKey action_key) const; + // Check if the globe key exists on the given keyboard. + bool HasGlobeKey(const InputDevice& keyboard) const; + bool HasGlobeKeyOnAnyKeyboard() const; + + // Gets the corresponding function key for the given `action_key` on the given + // `keyboard`. + absl::optional<KeyboardCode> GetCorrespondingFunctionKey( + const InputDevice& keyboard, + TopRowActionKey action_key) const; + const base::flat_map<int, KeyboardInfo>& keyboard_info_map() const { return keyboard_info_map_; }
diff --git a/ui/message_center/views/message_popup_collection.cc b/ui/message_center/views/message_popup_collection.cc index 7e028ae..e8ec0cb7 100644 --- a/ui/message_center/views/message_popup_collection.cc +++ b/ui/message_center/views/message_popup_collection.cc
@@ -11,7 +11,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/time/time.h" #include "base/timer/timer.h" -#include "build/chromeos_buildflags.h" #include "ui/compositor/layer.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/gfx/animation/linear_animation.h" @@ -24,9 +23,6 @@ #include "ui/message_center/views/notification_view.h" #include "ui/views/animation/animation_builder.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) -#include "ash/constants/ash_features.h" -#endif namespace message_center { namespace { @@ -80,7 +76,7 @@ if (state_ != State::IDLE) { // If not in IDLE state, start animation. base::TimeDelta animation_duration; - if (state_ == State::MOVE_DOWN || state_ == State::MOVE_UP_FOR_INVERSE) { + if (state_ == State::MOVE_DOWN) { animation_duration = kMoveDownDuration; } else { animation_duration = kFadeInFadeOutDuration; @@ -309,17 +305,7 @@ // If FADE_OUT animation is finished, remove the animated popup. if (state_ == State::FADE_OUT) { - // In inverse mode if the popups are not removed in the order they were - // added (the ones on the top are removed while the ones at the bottom stay) - // we need to move the remaining popups down. This might happen if the - // popups have different TTL. - bool move_down_needed = inverse_ && !AreAllAnimatingPopupsFirst(); CloseAnimatingPopups(); - if (move_down_needed) { - state_ = State::MOVE_DOWN; - MoveDownPopups(); - return; - } } if (state_ == State::FADE_IN || state_ == State::MOVE_DOWN || @@ -327,22 +313,15 @@ // If the animation is finished, transition to IDLE. state_ = State::IDLE; } else if (state_ == State::FADE_OUT && !popup_items_.empty()) { - if ((HasAddedPopup() && CollapseAllPopups()) || !inverse_) { - // If FADE_OUT animation is finished and we still have remaining popups, - // we have to MOVE_DOWN them. - // If we're going to add a new popup after this MOVE_DOWN, do the collapse - // animation at the same time. Otherwise it will take another MOVE_DOWN. - state_ = State::MOVE_DOWN; - MoveDownPopups(); - } else { - // If there's no collapsable popups and |inverse_| is on, there's nothing - // to do after FADE_OUT. - state_ = State::IDLE; + if (HasAddedPopup()) { + CollapseAllPopups(); } - } else if (state_ == State::MOVE_UP_FOR_INVERSE) { - for (auto& item : popup_items_) - item.is_animating = item.will_fade_in; - state_ = State::FADE_IN; + // If FADE_OUT animation is finished and we still have remaining popups, + // we have to MOVE_DOWN them. + // If we're going to add a new popup after this MOVE_DOWN, do the collapse + // animation at the same time. Otherwise it will take another MOVE_DOWN. + state_ = State::MOVE_DOWN; + MoveDownPopups(); } } @@ -371,16 +350,8 @@ MoveDownPopups(); return; } else if (AddPopup()) { - // A popup is actually added. - if (inverse_ && popup_items_.size() > 1) { - // If |inverse_| is on and there are existing notifications that have to - // be moved up (existing ones + new one, so > 1), transition to - // MOVE_UP_FOR_INVERSE. - state_ = State::MOVE_UP_FOR_INVERSE; - } else { - // Show FADE_IN animation. - state_ = State::FADE_IN; - } + // A popup is actually added. Show FADE_IN animation. + state_ = State::FADE_IN; return; } } @@ -458,8 +429,7 @@ else if (state_ == State::FADE_OUT) item.popup->SetOpacity(gfx::Tween::FloatValueBetween(value, 1.0f, 0.0f)); - if (state_ == State::FADE_IN || state_ == State::MOVE_DOWN || - state_ == State::MOVE_UP_FOR_INVERSE) { + if (state_ == State::FADE_IN || state_ == State::MOVE_DOWN) { item.popup->SetPopupBounds( gfx::Tween::RectValueBetween(value, item.start_bounds, item.bounds)); } @@ -512,7 +482,6 @@ // Reset animation flags of existing popups. for (auto& item : popup_items_) { item.is_animating = false; - item.will_fade_in = false; } if (new_notification->group_child()) @@ -535,15 +504,6 @@ NotifyPopupAdded(item.popup); } - // There are existing notifications that have to be moved up (existing ones + - // new one, so > 1). - if (inverse_ && popup_items_.size() > 1) { - for (auto& item : popup_items_) { - item.will_fade_in = item.is_animating; - item.is_animating = !item.is_animating; - } - } - MessageCenter::Get()->DisplayedNotification(new_notification->id(), DISPLAY_SOURCE_POPUP); @@ -583,9 +543,6 @@ int base = 0; if (popup_items_.empty()) { base = GetBaseline(); - } else if (inverse_) { - base = IsTopDown() ? popup_items_.front().bounds.bottom() - : popup_items_.front().bounds.y(); } else { base = IsTopDown() ? popup_items_.back().bounds.bottom() : popup_items_.back().bounds.y(); @@ -602,16 +559,6 @@ : next_edge < work_area.y(); } -bool MessagePopupCollection::AreAllAnimatingPopupsFirst() const { - bool previous_item_was_animating = true; - for (const auto& item : popup_items_) { - if (item.is_animating && !previous_item_was_animating) - return false; - previous_item_was_animating = item.is_animating; - } - return true; -} - void MessagePopupCollection::CloseAnimatingPopups() { for (auto& item : popup_items_) { if (!item.is_animating) @@ -725,8 +672,7 @@ MessagePopupCollection::PopupItem* MessagePopupCollection::GetPopupItem( size_t index_from_top) { DCHECK_LT(index_from_top, popup_items_.size()); - return &popup_items_[inverse_ ? popup_items_.size() - index_from_top - 1 - : index_from_top]; + return &popup_items_[index_from_top]; } } // namespace message_center
diff --git a/ui/message_center/views/message_popup_collection.h b/ui/message_center/views/message_popup_collection.h index a60848bb..34a6199 100644 --- a/ui/message_center/views/message_popup_collection.h +++ b/ui/message_center/views/message_popup_collection.h
@@ -100,8 +100,6 @@ views::Widget* widget, views::Widget::InitParams* init_params) = 0; - void set_inverse() { inverse_ = true; } - protected: // Returns the x-origin for the given popup bounds in the current work area. virtual int GetPopupOriginX(const gfx::Rect& popup_bounds) const = 0; @@ -174,10 +172,6 @@ // Moving down notifications. Notification collapsing and resizing are also // done in MOVE_DOWN. MOVE_DOWN, - - // Moving up notifications in order to show new one by FADE_IN. This is only - // used when |inverse_| is true. - MOVE_UP_FOR_INVERSE }; // Stores animation related state of a popup. @@ -193,11 +187,6 @@ // The final bounds of the popup. gfx::Rect bounds; - // The popup is waiting for MOVE_UP_FOR_INVERSE animation so that it can - // FADE_IN after that. The value is only used when the animation type is - // MOVE_UP_FOR_INVERSE. - bool will_fade_in = false; - // If the popup is animating. bool is_animating = false; @@ -249,11 +238,6 @@ void ClosePopupsOutsideWorkArea(); void RemoveClosedPopupItems(); - // Returns true if all the animating popups are at the beginning of the - // collection or the queue is empty. Returns false only if there is an - // animating popup after a non-animating one. - bool AreAllAnimatingPopupsFirst() const; - // Stops all the animation and closes all the popups immediately. void CloseAllPopupsNow(); @@ -272,7 +256,6 @@ bool IsAnyPopupFocused() const; // Returns the popup which is visually |index_from_top|-th from the top. - // When |inverse_| is false, it's same as popup_items_[i]. PopupItem* GetPopupItem(size_t index_from_top); // Reset |recently_closed_by_user_| to false. Used by @@ -301,16 +284,6 @@ // IDLE state. bool resize_requested_ = false; - // Invert ordering of notification popups i.e. showing the latest notification - // at the top. It changes the state transition like this: - // Normal: - // * a new notification comes in: FADE_IN - // * a notification comes out: FADE_OUT -> MOVE_DOWN - // Inverted: - // * a new notification comes in: MOVE_UP_FOR_INVERSE -> FADE_IN - // * a notification comes out: FADE_OUT - bool inverse_ = false; - base::ScopedObservation<MessageCenter, MessageCenterObserver> message_center_observation_{this};
diff --git a/ui/message_center/views/message_popup_collection_unittest.cc b/ui/message_center/views/message_popup_collection_unittest.cc index e6afbe74..2d72ffb 100644 --- a/ui/message_center/views/message_popup_collection_unittest.cc +++ b/ui/message_center/views/message_popup_collection_unittest.cc
@@ -393,43 +393,6 @@ } } -TEST_F(MessagePopupCollectionTest, FadeInMultipleNotificationsInverse) { - popup_collection()->set_inverse(); - - std::vector<std::string> ids; - for (size_t i = 0; i < kMaxVisiblePopupNotifications; ++i) - ids.push_back(AddNotification()); - - for (size_t i = 0; i < ids.size(); ++i) { - EXPECT_EQ(ids[i], last_displayed_id()); - EXPECT_EQ(i + 1, GetPopupCounts()); - const int before_x = GetPopupAt(i)->GetBoundsInScreen().x(); - AnimateToMiddle(); - EXPECT_LT(0.0f, GetPopupAt(i)->GetOpacity()); - EXPECT_GT(before_x, GetPopupAt(i)->GetBoundsInScreen().x()); - AnimateToEnd(); - EXPECT_EQ(1.0f, GetPopupAt(i)->GetOpacity()); - EXPECT_TRUE(work_area().Contains(GetPopupAt(i)->GetBoundsInScreen())); - if (i + 1 < ids.size()) { - const int before_y = GetPopupAt(i)->GetBoundsInScreen().y(); - AnimateToMiddle(); - EXPECT_GT(before_y, GetPopupAt(i)->GetBoundsInScreen().y()); - AnimateToEnd(); - } - } - EXPECT_FALSE(IsAnimating()); - - EXPECT_EQ(kMaxVisiblePopupNotifications, GetPopupCounts()); - - for (size_t i = 0; i < ids.size(); ++i) - EXPECT_EQ(ids[i], GetPopupAt(i)->id()); - - for (size_t i = 0; i < ids.size() - 1; ++i) { - EXPECT_GT(GetPopupAt(i + 1)->GetBoundsInScreen().x(), - GetPopupAt(i)->GetBoundsInScreen().bottom()); - } -} - TEST_F(MessagePopupCollectionTest, UpdateContents) { std::string id = AddNotification(); AnimateToEnd(); @@ -572,99 +535,6 @@ EXPECT_FALSE(IsAnimating()); } -TEST_F(MessagePopupCollectionTest, NotificationsMoveDownInverse) { - popup_collection()->set_inverse(); - - std::vector<std::string> ids; - for (size_t i = 0; i < kMaxVisiblePopupNotifications; ++i) - ids.push_back(AddNotification()); - - std::string dismissed_id = ids[kMaxVisiblePopupNotifications - 1]; - std::string new_bottom_id = ids[kMaxVisiblePopupNotifications - 2]; - - AnimateUntilIdle(); - - EXPECT_EQ(kMaxVisiblePopupNotifications, GetPopupCounts()); - EXPECT_FALSE(IsAnimating()); - - gfx::Rect dismissed = GetPopup(dismissed_id)->GetBoundsInScreen(); - - MessageCenter::Get()->MarkSinglePopupAsShown(dismissed_id, false); - EXPECT_TRUE(IsAnimating()); - - AnimateToMiddle(); - EXPECT_GT(1.0f, GetPopup(dismissed_id)->GetOpacity()); - EXPECT_EQ(dismissed_id, GetPopup(dismissed_id)->id()); - - AnimateToEnd(); - EXPECT_EQ(ids[1], GetPopup(new_bottom_id)->id()); - EXPECT_TRUE(IsAnimating()); - - gfx::Rect before = GetPopup(new_bottom_id)->GetBoundsInScreen(); - - AnimateToMiddle(); - gfx::Rect moving = GetPopup(new_bottom_id)->GetBoundsInScreen(); - EXPECT_GT(moving.bottom(), before.bottom()); - EXPECT_GT(dismissed.bottom(), moving.bottom()); - - AnimateToEnd(); - gfx::Rect after = GetPopup(new_bottom_id)->GetBoundsInScreen(); - EXPECT_EQ(dismissed, after); - EXPECT_EQ(kMaxVisiblePopupNotifications - 1, GetPopupCounts()); - EXPECT_FALSE(IsAnimating()); -} - -TEST_F(MessagePopupCollectionTest, NotificationsMoveUpForInverse) { - popup_collection()->set_inverse(); - - std::vector<std::string> ids; - for (size_t i = 0; i < kMaxVisiblePopupNotifications + 1; ++i) - ids.push_back(AddNotification()); - - AnimateUntilIdle(); - - EXPECT_EQ(kMaxVisiblePopupNotifications, GetPopupCounts()); - EXPECT_FALSE(IsAnimating()); - - gfx::Rect dismissed = GetPopup(ids.front())->GetBoundsInScreen(); - - MessageCenter::Get()->MarkSinglePopupAsShown(ids.front(), false); - EXPECT_TRUE(IsAnimating()); - - // FADE_OUT - AnimateToMiddle(); - EXPECT_GT(1.0f, GetPopup(ids[0])->GetOpacity()); - EXPECT_EQ(ids[0], GetPopup(ids[0])->id()); - - AnimateToEnd(); - EXPECT_EQ(ids[1], GetPopup(ids[1])->id()); - EXPECT_TRUE(IsAnimating()); - - gfx::Rect before = GetPopup(ids[1])->GetBoundsInScreen(); - - // MOVE_UP_FOR_INVERSE - AnimateToMiddle(); - gfx::Rect moving = GetPopup(ids[1])->GetBoundsInScreen(); - EXPECT_LT(moving.bottom(), before.bottom()); - EXPECT_LT(dismissed.bottom(), moving.bottom()); - - AnimateToEnd(); - gfx::Rect after = GetPopup(ids[1])->GetBoundsInScreen(); - EXPECT_EQ(dismissed, after); - EXPECT_EQ(kMaxVisiblePopupNotifications, GetPopupCounts()); - EXPECT_TRUE(IsAnimating()); - - EXPECT_EQ(0.f, GetPopup(ids.back())->GetOpacity()); - - // FADE_IN - AnimateToMiddle(); - EXPECT_LT(0.0f, GetPopup(ids.back())->GetOpacity()); - - AnimateToEnd(); - EXPECT_EQ(1.0f, GetPopup(ids.back())->GetOpacity()); - EXPECT_FALSE(IsAnimating()); -} - TEST_F(MessagePopupCollectionTest, PopupResized) { std::vector<std::string> ids; for (size_t i = 0; i < kMaxVisiblePopupNotifications; ++i) @@ -852,38 +722,6 @@ EXPECT_TRUE(GetPopup(id2)); } -TEST_F(MessagePopupCollectionTest, TooTallNotificationInverse) { - popup_collection()->set_inverse(); - - SetDisplayInfo(gfx::Rect(0, 0, 800, 470), // taskbar at the bottom. - gfx::Rect(0, 0, 800, 480)); - - // 2 popus shall fit. 3 popups shall not. - popup_collection()->set_new_popup_height(200); - - std::string id0 = AddNotification(); - std::string id1 = AddNotification(); - - AnimateUntilIdle(); - - EXPECT_EQ(2u, GetPopupCounts()); - - std::string id2 = AddNotification(); - - EXPECT_FALSE(IsAnimating()); - EXPECT_EQ(2u, GetPopupCounts()); - EXPECT_TRUE(GetPopup(id0)); - EXPECT_TRUE(GetPopup(id1)); - EXPECT_FALSE(GetPopup(id2)); - - MessageCenter::Get()->MarkSinglePopupAsShown(id0, false); - AnimateUntilIdle(); - EXPECT_EQ(2u, GetPopupCounts()); - EXPECT_FALSE(GetPopup(id0)); - EXPECT_TRUE(GetPopup(id1)); - EXPECT_TRUE(GetPopup(id2)); -} - TEST_F(MessagePopupCollectionTest, DisplaySizeChanged) { std::string id0 = AddNotification(); AnimateToEnd(); @@ -1029,38 +867,6 @@ EXPECT_EQ(r1.x(), r2.x()); } -TEST_F(MessagePopupCollectionTest, DefaultPositioningInverse) { - popup_collection()->set_inverse(); - - std::string id0 = AddNotification(); - std::string id1 = AddNotification(); - std::string id2 = AddNotification(); - std::string id3 = AddNotification(); - - AnimateUntilIdle(); - - // This part is inverted. - gfx::Rect r0 = GetPopup(id2)->GetBoundsInScreen(); - gfx::Rect r1 = GetPopup(id1)->GetBoundsInScreen(); - gfx::Rect r2 = GetPopup(id0)->GetBoundsInScreen(); - - // The 4th toast is not shown yet. - EXPECT_FALSE(GetPopup(id3)); - - // 3 toasts are shown, equal size, vertical stack. - EXPECT_EQ(r0.width(), r1.width()); - EXPECT_EQ(r1.width(), r2.width()); - - EXPECT_EQ(r0.height(), r1.height()); - EXPECT_EQ(r1.height(), r2.height()); - - EXPECT_GT(r0.y(), r1.y()); - EXPECT_GT(r1.y(), r2.y()); - - EXPECT_EQ(r0.x(), r1.x()); - EXPECT_EQ(r1.x(), r2.x()); -} - TEST_F(MessagePopupCollectionTest, DefaultPositioningWithRightTaskbar) { // If taskbar is on the right we show the toasts bottom to top as usual.
diff --git a/ui/views/controls/menu/menu_cocoa_watcher_mac.h b/ui/views/controls/menu/menu_cocoa_watcher_mac.h index 14d1cb7e..abb4bcb 100644 --- a/ui/views/controls/menu/menu_cocoa_watcher_mac.h +++ b/ui/views/controls/menu/menu_cocoa_watcher_mac.h
@@ -5,7 +5,7 @@ #ifndef UI_VIEWS_CONTROLS_MENU_MENU_COCOA_WATCHER_MAC_H_ #define UI_VIEWS_CONTROLS_MENU_MENU_COCOA_WATCHER_MAC_H_ -#include <objc/objc.h> +#include <memory> #include "base/functional/callback.h" #include "ui/views/views_export.h" @@ -41,10 +41,8 @@ // The closure to call when the notification comes in. base::OnceClosure callback_; - // Tokens representing the notification observers. - id observer_token_other_menu_; - id observer_token_new_window_focus_; - id observer_token_app_change_; + struct ObjCStorage; + std::unique_ptr<ObjCStorage> objc_storage_; }; } // namespace views
diff --git a/ui/views/controls/menu/menu_cocoa_watcher_mac.mm b/ui/views/controls/menu/menu_cocoa_watcher_mac.mm index 18953a1..5f236f2b 100644 --- a/ui/views/controls/menu/menu_cocoa_watcher_mac.mm +++ b/ui/views/controls/menu/menu_cocoa_watcher_mac.mm
@@ -7,7 +7,8 @@ #import <Cocoa/Cocoa.h> #include <dispatch/dispatch.h> -#import <utility> +#include <memory> +#include <utility> namespace views { namespace { @@ -36,29 +37,41 @@ } } // namespace +struct MenuCocoaWatcherMac::ObjCStorage { + // Tokens representing the notification observers. + id observer_token_other_menu_ = nil; + id observer_token_new_window_focus_ = nil; + id observer_token_app_change_ = nil; +}; + MenuCocoaWatcherMac::MenuCocoaWatcherMac(base::OnceClosure callback) - : callback_(std::move(callback)) { - observer_token_other_menu_ = [[NSNotificationCenter defaultCenter] - addObserverForName:NSMenuDidBeginTrackingNotification - object:nil - queue:nil - usingBlock:^(NSNotification* notification) { - if (ShouldIgnoreNotification(notification)) - return; + : callback_(std::move(callback)), + objc_storage_(std::make_unique<ObjCStorage>()) { + objc_storage_->observer_token_other_menu_ = + [[NSNotificationCenter defaultCenter] + addObserverForName:NSMenuDidBeginTrackingNotification + object:nil + queue:nil + usingBlock:^(NSNotification* notification) { + if (ShouldIgnoreNotification(notification)) { + return; + } - ExecuteCallback(); - }]; - observer_token_new_window_focus_ = [[NSNotificationCenter defaultCenter] - addObserverForName:NSWindowDidBecomeKeyNotification - object:nil - queue:nil - usingBlock:^(NSNotification* notification) { - if (ShouldIgnoreNotification(notification)) - return; + ExecuteCallback(); + }]; + objc_storage_->observer_token_new_window_focus_ = + [[NSNotificationCenter defaultCenter] + addObserverForName:NSWindowDidBecomeKeyNotification + object:nil + queue:nil + usingBlock:^(NSNotification* notification) { + if (ShouldIgnoreNotification(notification)) { + return; + } - ExecuteCallback(); - }]; - observer_token_app_change_ = + ExecuteCallback(); + }]; + objc_storage_->observer_token_app_change_ = [[[NSWorkspace sharedWorkspace] notificationCenter] addObserverForName:NSWorkspaceDidActivateApplicationNotification object:nil @@ -79,11 +92,11 @@ MenuCocoaWatcherMac::~MenuCocoaWatcherMac() { [[NSNotificationCenter defaultCenter] - removeObserver:observer_token_other_menu_]; + removeObserver:objc_storage_->observer_token_other_menu_]; [[NSNotificationCenter defaultCenter] - removeObserver:observer_token_new_window_focus_]; + removeObserver:objc_storage_->observer_token_new_window_focus_]; [[[NSWorkspace sharedWorkspace] notificationCenter] - removeObserver:observer_token_app_change_]; + removeObserver:objc_storage_->observer_token_app_change_]; } void MenuCocoaWatcherMac::SetNotificationFilterForTesting(
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index 303945c..23f7461 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -18,6 +18,7 @@ #include "base/pickle.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" @@ -473,7 +474,7 @@ void TextfieldTest::InitTextfield(int count) { ASSERT_FALSE(textfield_); textfield_ = PrepareTextfields(count, std::make_unique<TestTextfield>(), - gfx::Rect(100, 100, 100, 100)); + gfx::Rect(100, 100, 200, 200)); } void TextfieldTest::PrepareTextfieldsInternal(int count, @@ -3639,6 +3640,8 @@ textfield_->CanStartDragForView(nullptr, kStringPoint, kStringPoint)); } +// No touch on desktop Mac. +#if !BUILDFLAG(IS_MAC) TEST_F(TextfieldTest, ScrollToAdjustDisplayOffset) { InitTextfield(); @@ -3652,29 +3655,25 @@ textfield_->SetTextWithoutCaretBoundsChangeNotification( u"0123456789_123456789_123456789", 0); test_api_->SetDisplayOffsetX(0); + constexpr gfx::Range kSelectionRange(2, 7); + textfield_->SetEditableSelectionRange(kSelectionRange); + + // Scroll starting at a vertical angle to adjust the display offset. + constexpr int kDisplayOffsetXAdjustment = -30; + const gfx::Point kScrollStart = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(5), GetCursorYForTesting()}); + const gfx::Point kScrollEnd = + kScrollStart + gfx::Vector2d(kDisplayOffsetXAdjustment, 60); + event_generator_->GestureScrollSequence(kScrollStart, kScrollEnd, + /*duration=*/base::Milliseconds(50), + /*steps=*/5); + + // Display offset should have updated without the selection changing. + gfx::Range range; + textfield_->GetEditableSelectionRange(&range); + EXPECT_EQ(range, kSelectionRange); EXPECT_FALSE(test_api_->touch_selection_controller()); - - // A scroll which begins in a vertical direction should adjust the display - // offset. - ui::GestureEvent scroll_begin = CreateTestGestureEvent( - GetCursorPositionX(5), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 1)); - textfield_->OnGestureEvent(&scroll_begin); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), 0); - - ui::GestureEvent scroll_update = CreateTestGestureEvent( - GetCursorPositionX(5) - 30, GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); - textfield_->OnGestureEvent(&scroll_update); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), -30); - - ui::GestureEvent scroll_end = CreateTestGestureEvent( - GetCursorPositionX(5) - 30, GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END)); - textfield_->OnGestureEvent(&scroll_end); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), -30); - // Touch handles shouldn't be shown since they weren't shown initially. - EXPECT_FALSE(test_api_->touch_selection_controller()); + EXPECT_EQ(test_api_->GetDisplayOffsetX(), kDisplayOffsetXAdjustment); } TEST_F(TextfieldTest, TwoFingerScroll) { @@ -3690,35 +3689,29 @@ textfield_->SetTextWithoutCaretBoundsChangeNotification( u"0123456789_123456789_123456789", 0); test_api_->SetDisplayOffsetX(0); + constexpr gfx::Range kSelectionRange(2, 7); + textfield_->SetEditableSelectionRange(kSelectionRange); + + // Scroll with two fingers to adjust the display offset. + constexpr int kDisplayOffsetXAdjustment = -30; + const gfx::Point kStart1 = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(5), GetCursorYForTesting()}); + const gfx::Point kStart2 = kStart1 + gfx::Vector2d(20, 0); + const gfx::Point kStart[] = {kStart1, kStart2}; + event_generator_->GestureMultiFingerScroll( + /*count=*/2, kStart, + /*event_separation_time_ms=*/50, + /*steps=*/5, /*move_x=*/kDisplayOffsetXAdjustment, + /*move_y=*/0); + + // Display offset should have updated without the selection changing. + gfx::Range range; + textfield_->GetEditableSelectionRange(&range); + EXPECT_EQ(range, kSelectionRange); EXPECT_FALSE(test_api_->touch_selection_controller()); - - // Two finger scroll should adjust the display offset. - ui::GestureEventDetails scroll_begin_details(ui::ET_GESTURE_SCROLL_BEGIN); - scroll_begin_details.set_touch_points(2); - ui::GestureEvent scroll_begin = CreateTestGestureEvent( - GetCursorPositionX(5), GetCursorYForTesting(), scroll_begin_details); - textfield_->OnGestureEvent(&scroll_begin); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), 0); - - ui::GestureEventDetails scroll_update_details(ui::ET_GESTURE_SCROLL_UPDATE); - scroll_update_details.set_touch_points(2); - ui::GestureEvent scroll_update = - CreateTestGestureEvent(GetCursorPositionX(5) - 30, GetCursorYForTesting(), - scroll_update_details); - textfield_->OnGestureEvent(&scroll_update); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), -30); - - ui::GestureEvent scroll_end = CreateTestGestureEvent( - GetCursorPositionX(5) - 30, GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END)); - textfield_->OnGestureEvent(&scroll_end); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), -30); - // Touch handles shouldn't be shown since they weren't shown initially. - EXPECT_FALSE(test_api_->touch_selection_controller()); + EXPECT_EQ(test_api_->GetDisplayOffsetX(), kDisplayOffsetXAdjustment); } -// No touch on desktop Mac. -#if !BUILDFLAG(IS_MAC) TEST_F(TextfieldTest, ScrollToPlaceCursor) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures( @@ -3727,27 +3720,22 @@ InitTextfield(); textfield_->SetText(u"Hello string world"); + + // Scroll in a horizontal direction to move the cursor. + constexpr int kCursorStartPos = 2; + constexpr int kCursorEndPos = 15; + const gfx::Point kScrollStart = views::View::ConvertPointToScreen( + textfield_, + {GetCursorPositionX(kCursorStartPos), GetCursorYForTesting()}); + const gfx::Point kScrollEnd = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(kCursorEndPos), GetCursorYForTesting()}); + event_generator_->GestureScrollSequence(kScrollStart, kScrollEnd, + /*duration=*/base::Milliseconds(50), + /*steps=*/5); + gfx::Range range; - - // A scroll which begins in a horizontal direction should move the cursor. - ui::GestureEvent scroll_begin = CreateTestGestureEvent( - GetCursorPositionX(2), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 1, 0)); - textfield_->OnGestureEvent(&scroll_begin); - - ui::GestureEvent scroll_update_1 = CreateTestGestureEvent( - GetCursorPositionX(5), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); - textfield_->OnGestureEvent(&scroll_update_1); textfield_->GetEditableSelectionRange(&range); - EXPECT_EQ(range, gfx::Range(5)); - - ui::GestureEvent scroll_update_2 = CreateTestGestureEvent( - GetCursorPositionX(7), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); - textfield_->OnGestureEvent(&scroll_update_2); - textfield_->GetEditableSelectionRange(&range); - EXPECT_EQ(range, gfx::Range(7)); + EXPECT_EQ(range, gfx::Range(kCursorEndPos)); } TEST_F(TextfieldTest, ScrollToPlaceCursorShowsTouchHandles) { @@ -3759,24 +3747,24 @@ InitTextfield(); textfield_->SetText(u"Hello string world"); - // A scroll which begins in a horizontal direction should move the cursor. - ui::GestureEvent scroll_begin = CreateTestGestureEvent( - GetCursorPositionX(2), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 1, 0)); - textfield_->OnGestureEvent(&scroll_begin); + // Scroll in a horizontal direction to move the cursor. + const gfx::Point kScrollStart = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(2), GetCursorYForTesting()}); + const gfx::Point kScrollEnd = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(15), GetCursorYForTesting()}); + event_generator_->GestureScrollSequenceWithCallback( + kScrollStart, kScrollEnd, /*duration=*/base::Milliseconds(50), + /*steps=*/5, + base::BindLambdaForTesting( + [&](ui::EventType event_type, const gfx::Vector2dF& offset) { + if (event_type != ui::ET_GESTURE_SCROLL_UPDATE) { + return; + } + // Touch handles should be hidden during scroll. + EXPECT_FALSE(test_api_->touch_selection_controller()); + })); - ui::GestureEvent scroll_update = CreateTestGestureEvent( - GetCursorPositionX(5), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); - textfield_->OnGestureEvent(&scroll_update); - // Touch handles should be hidden during scroll. - EXPECT_FALSE(test_api_->touch_selection_controller()); - - ui::GestureEvent scroll_end = CreateTestGestureEvent( - GetCursorPositionX(7), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END)); - textfield_->OnGestureEvent(&scroll_end); - // Touch handles should be shown when scroll ends. + // Touch handles should be shown after scroll ends. EXPECT_TRUE(test_api_->touch_selection_controller()); } @@ -3798,22 +3786,21 @@ textfield_->SetTextWithoutCaretBoundsChangeNotification( u"0123456789_123456789_123456789", 0); test_api_->SetDisplayOffsetX(0); + + // Scroll in a horizontal direction to move the cursor. + const gfx::Point kScrollStart = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(2), GetCursorYForTesting()}); + const gfx::Point kScrollEnd = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(30), GetCursorYForTesting()}); + event_generator_->GestureScrollSequence(kScrollStart, kScrollEnd, + /*duration=*/base::Milliseconds(50), + /*steps=*/5); + + // Cursor should have moved and display should be offset so that the cursor is + // visible in the textfield. gfx::Range range; - - // A scroll which begins in a horizontal direction should move the cursor. - ui::GestureEvent scroll_begin = CreateTestGestureEvent( - GetCursorPositionX(2), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 1, 0)); - textfield_->OnGestureEvent(&scroll_begin); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), 0); - - ui::GestureEvent scroll_update = CreateTestGestureEvent( - GetCursorPositionX(30), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); - textfield_->OnGestureEvent(&scroll_update); textfield_->GetEditableSelectionRange(&range); EXPECT_EQ(range, gfx::Range(30)); - // Display should be offset so that the cursor is visible in the textfield. EXPECT_EQ(test_api_->GetDisplayOffsetX(), -200); } @@ -3835,52 +3822,32 @@ textfield_->SetTextWithoutCaretBoundsChangeNotification( u"0123456789_123456789_123456789", 0); test_api_->SetDisplayOffsetX(0); + textfield_->SetEditableSelectionRange(gfx::Range(2, 7)); + + // Perform a scroll which starts with one finger then adds another finger + // after a delay. + const gfx::Point kStart1 = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(8), GetCursorYForTesting()}); + const gfx::Point kStart2 = kStart1 + gfx::Vector2d(20, 0); + const gfx::Point kStart[] = {kStart1, kStart2}; + constexpr gfx::Vector2d kDelta[] = { + gfx::Vector2d(-50, 0), + gfx::Vector2d(-30, 0), + }; + constexpr int kDelayAddingFingerMs[] = {0, 40}; + constexpr int kDelayReleasingFingerMs[] = {150, 150}; + event_generator_->GestureMultiFingerScrollWithDelays( + /*count=*/2, kStart, kDelta, kDelayAddingFingerMs, + kDelayReleasingFingerMs, /*event_separation_time_ms=*/20, /*steps=*/5); + + // Since the scroll started with one finger, the cursor should have moved. gfx::Range range; - - // Start scrolling with one touch point in a horizontal direction. - ui::GestureEventDetails scroll_begin_details(ui::ET_GESTURE_SCROLL_BEGIN, 1, - 0); - ui::GestureEvent scroll_begin = CreateTestGestureEvent( - GetCursorPositionX(5), GetCursorYForTesting(), scroll_begin_details); - textfield_->OnGestureEvent(&scroll_begin); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), 0); - - // Scroll update should move the cursor. - ui::GestureEvent scroll_update_1 = CreateTestGestureEvent( - GetCursorPositionX(5), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); - textfield_->OnGestureEvent(&scroll_update_1); textfield_->GetEditableSelectionRange(&range); - EXPECT_EQ(range, gfx::Range(5)); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), 0); - - // Add second touch point to scroll sequence. - ui::GestureEventDetails scroll_update_details_2(ui::ET_GESTURE_SCROLL_UPDATE); - scroll_update_details_2.set_touch_points(2); - ui::GestureEvent scroll_update_2 = CreateTestGestureEvent( - GetCursorPositionX(5), GetCursorYForTesting(), scroll_update_details_2); - textfield_->OnGestureEvent(&scroll_update_2); - EXPECT_EQ(range, gfx::Range(5)); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), 0); - - // Scroll update should adjust display offset without moving cursor. - ui::GestureEventDetails scroll_update_details_3(ui::ET_GESTURE_SCROLL_UPDATE); - scroll_update_details_3.set_touch_points(2); - ui::GestureEvent scroll_update_3 = - CreateTestGestureEvent(GetCursorPositionX(5) - 30, GetCursorYForTesting(), - scroll_update_details_3); - textfield_->OnGestureEvent(&scroll_update_3); - EXPECT_EQ(range, gfx::Range(5)); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), -30); - - ui::GestureEvent scroll_end = CreateTestGestureEvent( - GetCursorPositionX(5) - 30, GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END)); - textfield_->OnGestureEvent(&scroll_end); - EXPECT_EQ(test_api_->GetDisplayOffsetX(), -30); - // Touch handles should be shown when scroll ends since the scroll sequence - // was initially used for cursor placement. + EXPECT_EQ(range, gfx::Range(6)); EXPECT_TRUE(test_api_->touch_selection_controller()); + // Since a second finger was added, the display should also be slightly + // offset. + EXPECT_LT(test_api_->GetDisplayOffsetX(), 0); } TEST_F(TextfieldTest, LongPressDragLTR_Forward) {
diff --git a/ui/views/event_monitor_mac.h b/ui/views/event_monitor_mac.h index 4a2be75..694d98c7 100644 --- a/ui/views/event_monitor_mac.h +++ b/ui/views/event_monitor_mac.h
@@ -5,6 +5,7 @@ #ifndef UI_VIEWS_EVENT_MONITOR_MAC_H_ #define UI_VIEWS_EVENT_MONITOR_MAC_H_ +#include <memory> #include <set> #include "base/memory/weak_ptr.h" @@ -28,9 +29,11 @@ gfx::Point GetLastMouseLocation() override; private: - id monitor_ = nil; const std::set<ui::EventType> types_; + struct ObjCStorage; + std::unique_ptr<ObjCStorage> objc_storage_; + base::WeakPtrFactory<EventMonitorMac> factory_{this}; };
diff --git a/ui/views/event_monitor_mac.mm b/ui/views/event_monitor_mac.mm index af43d7f..4ee546af 100644 --- a/ui/views/event_monitor_mac.mm +++ b/ui/views/event_monitor_mac.mm
@@ -6,6 +6,8 @@ #import <Cocoa/Cocoa.h> +#include <memory> + #include "base/check.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" @@ -34,10 +36,14 @@ types); } +struct EventMonitorMac::ObjCStorage { + id monitor_ = nil; +}; + EventMonitorMac::EventMonitorMac(ui::EventObserver* event_observer, gfx::NativeWindow target_native_window, const std::set<ui::EventType>& types) - : types_(types) { + : types_(types), objc_storage_(std::make_unique<ObjCStorage>()) { DCHECK(event_observer); NSWindow* target_window = target_native_window.GetNativeNSWindow(); @@ -59,12 +65,13 @@ return event; }; - monitor_ = [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskAny - handler:block]; + objc_storage_->monitor_ = + [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskAny + handler:block]; } EventMonitorMac::~EventMonitorMac() { - [NSEvent removeMonitor:monitor_]; + [NSEvent removeMonitor:objc_storage_->monitor_]; } gfx::Point EventMonitorMac::GetLastMouseLocation() {
diff --git a/ui/webui/resources/cr_components/omnibox/realbox_dropdown.html b/ui/webui/resources/cr_components/omnibox/realbox_dropdown.html index a1182aa3..d6fe9a13 100644 --- a/ui/webui/resources/cr_components/omnibox/realbox_dropdown.html +++ b/ui/webui/resources/cr_components/omnibox/realbox_dropdown.html
@@ -36,8 +36,14 @@ .header { align-items: center; + box-sizing: border-box; display: flex; - margin-top: 8px; + font-size: inherit; + font-weight: inherit; + /* To mirror match typical row height of items in vertical list. */ + height: 44px; + margin-block-end: 0; + margin-block-start: 0; outline: none; padding-bottom: 6px; padding-inline-end: 16px; @@ -88,9 +94,6 @@ } .secondary-side .header { - box-sizing: border-box; - height: 44px; /* To mirror match row height on primary side. */ - margin: 0; padding-inline-end: 6px; padding-inline-start: 6px; } @@ -113,7 +116,7 @@ <template is="dom-if" if="[[hasHeaderForGroup_(groupId)]]"> <!-- Header cannot be tabbed into but gets focus when clicked. This stops the dropdown from losing focus and closing as a result. --> - <div class="header" data-id$="[[groupId]]" tabindex="-1" + <h3 class="header" data-id$="[[groupId]]" tabindex="-1" on-focusin="onHeaderFocusin_" on-click="onHeaderClick_" aria-hidden="true"> <span class="text">[[headerForGroup_(groupId)]]</span> @@ -122,7 +125,7 @@ aria-label$="[[toggleButtonA11yLabelForGroup_(groupId, hiddenGroupIds_.*)]]" on-mousedown="onToggleButtonMouseDown_"> </cr-icon-button> - </div> + </h3> </template> <div class="matches"> <template is="dom-repeat"
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn index 5c9404e..80a8d9c 100644 --- a/weblayer/shell/android/BUILD.gn +++ b/weblayer/shell/android/BUILD.gn
@@ -149,7 +149,6 @@ "webengine_shell_apk/src/org/chromium/webengine/shell/InstrumentationActivity.java", "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineNavigationTestActivity.java", "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java", - "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellApplication.java", "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineStateTestActivity.java", "webengine_shell_apk/src/org/chromium/webengine/shell/topbar/CustomSpinner.java", "webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsDelegate.java", @@ -164,7 +163,6 @@ "//third_party/android_deps:guava_android_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_java", - "//third_party/androidx:androidx_concurrent_concurrent_futures_java", "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_fragment_fragment_java", "//weblayer/public/java:service_provider_java",
diff --git a/weblayer/shell/android/webengine_shell_apk/AndroidManifest.xml b/weblayer/shell/android/webengine_shell_apk/AndroidManifest.xml index dd802c1..91ce32a 100644 --- a/weblayer/shell/android/webengine_shell_apk/AndroidManifest.xml +++ b/weblayer/shell/android/webengine_shell_apk/AndroidManifest.xml
@@ -11,9 +11,7 @@ xmlns:tools="http://schemas.android.com/tools" package="org.chromium.webengine.shell"> - <application - android:name="WebEngineShellApplication" - android:label="WE shell" + <application android:label="WE shell" tools:replace="android:label" android:supportsRtl="true"> <activity android:name="WebEngineShellActivity"
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java index 5f93eeb..bed36443 100644 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java +++ b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java
@@ -67,9 +67,9 @@ private static final String WEB_FRAGMENT_TAG = "WEB_FRAGMENT_TAG"; - private WebEngineShellApplication mApplication; private Context mContext; + private WebSandbox mWebSandbox; private TabManager mTabManager; private TabEventsDelegate mTabEventsDelegate; @@ -96,7 +96,6 @@ } setContentView(R.layout.main); - mApplication = (WebEngineShellApplication) getApplication(); mContext = getApplicationContext(); mDefaultTabListObserver = new DefaultObservers(); @@ -154,6 +153,7 @@ }); ListenableFuture<String> sandboxVersionFuture = WebSandbox.getVersion(mContext); + Futures.addCallback(sandboxVersionFuture, new FutureCallback<String>() { @Override public void onSuccess(String version) { @@ -164,29 +164,166 @@ public void onFailure(Throwable thrown) {} }, ContextCompat.getMainExecutor(mContext)); - Futures.addCallback(mApplication.getWebEngine(), new FutureCallback<WebEngine>() { + ListenableFuture<WebSandbox> webSandboxFuture = WebSandbox.create(mContext); + Futures.addCallback(webSandboxFuture, new FutureCallback<WebSandbox>() { + @Override + public void onSuccess(WebSandbox webSandbox) { + onWebSandboxReady(webSandbox); + } + + @Override + public void onFailure(Throwable thrown) { + Toast.makeText(mContext, "Failed to start WebSandbox. WebView update needed.", + Toast.LENGTH_LONG) + .show(); + } + }, ContextCompat.getMainExecutor(mContext)); + } + + @Override + public void startActivity(Intent intent) { + if (mWebSandbox != null) { + // Shutdown sandbox before another activity is opened. + mWebSandbox.shutdown(); + mWebSandbox = null; + } + super.startActivity(intent); + } + + private void onWebSandboxReady(WebSandbox webSandbox) { + mWebSandbox = webSandbox; + webSandbox.setRemoteDebuggingEnabled(true); + + WebEngine webEngine = webSandbox.getWebEngine("shell-engine"); + if (webEngine != null) { + assert webSandbox.getWebEngines().size() == 1; + + mTabManager = webEngine.getTabManager(); + + mTabEventsDelegate = new TabEventsDelegate(mTabManager); + mTabEventsDelegate.registerObserver(this); + + mTabCountButton.setText(String.valueOf(getTabsCount())); + mTabListAdapter = new ArrayAdapter<TabWrapper>( + this, android.R.layout.simple_spinner_dropdown_item); + mTabListSpinner.setAdapter(mTabListAdapter); + + for (Tab t : mTabManager.getAllTabs()) { + TabWrapper tabWrapper = new TabWrapper(t); + mTabListAdapter.add(tabWrapper); + if (t.equals(mTabManager.getActiveTab())) { + mTabListSpinner.setSelection(mTabListAdapter.getPosition(tabWrapper)); + } + } + + if (mIsTabListOpen) { + mTabListSpinner.performClick(); + } + + for (Tab tab : mTabManager.getAllTabs()) { + tab.setFullscreenCallback(this); + } + return; + } + + ListenableFuture<WebEngine> webEngineFuture = webSandbox.createWebEngine("shell-engine"); + Futures.addCallback(webEngineFuture, new FutureCallback<WebEngine>() { @Override public void onSuccess(WebEngine webEngine) { onWebEngineReady(webEngine); } @Override - public void onFailure(Throwable thrown) { - Toast.makeText(mContext, "Failed to start WebEngine.", Toast.LENGTH_LONG).show(); - } + public void onFailure(Throwable thrown) {} }, ContextCompat.getMainExecutor(mContext)); + } - Futures.addCallback( - mApplication.getTabEventsDelegate(), new FutureCallback<TabEventsDelegate>() { + private void onWebEngineReady(WebEngine webEngine) { + mTabManager = webEngine.getTabManager(); + CookieManager cookieManager = webEngine.getCookieManager(); + + Tab activeTab = mTabManager.getActiveTab(); + + mTabCountButton.setText(String.valueOf(getTabsCount())); + mTabListAdapter = + new ArrayAdapter<TabWrapper>(this, android.R.layout.simple_spinner_dropdown_item); + mTabListSpinner.setAdapter(mTabListAdapter); + + mTabEventsDelegate = new TabEventsDelegate(mTabManager); + mTabEventsDelegate.registerObserver(this); + + for (Tab t : mTabManager.getAllTabs()) { + TabWrapper tabWrapper = new TabWrapper(t); + mTabListAdapter.add(tabWrapper); + if (t.equals(mTabManager.getActiveTab())) { + mTabListSpinner.setSelection(mTabListAdapter.getPosition(tabWrapper)); + } + } + + activeTab.setFullscreenCallback(this); + mTabManager.registerTabListObserver(new TabListObserver() { + @Override + public void onTabAdded(@NonNull WebEngine webEngine, @NonNull Tab tab) { + tab.setFullscreenCallback(WebEngineShellActivity.this); + } + }); + activeTab.registerTabObserver(mDefaultTabListObserver); + activeTab.getNavigationController().registerNavigationObserver(mDefaultTabListObserver); + mTabManager.registerTabListObserver(mDefaultTabListObserver); + + activeTab.getNavigationController().registerNavigationObserver(new NavigationObserver() { + @Override + public void onNavigationCompleted(@NonNull Tab tab, @NonNull Navigation navigation) { + ListenableFuture<String> scriptResultFuture = activeTab.executeScript("1+1", true); + Futures.addCallback( + scriptResultFuture, new FutureCallback<String>() { + @Override + public void onSuccess(String result) { + Log.w(TAG, "executeScript result: " + result); + } + @Override + public void onFailure(Throwable thrown) { + Log.w(TAG, "executeScript failed: " + thrown); + } + }, ContextCompat.getMainExecutor(mContext)); + } + }); + activeTab.getNavigationController().navigate("https://google.com"); + + activeTab.addMessageEventListener((Tab source, String message) -> { + Log.w(TAG, "Received post message from web content: " + message); + }, Arrays.asList("*")); + activeTab.postMessage("Hello!", "*"); + + ListenableFuture<Void> setCookieFuture = + cookieManager.setCookie("https://sadchonks.com", "foo=bar123"); + Futures.addCallback(setCookieFuture, new FutureCallback<Void>() { + @Override + public void onSuccess(Void v) { + ListenableFuture<String> cookieFuture = + cookieManager.getCookie("https://sadchonks.com"); + Futures.addCallback(cookieFuture, new FutureCallback<String>() { @Override - public void onSuccess(TabEventsDelegate tabEventsDelegate) { - mTabEventsDelegate = tabEventsDelegate; - tabEventsDelegate.registerObserver(WebEngineShellActivity.this); + public void onSuccess(String value) { + Log.w(TAG, "cookie: " + value); } @Override public void onFailure(Throwable thrown) {} }, ContextCompat.getMainExecutor(mContext)); + } + + @Override + public void onFailure(Throwable thrown) { + Log.w(TAG, "setCookie failed: " + thrown); + } + }, ContextCompat.getMainExecutor(mContext)); + + getSupportFragmentManager() + .beginTransaction() + .setReorderingAllowed(true) + .add(R.id.fragment_container_view, webEngine.getFragment(), WEB_FRAGMENT_TAG) + .commit(); } @Override @@ -202,7 +339,7 @@ for (Tab tab : mTabManager.getAllTabs()) { tab.setFullscreenCallback(null); } - if (mTabEventsDelegate != null) mTabEventsDelegate.unregisterObserver(); + mTabEventsDelegate.unregisterObservers(); } @Override @@ -223,6 +360,9 @@ } @Override public void onFailure(Throwable thrown) { + if (mWebSandbox != null) { + mWebSandbox.shutdown(); + } WebEngineShellActivity.super.onBackPressed(); } }, ContextCompat.getMainExecutor(mContext)); @@ -298,102 +438,6 @@ } } - private void onWebEngineReady(WebEngine webEngine) { - mTabManager = webEngine.getTabManager(); - - CookieManager cookieManager = webEngine.getCookieManager(); - Tab activeTab = mTabManager.getActiveTab(); - - mTabCountButton.setText(String.valueOf(getTabsCount())); - mTabListAdapter = new ArrayAdapter<TabWrapper>( - mContext, android.R.layout.simple_spinner_dropdown_item); - mTabListSpinner.setAdapter(mTabListAdapter); - - for (Tab t : mTabManager.getAllTabs()) { - TabWrapper tabWrapper = new TabWrapper(t); - mTabListAdapter.add(tabWrapper); - if (t.equals(mTabManager.getActiveTab())) { - mTabListSpinner.setSelection(mTabListAdapter.getPosition(tabWrapper)); - } - } - - if (mIsTabListOpen) { - mTabListSpinner.performClick(); - } - - for (Tab tab : mTabManager.getAllTabs()) { - tab.setFullscreenCallback(WebEngineShellActivity.this); - } - - if (activeTab.getDisplayUri().toString().equals("")) { - mTabManager.registerTabListObserver(new TabListObserver() { - @Override - public void onTabAdded(@NonNull WebEngine webEngine, @NonNull Tab tab) { - tab.setFullscreenCallback(WebEngineShellActivity.this); - } - }); - activeTab.registerTabObserver(mDefaultTabListObserver); - activeTab.getNavigationController().registerNavigationObserver(mDefaultTabListObserver); - - activeTab.getNavigationController().registerNavigationObserver( - new NavigationObserver() { - @Override - public void onNavigationCompleted( - @NonNull Tab tab, @NonNull Navigation navigation) { - ListenableFuture<String> scriptResultFuture = - activeTab.executeScript("1+1", true); - Futures.addCallback(scriptResultFuture, new FutureCallback<String>() { - @Override - public void onSuccess(String result) { - Log.w(TAG, "executeScript result: " + result); - } - @Override - public void onFailure(Throwable thrown) { - Log.w(TAG, "executeScript failed: " + thrown); - } - }, ContextCompat.getMainExecutor(mContext)); - } - }); - activeTab.getNavigationController().navigate("https://google.com"); - - activeTab.addMessageEventListener((Tab source, String message) -> { - Log.w(TAG, "Received post message from web content: " + message); - }, Arrays.asList("*")); - activeTab.postMessage("Hello!", "*"); - - ListenableFuture<Void> setCookieFuture = - cookieManager.setCookie("https://sadchonks.com", "foo=bar123"); - Futures.addCallback(setCookieFuture, new FutureCallback<Void>() { - @Override - public void onSuccess(Void v) { - ListenableFuture<String> cookieFuture = - cookieManager.getCookie("https://sadchonks.com"); - Futures.addCallback(cookieFuture, new FutureCallback<String>() { - @Override - public void onSuccess(String value) { - Log.w(TAG, "cookie: " + value); - } - - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(mContext)); - } - - @Override - public void onFailure(Throwable thrown) { - Log.w(TAG, "setCookie failed: " + thrown); - } - }, ContextCompat.getMainExecutor(mContext)); - } - if (getSupportFragmentManager().findFragmentByTag(WEB_FRAGMENT_TAG) == null) { - getSupportFragmentManager() - .beginTransaction() - .setReorderingAllowed(true) - .add(R.id.fragment_container_view, webEngine.getFragment(), WEB_FRAGMENT_TAG) - .commit(); - } - } - int getTabsCount() { if (mTabManager == null) { return 0;
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellApplication.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellApplication.java deleted file mode 100644 index 22fde8a..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellApplication.java +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.shell; - -import android.app.Application; - -import androidx.core.content.ContextCompat; - -import com.google.common.base.Function; -import com.google.common.util.concurrent.AsyncFunction; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; -import org.chromium.webengine.shell.topbar.TabEventsDelegate; - -/** - * Application for managing WebSandbox and WebEngine in the Demo Shell. - */ -public class WebEngineShellApplication extends Application { - private ListenableFuture<WebEngine> mWebEngineFuture; - private ListenableFuture<TabEventsDelegate> mTabEventsDelegateFuture; - - private WebEngine mWebEngine; - private TabEventsDelegate mTabEventsDelegate; - - public ListenableFuture<WebEngine> getWebEngine() { - if (mWebEngine != null) { - return Futures.immediateFuture(mWebEngine); - } - return mWebEngineFuture; - } - - public ListenableFuture<TabEventsDelegate> getTabEventsDelegate() { - if (mTabEventsDelegate != null) { - return Futures.immediateFuture(mTabEventsDelegate); - } - - if (mTabEventsDelegateFuture != null) { - return mTabEventsDelegateFuture; - } - - Function<WebEngine, TabEventsDelegate> getTabEventsDelegateTask = - webEngine -> new TabEventsDelegate(webEngine.getTabManager()); - - mTabEventsDelegateFuture = Futures.transform( - getWebEngine(), getTabEventsDelegateTask, ContextCompat.getMainExecutor(this)); - - return mTabEventsDelegateFuture; - } - - @Override - public void onCreate() { - super.onCreate(); - - AsyncFunction<WebSandbox, WebEngine> getWebEngineTask = - webSandbox -> webSandbox.createWebEngine("shell-engine"); - mWebEngineFuture = Futures.transformAsync( - WebSandbox.create(this), getWebEngineTask, ContextCompat.getMainExecutor(this)); - Futures.addCallback(mWebEngineFuture, new FutureCallback<WebEngine>() { - @Override - public void onSuccess(WebEngine webEngine) { - mWebEngine = webEngine; - mWebEngineFuture = null; - - mTabEventsDelegate = new TabEventsDelegate(webEngine.getTabManager()); - } - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(this)); - } -}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsDelegate.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsDelegate.java index 9263e5b53..fa79d5a8 100644 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsDelegate.java +++ b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsDelegate.java
@@ -24,6 +24,11 @@ public TabEventsDelegate(TabManager tabManager) { mTabManager = tabManager; + } + + // Registers only one TabEventsObserver. + public void registerObserver(TabEventsObserver tabEventsObserver) { + mTabEventsObserver = tabEventsObserver; mTabManager.registerTabListObserver(this); for (Tab t : mTabManager.getAllTabs()) { t.getNavigationController().registerNavigationObserver(this); @@ -31,12 +36,13 @@ } } - public void registerObserver(TabEventsObserver tabEventsObserver) { - mTabEventsObserver = tabEventsObserver; - } - - public void unregisterObserver() { + public void unregisterObservers() { mTabEventsObserver = null; + mTabManager.unregisterTabListObserver(this); + for (Tab t : mTabManager.getAllTabs()) { + t.getNavigationController().unregisterNavigationObserver(this); + t.unregisterTabObserver(this); + } } // TabObserver implementation.